mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Added a method JavascriptEngine::callFunctionObject() for invoking javascript methods in DynamicObject native methods
This commit is contained in:
parent
3f223d2caa
commit
9c75f13a4f
2 changed files with 65 additions and 17 deletions
|
|
@ -144,15 +144,15 @@ struct JavascriptEngine::RootObject : public DynamicObject
|
|||
|
||||
var findFunctionCall (const CodeLocation& location, const var& targetObject, const Identifier& functionName) const
|
||||
{
|
||||
if (DynamicObject* o = targetObject.getDynamicObject())
|
||||
if (auto* o = targetObject.getDynamicObject())
|
||||
{
|
||||
if (const var* prop = getPropertyPointer (o, functionName))
|
||||
if (auto* prop = getPropertyPointer (o, functionName))
|
||||
return *prop;
|
||||
|
||||
for (DynamicObject* p = o->getProperty (getPrototypeIdentifier()).getDynamicObject(); p != nullptr;
|
||||
for (auto* p = o->getProperty (getPrototypeIdentifier()).getDynamicObject(); p != nullptr;
|
||||
p = p->getProperty (getPrototypeIdentifier()).getDynamicObject())
|
||||
{
|
||||
if (const var* prop = getPropertyPointer (p, functionName))
|
||||
if (auto* prop = getPropertyPointer (p, functionName))
|
||||
return *prop;
|
||||
}
|
||||
|
||||
|
|
@ -162,23 +162,23 @@ struct JavascriptEngine::RootObject : public DynamicObject
|
|||
}
|
||||
|
||||
if (targetObject.isString())
|
||||
if (var* m = findRootClassProperty (StringClass::getClassName(), functionName))
|
||||
if (auto* m = findRootClassProperty (StringClass::getClassName(), functionName))
|
||||
return *m;
|
||||
|
||||
if (targetObject.isArray())
|
||||
if (var* m = findRootClassProperty (ArrayClass::getClassName(), functionName))
|
||||
if (auto* m = findRootClassProperty (ArrayClass::getClassName(), functionName))
|
||||
return *m;
|
||||
|
||||
if (var* m = findRootClassProperty (ObjectClass::getClassName(), functionName))
|
||||
if (auto* m = findRootClassProperty (ObjectClass::getClassName(), functionName))
|
||||
return *m;
|
||||
|
||||
location.throwError ("Unknown function '" + functionName.toString() + "'");
|
||||
return var();
|
||||
return {};
|
||||
}
|
||||
|
||||
var* findRootClassProperty (const Identifier& className, const Identifier& propName) const
|
||||
{
|
||||
if (DynamicObject* cls = root->getProperty (className).getDynamicObject())
|
||||
if (auto* cls = root->getProperty (className).getDynamicObject())
|
||||
return getPropertyPointer (cls, propName);
|
||||
|
||||
return nullptr;
|
||||
|
|
@ -186,7 +186,7 @@ struct JavascriptEngine::RootObject : public DynamicObject
|
|||
|
||||
var findSymbolInParentScopes (const Identifier& name) const
|
||||
{
|
||||
if (const var* v = getPropertyPointer (scope, name))
|
||||
if (auto* v = getPropertyPointer (scope, name))
|
||||
return *v;
|
||||
|
||||
return parent != nullptr ? parent->findSymbolInParentScopes (name)
|
||||
|
|
@ -195,13 +195,13 @@ struct JavascriptEngine::RootObject : public DynamicObject
|
|||
|
||||
bool findAndInvokeMethod (const Identifier& function, const var::NativeFunctionArgs& args, var& result) const
|
||||
{
|
||||
DynamicObject* target = args.thisObject.getDynamicObject();
|
||||
auto* target = args.thisObject.getDynamicObject();
|
||||
|
||||
if (target == nullptr || target == scope)
|
||||
{
|
||||
if (const var* m = getPropertyPointer (scope, function))
|
||||
if (auto* m = getPropertyPointer (scope, function))
|
||||
{
|
||||
if (FunctionObject* fo = dynamic_cast<FunctionObject*> (m->getObject()))
|
||||
if (auto fo = dynamic_cast<FunctionObject*> (m->getObject()))
|
||||
{
|
||||
result = fo->invoke (*this, args);
|
||||
return true;
|
||||
|
|
@ -209,16 +209,35 @@ struct JavascriptEngine::RootObject : public DynamicObject
|
|||
}
|
||||
}
|
||||
|
||||
const NamedValueSet& props = scope->getProperties();
|
||||
const auto& props = scope->getProperties();
|
||||
|
||||
for (int i = 0; i < props.size(); ++i)
|
||||
if (DynamicObject* o = props.getValueAt (i).getDynamicObject())
|
||||
if (auto* o = props.getValueAt (i).getDynamicObject())
|
||||
if (Scope (this, root, o).findAndInvokeMethod (function, args, result))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool invokeMethod (const var& m, const var::NativeFunctionArgs& args, var& result) const
|
||||
{
|
||||
if (isFunction (m))
|
||||
{
|
||||
auto* target = args.thisObject.getDynamicObject();
|
||||
|
||||
if (target == nullptr || target == scope)
|
||||
{
|
||||
if (auto fo = dynamic_cast<FunctionObject*> (m.getObject()))
|
||||
{
|
||||
result = fo->invoke (*this, args);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void checkTimeOut (const CodeLocation& location) const
|
||||
{
|
||||
if (Time::getCurrentTime() > root->timeout)
|
||||
|
|
@ -1372,7 +1391,7 @@ struct JavascriptEngine::RootObject : public DynamicObject
|
|||
template <typename OpType>
|
||||
Expression* parsePreIncDec()
|
||||
{
|
||||
Expression* e = parseFactor(); // careful - bare pointer is deliberately alised
|
||||
Expression* e = parseFactor(); // careful - bare pointer is deliberately aliased
|
||||
ExpPtr lhs (e), one (new LiteralValue (location, (int) 1));
|
||||
return new SelfAssignment (location, e, new OpType (location, lhs, one));
|
||||
}
|
||||
|
|
@ -1380,7 +1399,7 @@ struct JavascriptEngine::RootObject : public DynamicObject
|
|||
template <typename OpType>
|
||||
Expression* parsePostIncDec (ExpPtr& lhs)
|
||||
{
|
||||
Expression* e = lhs.release(); // careful - bare pointer is deliberately alised
|
||||
Expression* e = lhs.release(); // careful - bare pointer is deliberately aliased
|
||||
ExpPtr lhs2 (e), one (new LiteralValue (location, (int) 1));
|
||||
return new PostAssignment (location, e, new OpType (location, lhs2, one));
|
||||
}
|
||||
|
|
@ -1850,6 +1869,26 @@ var JavascriptEngine::callFunction (const Identifier& function, const var::Nativ
|
|||
return returnVal;
|
||||
}
|
||||
|
||||
var JavascriptEngine::callFunctionObject (DynamicObject* objectScope, const var& functionObject,
|
||||
const var::NativeFunctionArgs& args, Result* result)
|
||||
{
|
||||
var returnVal (var::undefined());
|
||||
|
||||
try
|
||||
{
|
||||
prepareTimeout();
|
||||
if (result != nullptr) *result = Result::ok();
|
||||
RootObject::Scope rootScope (nullptr, root, root);
|
||||
RootObject::Scope (&rootScope, root, objectScope).invokeMethod (functionObject, args, returnVal);
|
||||
}
|
||||
catch (String& error)
|
||||
{
|
||||
if (result != nullptr) *result = Result::fail (error);
|
||||
}
|
||||
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
const NamedValueSet& JavascriptEngine::getRootObjectProperties() const noexcept
|
||||
{
|
||||
return root->getProperties();
|
||||
|
|
|
|||
|
|
@ -84,6 +84,15 @@ public:
|
|||
const var::NativeFunctionArgs& args,
|
||||
Result* errorMessage = nullptr);
|
||||
|
||||
/** Calls a function object in the namespace of a dynamic object, and returns the result.
|
||||
The function arguments are passed in the same format as used by native
|
||||
methods in the var class.
|
||||
*/
|
||||
var callFunctionObject (DynamicObject* objectScope,
|
||||
const var& functionObject,
|
||||
const var::NativeFunctionArgs& args,
|
||||
Result* errorMessage = nullptr);
|
||||
|
||||
/** Adds a native object to the root namespace.
|
||||
The object passed-in is reference-counted, and will be retained by the
|
||||
engine until the engine is deleted. The name must be a simple JS identifier,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue