diff --git a/src/scripting/wren_state.cpp b/src/scripting/wren_state.cpp index c1a4936..9c7c404 100644 --- a/src/scripting/wren_state.cpp +++ b/src/scripting/wren_state.cpp @@ -44,6 +44,52 @@ namespace lunarium return mLogCat; } + WrenHandle* WrenState::GetWrenClassHandle(std::string from_module, std::string class_name) + { + // Load the class into slot 0. + wrenEnsureSlots(mpVM, 1); + wrenGetVariable(mpVM, from_module.c_str(), class_name.c_str(), 0); + WrenHandle* handle = wrenGetSlotHandle(mpVM, 0); + return handle; + } + + WrenHandle* WrenState::GetWrenMethodHandle(std::string method_signature) + { + WrenHandle* handle = wrenMakeCallHandle(mpVM, method_signature.c_str()); + return handle; + } + + void WrenState::CallWrenMethod(WrenHandle* method, WrenHandle* receiver, std::vector params, std::string name_tag) + { + + wrenEnsureSlots(mpVM, params.size() + 1); + for (int i = 0; i < params.size(); i++) + { + switch (params[i].Type) + { + case WrenParamType::WPT_DOUBLE: wrenSetSlotDouble(mpVM, i + 1, params[i].As.Double); break; + case WrenParamType::WPT_BOOL: wrenSetSlotBool(mpVM, i + 1, params[i].As.Bool); break; + case WrenParamType::WPT_STR: wrenSetSlotString(mpVM, i + 1, params[i].As.String); break; + default: Logger::Warn(mLogCat, "Unknown wren parameter type: %d", (int)params[i].Type); + } + } + + wrenSetSlotHandle(mpVM, 0, receiver); + WrenInterpretResult result = wrenCall(mpVM, method); + + switch (result) + { + case WREN_RESULT_COMPILE_ERROR: Logger::Trace(mLogCat, "Call compile error in module: %s", name_tag.c_str()); break; + case WREN_RESULT_RUNTIME_ERROR: Logger::Trace(mLogCat, "Call runtime error in module: %s", name_tag.c_str()); break; + case WREN_RESULT_SUCCESS: Logger::Trace(mLogCat, "Call %s run successfully", name_tag.c_str()); break; + } + } + + void WrenState::ReleaseWrenHandle(WrenHandle* handle) + { + wrenReleaseHandle(mpVM, handle); + } + void WrenState::RunScript(WrenScript* script) { diff --git a/src/scripting/wren_state.h b/src/scripting/wren_state.h index be4d73e..db61379 100644 --- a/src/scripting/wren_state.h +++ b/src/scripting/wren_state.h @@ -15,9 +15,31 @@ #include #include +#include namespace lunarium { + enum class WrenParamType + { + WPT_DOUBLE, + WPT_BOOL, + WPT_STR, + }; + + struct WrenParameter + { + WrenParamType Type; + union + { + double Double; + float Float; + int Int; + char Char; + bool Bool; + char* String; + } As; + }; + class WrenScript; class WrenState @@ -31,6 +53,11 @@ namespace lunarium void RunScript(WrenScript* script); void RunSnippet(std::string name, std::string code); + WrenHandle* GetWrenClassHandle(std::string from_module, std::string class_name); + WrenHandle* GetWrenMethodHandle(std::string method_signature); // signature example (mehtod takes 2 parameters): method_name(_,_) + void CallWrenMethod(WrenHandle* method, WrenHandle* receiver, std::vector params, std::string name_tag); + void ReleaseWrenHandle(WrenHandle* handle); + // CALL BACKS static void WriteFN(WrenVM* vm, const char* text); static void ErrorFN(WrenVM* vm, WrenErrorType type, const char* module, int line, const char* message); diff --git a/src/world/world.cpp b/src/world/world.cpp index 79833fc..e26c78d 100644 --- a/src/world/world.cpp +++ b/src/world/world.cpp @@ -45,13 +45,22 @@ namespace lunarium { mScriptState.Initialize().LogIfFailed(LogCategory::GAME_SYSTEM, "Failed to initialize the world script state"); - // TODO: Load the world interface script + // Load the world interface script mWorldInterface.SetModuleName("WorldInterface"); std::string code = File::ReadTextFile("world_interface.wren"); // This will eventually move to internal data mWorldInterface.SetScriptCode(code); mScriptState.RunScript(&mWorldInterface); - mScriptState.RunSnippet("WorldInterface", "WorldInterface.Init()"); + + // Get class and method handles + mWIHandle = mScriptState.GetWrenClassHandle("WorldInterface", "WorldInterface"); + mWIInitMethod = mScriptState.GetWrenMethodHandle("Init()"); + mWIDoOnLoadMethod = mScriptState.GetWrenMethodHandle("DoOnLoad()"); + mWIDoOnUnloadMethod = mScriptState.GetWrenMethodHandle("DoOnUnload()"); + mWIUpdateMethod = mScriptState.GetWrenMethodHandle("Update(_)"); + + // Init the interface + mScriptState.CallWrenMethod(mWIInitMethod, mWIHandle, {}, "WorldInterface.Init()"); } void World::OnLoad() @@ -76,13 +85,15 @@ namespace lunarium } // Call OnLoad for each registered EntityBehavior class object - mScriptState.RunSnippet("WorldInterface", "WorldInterface.DoOnLoad()"); + //mScriptState.RunSnippet("WorldInterface", "WorldInterface.DoOnLoad()"); + mScriptState.CallWrenMethod(mWIDoOnLoadMethod, mWIHandle, {}, "WorldInterface.DoOnLoad()"); } void World::OnUnload() { // TODO: Call OnUnLoad for each registered EntityBehavior class object - mScriptState.RunSnippet("WorldInterface", "WorldInterface.DoOnUnload()"); + //mScriptState.RunSnippet("WorldInterface", "WorldInterface.DoOnUnload()"); + mScriptState.CallWrenMethod(mWIDoOnUnloadMethod, mWIHandle, {}, "WorldInterface.DoOnUnload()"); mScriptState.Shutdown(); } @@ -100,10 +111,11 @@ namespace lunarium { // Update all scripts // Call OnUpdate for each registered EntityBehavior class object - std::string code = "WorldInterface.Update("; - code.append(std::to_string(dt)); - code.append(")"); - mScriptState.RunSnippet("WorldInterface", code); + // std::string code = "WorldInterface.Update("; + // code.append(std::to_string(dt)); + // code.append(")"); + // mScriptState.RunSnippet("WorldInterface", code); + mScriptState.CallWrenMethod(mWIUpdateMethod, mWIHandle, { {WrenParamType::WPT_DOUBLE, (double)dt} }, "WorldInterface.Update(dt)"); diff --git a/src/world/world.h b/src/world/world.h index 395cd34..b1e2796 100644 --- a/src/world/world.h +++ b/src/world/world.h @@ -24,6 +24,8 @@ #include #include +struct WrenHandle; + namespace lunarium { class Renderer2D; @@ -107,6 +109,11 @@ namespace lunarium std::string mName; WrenState mScriptState; WrenScript mWorldInterface; + WrenHandle* mWIHandle; + WrenHandle* mWIInitMethod; + WrenHandle* mWIDoOnLoadMethod; + WrenHandle* mWIDoOnUnloadMethod; + WrenHandle* mWIUpdateMethod; // State critical Data entt::registry mECSRegistry;