c++ call wren function error

44 views
Skip to first unread message

tongtang li

unread,
Mar 29, 2022, 3:52:36 AM3/29/22
to Wren
#include <string>
#include <iostream>
#include "wren.hpp"

using namespace std;

class View
{
public:
};

static void viewAllocate(WrenVM* vm)
{
    View** vw = (View**)wrenSetSlotNewForeign(vm,
        0, 0, sizeof(View*));
    *vw = new View;
}

static void viewFinalize(void* data)
{
    auto vw = (View**)data;
    if (vw && *vw) {
        delete* vw;
        *vw = NULL;
    }
}

static void viewDraw(WrenVM* vm)
{
    View** vw = (View**)wrenGetSlotForeign(vm, 0);
    const char* str = wrenGetSlotString(vm, 1);
    cout << str << endl;

    auto var = wrenGetSlotHandle(vm, 2);
    wrenEnsureSlots(vm, 2);
    wrenSetSlotHandle(vm, 0, var);
    wrenSetSlotString(vm, 1, "form c++");
    auto fn = wrenMakeCallHandle(vm, "call(_)");
    wrenCall(vm, fn);
    wrenReleaseHandle(vm, var);
    wrenReleaseHandle(vm, fn);
}

WrenForeignClassMethods bindForeignClass(
    WrenVM* vm, const char* module, const char* className)
{
    WrenForeignClassMethods methods;
    if (strcmp(className, "View") == 0)
    {
        methods.allocate = viewAllocate;
        methods.finalize = viewFinalize;
    }
    else
    {
        // Unknown class.
        methods.allocate = NULL;
        methods.finalize = NULL;
    }
    return methods;
}

WrenForeignMethodFn bindForeignMethod(WrenVM* vm, const char* module,
    const char* className, bool isStatic, const char* signature)
{
    if (strcmp(className, "View") == 0)
    {
        if (!isStatic && strcmp(signature, "draw(_,_)") == 0)
        {
            return viewDraw;
        }
    }
    // Unknown method.
    return NULL;
}

static void loadModuleComplete(
    WrenVM* vm,
    const char* module,
    WrenLoadModuleResult result)
{
}

static string viewCode = R"(
    foreign class View {
      construct new() {}
      foreign draw(text,fn)
    }
)";

static WrenLoadModuleResult myLoadModule(WrenVM* vm, const char* name) {
    WrenLoadModuleResult result = { 0 };
    if (strcmp(name, "view") == 0) {
        result.onComplete = loadModuleComplete;
        result.source = viewCode.c_str();
    }
    return result;
}

static void writeFn(WrenVM* vm, const char* text)
{
    printf("%s", text);
}

void errorFn(WrenVM* vm, WrenErrorType errorType,
    const char* module, const int line,
    const char* msg)
{
    switch (errorType)
    {
    case WREN_ERROR_COMPILE:
    {
        printf("[%s line %d] [Error] %s\n", module, line, msg);
    } break;
    case WREN_ERROR_STACK_TRACE:
    {
        printf("[%s line %d] in %s\n", module, line, msg);
    } break;
    case WREN_ERROR_RUNTIME:
    {
        printf("[Runtime Error] %s\n", msg);
    } break;
    }
}

int main()
{
    WrenConfiguration config;
    wrenInitConfiguration(&config);
    config.writeFn = &writeFn;
    config.errorFn = &errorFn;
    config.loadModuleFn = &myLoadModule;
    config.bindForeignClassFn = &bindForeignClass;
    config.bindForeignMethodFn = &bindForeignMethod;

    WrenVM* vm = wrenNewVM(&config);

    const char* module = "main";
    const char* script = R"(
        import "view" for View

        class Main {
            static main() {
                var vw = View.new()
                var fn = Fn.new {|arg|
                    System.print(arg)
                }
                vw.draw("Hello,OurNav", fn)
            }
        }
        )";

    WrenInterpretResult result = wrenInterpret(vm, module, script);

    switch (result) {
    case WREN_RESULT_COMPILE_ERROR:
    { printf("Compile Error!\n"); } break;
    case WREN_RESULT_RUNTIME_ERROR:
    { printf("Runtime Error!\n"); } break;
    case WREN_RESULT_SUCCESS:
    { printf("wrenInterpret Success!\n"); } break;
    }

    wrenEnsureSlots(vm, 1);
    wrenGetVariable(vm, module, "Main", 0);
    auto mainFn = wrenMakeCallHandle(vm, "main()");
    wrenCall(vm, mainFn);
    wrenReleaseHandle(vm, mainFn);

    wrenFreeVM(vm);

    return 0;
}

wrenInterpret Success!
Hello,OurNav
[Runtime Error] Main metaclass does not implement 'call(_)'.
[main line 6] in main()

Reply all
Reply to author
Forward
0 new messages