Passing (anonymous) functions from JavaScript to C++


#1

I’d need to be able to do something like this.

In JavaScript code :

function onButton()
{
Thing.automate(function(x){ return 1.0-x; });
}

Thing is a DynamicObject I have written that implements the “automate” method. There doesn’t seem to be a way to make the C++ code call the anonymous function defined on the JavaScript side and get its result back.

I tried various approaches to do this and not sure if it is even possible. The forum software suggested a couple of old topics but I didn’t really get clarity on the issue yet.


#2

The javascript implementation in JUCE does not support anonymous functions as I found out when experimenting with it. I think you’d have better luck integrating Google V8 into your project if you want to get serious with Javascript.


#3

Ok thanks for confirming.

I was able to do a limited workaround by using the anonymous functions inside the JavaScript code itself, but I don’t particularly like how this ended up. Sigh, I wish all the other JavaScript engines weren’t so awfully heavy weight and difficult to build… :disappointed: Maybe I have to look into Lua again…


#4

I wouldn’t give up so easy. With a little digging inside the Javascript engine, you might find something that you can hack together. Look for the findAndInvoke() method and see if you can get something useful out of it.

Another way would be parsing the body of the anonymous function and evaluate it as JavascriptCode from C++.


#5

Yeah, I don’t think it’d be particularly hard to add this - probably only a few of lines of code in the right place. Don’t have time right now to dig in there and figure it out, but hope someone else does!


#6

It might also be worth looking at embedding Ruby, seems quite straightforward to integrate and personally I much prefer it over Javascript.

(Although ES6 / ES2015 have made big improvements to JS)


#7

Hi Jules,

I had the same problem and wanted really to have the possibility to call a Javascript Function attached dynamically to a DynamicObject.

Finally i ended up with that function added in the javascript engine which seems to work as expected and grab the correct context/scope.
Would it be possible to integrate such function or capability ? It would be really a real change if you really can call JS from C++ as you can really dive in scripting capabilities/interaction, like use a javascript callback called from a C++ object.

var JavascriptEngine::callFunction (DynamicObject& object,
                                    const Identifier& function,
                                    const var::NativeFunctionArgs& args,
                                    Result* result
                                    )
{
    var returnVal (var::undefined());
    
    try
    {
        prepareTimeout();
        if (result != nullptr) *result = Result::ok();
        
        RootObject::Scope parentScope (nullptr, root, root);
        
        RootObject::Scope (&parentScope, root, &object).findAndInvokeMethod (function, args, returnVal);
    }
    catch (String& error)
    {
        if (result != nullptr) *result = Result::fail (error);
    }
    
    return returnVal;
}

HTH Thanks,
Best regards,
Charles