#include "ScriptingEngine.h" #include "WrenScript.h" #include "../Core/FileSystem.h" #include #include #include #include #include WrenVM* ScriptingEngine::m_WrenVM; std::map> ScriptingEngine::m_Scripts; std::map> ScriptingEngine::Modules; 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; } } void writeFn(WrenVM* vm, const char* text) { printf("%s", text); } bool hasEnding(std::string const& fullString, std::string const& ending) { if (fullString.length() >= ending.length()) { return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending)); } else { return false; } } WrenLoadModuleResult myLoadModule(WrenVM* vm, const char* name) { WrenLoadModuleResult result = { 0 }; std::string path = "resources/" + std::string(name); if(!hasEnding(path, ".wren")) path += ".wren"; std::string str = FileSystem::ReadFile(path, true); char* c = strcpy(new char[str.length() + 1], str.c_str()); result.source = c; return result; } Ref ScriptingEngine::RegisterScript(const std::string& path, const std::string& mod) { std::string query = "import \"" + path + "\" for " + mod; wrenInterpret(m_WrenVM, "main", query.c_str()); return CreateRef(path, mod); } void ScriptingEngine::RegisterModule(Ref scriptModule) { Modules[scriptModule->GetModuleName()] = scriptModule; scriptModule->RegisterModule(m_WrenVM); } void ScriptingEngine::InitScript(Ref script) { script->CallInit(); } void ScriptingEngine::UpdateScript(Ref script, Timestep timestep) { script->CallUpdate(timestep); } void ScriptingEngine::ExitScript(Ref script) { script->CallExit(); } void ScriptingEngine::Init() { m_Scripts = std::map>(); WrenConfiguration config; wrenInitConfiguration(&config); config.loadModuleFn = &myLoadModule; config.errorFn = &errorFn; config.writeFn = &writeFn; config.bindForeignMethodFn = &bindForeignMethod; m_WrenVM = wrenNewVM(&config); Ref engineModule = CreateRef(); RegisterModule(engineModule); Ref sceneModule = CreateRef(); RegisterModule(sceneModule); Ref mathModule = CreateRef(); RegisterModule(mathModule); Ref inputModule = CreateRef (); RegisterModule(inputModule); } void ScriptingEngine::Close() { wrenFreeVM(m_WrenVM); } WrenForeignMethodFn ScriptingEngine::bindForeignMethod(WrenVM* vm, const char* module, const char* className, bool isStatic, const char* signature) { if (Modules.find(className) != Modules.end()) { Ref mod = Modules[className]; void* ptr = mod->GetMethodPointer(signature); return (WrenForeignMethodFn)ptr; } } WrenVM* ScriptingEngine::GetWrenVM() { return m_WrenVM; }