wrenpp icon indicating copy to clipboard operation
wrenpp copied to clipboard

Binding a C++ member function to a static Wren method

Open xSke opened this issue 6 years ago • 2 comments

Is it possible to bind a C++ member function (or closure, for that matter) to a static Wren method? I can't figure out a way to get any sort of instance state inside those function bindings. (For example, if I wanted to bind a Wren function to close a window, I'd need access to the window handle from a closure scope or member variable)

xSke avatar Jul 30 '17 17:07 xSke

I managed to hack it to work with CFunctions:

template<class F> static void bind(wrenpp::ClassContext ctx, const std::string &sig, F const &callback) {
    static auto f = [=](WrenVM* w) {
        callback(w);
    };

    ctx.bindCFunction(true, sig, [](WrenVM* w) {
        f(w);
    }).endClass();
}

Callable with:

int counter = 42;
// ....
auto ctx = vm.beginModule("main").beginClass("Test");
bind(ctx, "count()", [&](WrenVM *w) {
    wrenSetSlotDouble(w, 0, counter++);
});

However, this is a really hacky solution and also doesn't work with the higher-level bindings.

xSke avatar Jul 30 '17 22:07 xSke

Sorry that this response has taken forever!

You could try binding a Cfunction. It's a raw WrenForeignMethodFn (which is all that Wren sees of your class methods, see src/include/wren.h in the Wren repo) that you can bind to a class by doing vm.beginModule("main").beginClass("Test").bindCFunction(true, &wren_count, "count()");.

The function would then be something like:

int counter = 42;

void wren_count(WrenVM* vm)
{
  wrenSetSlotDouble(vm, 0, counter++);
}

Adding wrappers for lambdas is probably something I should add to my TO-DO list, since it's a bit unfortunate to have to write this sort of boiler-plate code manually.

Nelarius avatar Sep 21 '17 18:09 Nelarius