Removed the last remnants of Wren QQ

This commit is contained in:
WiggleWizard
2024-09-17 00:08:04 +01:00
parent 4ac7d1cfc9
commit 1b2abced1e
15 changed files with 1 additions and 686 deletions

View File

@@ -1,236 +0,0 @@
#include "ScriptingEngine.h"
#include "WrenScript.h"
#include "src/FileSystem/FileSystem.h"
#include "src/Scripting/Modules/ScriptModule.h"
#include "src/Scripting/Modules/EngineModule.h"
#include "src/Scripting/Modules/SceneModule.h"
#include "src/Scripting/Modules/MathModule.h"
#include "src/Scripting/Modules/InputModule.h"
#include "src/Scripting/Modules/PhysicsModule.h"
#include "src/Resource/StaticResources.h"
namespace Nuake {
WrenVM* ScriptingEngine::m_WrenVM;
std::map<std::string, Ref<WrenScript>> ScriptingEngine::m_Scripts;
std::map<std::string, Ref<ScriptModule>> ScriptingEngine::Modules;
std::vector<std::string> ScriptingEngine::m_LoadedScripts;
void errorFn(WrenVM* vm, WrenErrorType errorType,
const char* moduleName, const int line,
const char* msg)
{
switch (errorType)
{
case WREN_ERROR_COMPILE:
{
std::string t = std::string(moduleName) + " line " + std::to_string(line) + ": " + msg;
Logger::Log(t, "script", CRITICAL);
Engine::ExitPlayMode();
} break;
case WREN_ERROR_STACK_TRACE:
{
std::string t = "Stack trace: " + std::string(moduleName) + " line " + std::to_string(line) + ": " + msg;
Logger::Log(t, "script", CRITICAL);
} break;
case WREN_ERROR_RUNTIME:
{
std::string t = "Script Runtime Error: " + std::string(msg);
Logger::Log(t, "script", WARNING);
} break;
default:
{
std::string t = "Script Runtime Error: " + std::string(msg);
Logger::Log(t, "script", CRITICAL);
}
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;
}
}
#define GET_STATIC_RESOURCE_SCRIPT_SRC(name) std::string(reinterpret_cast<const char*>(name), reinterpret_cast<const char*>(name) + name##_len)
std::map<std::string, std::string> _ModulesSRC =
{
{ "Audio", GET_STATIC_RESOURCE_SCRIPT_SRC(StaticResources::Resources_Scripts_Audio_wren) },
{ "Engine", GET_STATIC_RESOURCE_SCRIPT_SRC(StaticResources::Resources_Scripts_Engine_wren) },
{ "Input", GET_STATIC_RESOURCE_SCRIPT_SRC(StaticResources::Resources_Scripts_Input_wren) },
{ "Math", GET_STATIC_RESOURCE_SCRIPT_SRC(StaticResources::Resources_Scripts_Math_wren) },
{ "Physics", GET_STATIC_RESOURCE_SCRIPT_SRC(StaticResources::Resources_Scripts_Physics_wren) },
{ "Scene", GET_STATIC_RESOURCE_SCRIPT_SRC(StaticResources::Resources_Scripts_Scene_wren) },
{ "ScriptableEntity", GET_STATIC_RESOURCE_SCRIPT_SRC(StaticResources::Resources_Scripts_ScriptableEntity_wren) },
};
void onCompleteCB(WrenVM* vm, const char* name, WrenLoadModuleResult result)
{
delete result.source;
}
const std::string NuakeModulePrefix = "Nuake:";
WrenLoadModuleResult myLoadModule(WrenVM* vm, const char* name)
{
WrenLoadModuleResult result = { 0 };
result.onComplete = &onCompleteCB; // This will take care of the clean up of the new char*
std::string sname = std::string(name);
std::string path = "resources/" + std::string(name);
std::string fileContent = "";
bool isAbsolute = false;
if (sname.rfind(NuakeModulePrefix, 0) == 0)
{
size_t prefixPosition = sname.find(NuakeModulePrefix);
sname.erase(prefixPosition, NuakeModulePrefix.length());
path = "Resources/Scripts/"+std::string(sname);
if (_ModulesSRC.find(sname) != _ModulesSRC.end())
{
fileContent = _ModulesSRC[sname];
}
else
{
Logger::Log("Internal script module not found: " + sname + ". \n Did you forget to register it?", "scripting engine", CRITICAL);
}
}
else
{
path = FileSystem::Root + name;
isAbsolute = true;
}
if (!hasEnding(path, ".wren"))
path += ".wren";
if (isAbsolute)
{
fileContent = FileSystem::ReadFile(path, true);
}
// We have to use c style char array and the callback takes care of cleaning up.
char* sourceC = new char[fileContent.length() + 1];
char* c = strcpy(sourceC, fileContent.c_str()); // copy into c array
result.source = c;
return result;
}
//Ref<WrenScript> ScriptingEngine::RegisterScript(const std::string& path, const std::string& mod)
//{
// //// Check if scripts has already been loaded.
// //// You can't import the same module twice, otherwise, compile error.
// //if (m_Scripts.find(path) == m_Scripts.end())
// //{
// // std::string query = "import \"" + path + "\" for " + mod;
// // wrenInterpret(m_WrenVM, "main", query.c_str());
// //}
// //
// //return CreateRef<WrenScript>(path, mod);
//}
// Useful to check if a script has been imported, importing a script
// twice gives a compile error.
bool ScriptingEngine::IsScriptImported(const std::string& path)
{
for (auto& script : m_LoadedScripts)
{
if (script == path)
return true;
}
return false;
}
void ScriptingEngine::ImportScript(const std::string& path)
{
if (IsScriptImported(path))
return;
m_LoadedScripts.push_back(path);
}
void ScriptingEngine::RegisterModule(Ref<ScriptModule> scriptModule)
{
Modules[scriptModule->GetModuleName()] = scriptModule;
scriptModule->RegisterModule(m_WrenVM);
}
void ScriptingEngine::InitScript(Ref<WrenScript> script)
{
script->CallInit();
}
void ScriptingEngine::UpdateScript(Ref<WrenScript> script, Timestep timestep)
{
script->CallUpdate(timestep);
}
void ScriptingEngine::ExitScript(Ref<WrenScript> script)
{
script->CallExit();
}
void ScriptingEngine::Init()
{
Logger::Log("Initializing Scripting Engine");
m_Scripts = std::map<std::string, Ref<WrenScript>>();
m_LoadedScripts.clear();
WrenConfiguration config;
wrenInitConfiguration(&config);
config.loadModuleFn = &myLoadModule;
config.errorFn = &errorFn;
config.writeFn = &writeFn;
config.bindForeignMethodFn = &bindForeignMethod;
m_WrenVM = wrenNewVM(&config);
Logger::Log("Registing Scripting Modules");
RegisterModule(CreateRef<ScriptAPI::EngineModule>());
RegisterModule(CreateRef<ScriptAPI::SceneModule>());
RegisterModule(CreateRef<ScriptAPI::MathModule>());
RegisterModule(CreateRef<ScriptAPI::InputModule>());
RegisterModule(CreateRef<ScriptAPI::PhysicsModule>());
Logger::Log("Scripting Modules Registered");
Logger::Log("Scripting Engine initialized successfully");
}
void ScriptingEngine::Close()
{
wrenFreeVM(m_WrenVM);
}
WrenForeignMethodFn ScriptingEngine::bindForeignMethod(WrenVM* vm, const char* modul, const char* className, bool isStatic, const char* signature)
{
if (Modules.find(className) != Modules.end())
{
Ref<ScriptModule> mod = Modules[className];
void* ptr = mod->GetMethodPointer(signature);
return (WrenForeignMethodFn)ptr;
}
return nullptr;
}
WrenVM* ScriptingEngine::GetWrenVM()
{
return m_WrenVM;
}
}

View File

@@ -1,47 +0,0 @@
#pragma once
#include "src/Core/Core.h"
#include "src/Core/Timestep.h"
#include <string>
#include <vector>
#include <map>
#include "src/Vendors/wren/src/include/wren.hpp"
namespace Nuake
{
class WrenScript;
class ScriptModule;
class ScriptingEngine
{
private:
static WrenVM* m_WrenVM;
static std::vector<std::string> m_LoadedScripts;
static std::map<std::string, Ref<WrenScript>> m_Scripts;
static std::map<std::string, Ref<ScriptModule>> Modules;
public:
static void Init();
static void RunCode(const std::string& code);
static void Close();
static Ref<WrenScript> RegisterScript(const std::string& path, const std::string& mod);
static bool IsScriptImported(const std::string& path);
static void ImportScript(const std::string& path);
static void RegisterModule(Ref<ScriptModule> module);
static void InitScript(Ref<WrenScript> script);
static void UpdateScript(Ref<WrenScript> script, Timestep timestep);
static void ExitScript(Ref<WrenScript> script);
static WrenForeignMethodFn bindForeignMethod(
WrenVM* vm,
const char* module,
const char* className,
bool isStatic,
const char* signature);
static WrenVM* GetWrenVM();
};
}

View File

@@ -1,185 +0,0 @@
#include "WrenScript.h"
#include "src/Core/Logger.h"
#include "src/Core/String.h"
#include "src/FileSystem/FileSystem.h"
#include "src/FileSystem/File.h"
#include <src/Vendors/wren/src/include/wren.h>
#include <fstream>
namespace Nuake
{
WrenScript::WrenScript(Ref<File> file, bool isEntityScript)
{
mFile = file;
m_IsEntityScript = isEntityScript;
ParseModules();
}
void WrenScript::ParseModules()
{
std::ifstream MyReadFile(mFile->GetAbsolutePath());
std::string fileContent = "";
while (getline(MyReadFile, fileContent))
{
bool hasFoundModule = false;
auto splits = String::Split(fileContent, ' ');
for (unsigned int i = 0; i < splits.size(); i++)
{
std::string s = splits[i];
if (s == "class" && i + 1 < splits.size() && !hasFoundModule)
{
std::string moduleFound = splits[i + 1];
modules.push_back(moduleFound);
hasFoundModule = true;
}
}
}
MyReadFile.close();
}
std::vector<std::string> WrenScript::GetModules() const
{
return modules;
}
void WrenScript::Build(unsigned int moduleId, bool isEntity)
{
WrenVM* vm = ScriptingEngine::GetWrenVM();
const std::string& relativePath = mFile->GetRelativePath();
// Can't import twice the same script, otherwise gives a compile error.
if (!ScriptingEngine::IsScriptImported(relativePath))
{
const std::string& source = "import \"" + relativePath + "\" for " + GetModules()[moduleId];
WrenInterpretResult result = wrenInterpret(vm, "main", source.c_str());
if (result == WREN_RESULT_SUCCESS)
{
Logger::Log("[ScriptingEngine] Compiled succesfully: " + std::to_string(result));
m_HasCompiledSuccesfully = true;
ScriptingEngine::ImportScript(relativePath);
}
else
{
Logger::Log("[ScriptingEngine] Compiled failed: " + std::to_string(result));
m_HasCompiledSuccesfully = false;
return;
}
}
// Get handle to class
wrenEnsureSlots(vm, 1);
wrenGetVariable(vm, "main", GetModules()[moduleId].c_str(), 0);
WrenHandle* classHandle = wrenGetSlotHandle(vm, 0);
// Call the constructor
WrenHandle* constructHandle = wrenMakeCallHandle(vm, "new()");
wrenCall(vm, constructHandle);
// Retreive value of constructor
this->m_Instance = wrenGetSlotHandle(vm, 0);
// Create handles to the instance methods.
this->m_OnInitHandle = wrenMakeCallHandle(vm, "init()");
this->m_OnUpdateHandle = wrenMakeCallHandle(vm, "update(_)");
this->m_OnFixedUpdateHandle = wrenMakeCallHandle(vm, "fixedUpdate(_)");
this->m_OnExitHandle = wrenMakeCallHandle(vm, "exit()");
if (isEntity)
this->m_SetEntityIDHandle = wrenMakeCallHandle(vm, "SetEntityId(_)");
m_HasCompiledSuccesfully = true;
}
void WrenScript::CallInit()
{
if (!m_HasCompiledSuccesfully) return;
WrenVM* vm = ScriptingEngine::GetWrenVM();
wrenSetSlotHandle(vm, 0, this->m_Instance);
WrenInterpretResult result = wrenCall(vm, this->m_OnInitHandle);
}
void WrenScript::CallUpdate(float timestep)
{
if (!m_HasCompiledSuccesfully) return;
WrenVM* vm = ScriptingEngine::GetWrenVM();
wrenEnsureSlots(vm, 2);
wrenSetSlotHandle(vm, 0, this->m_Instance);
wrenSetSlotDouble(vm, 1, timestep);
WrenInterpretResult result = wrenCall(vm, this->m_OnUpdateHandle);
}
void WrenScript::CallFixedUpdate(float timestep)
{
if (!m_HasCompiledSuccesfully) return;
WrenVM* vm = ScriptingEngine::GetWrenVM();
wrenEnsureSlots(vm, 2);
wrenSetSlotHandle(vm, 0, this->m_Instance);
wrenSetSlotDouble(vm, 1, timestep);
WrenInterpretResult result = wrenCall(vm, this->m_OnFixedUpdateHandle);
}
void WrenScript::CallExit()
{
if (!m_HasCompiledSuccesfully || !m_Instance)
return;
WrenVM* vm = ScriptingEngine::GetWrenVM();
wrenEnsureSlots(vm, 1);
wrenSetSlotHandle(vm, 0, this->m_Instance);
WrenInterpretResult result = wrenCall(vm, this->m_OnExitHandle);
}
void WrenScript::RegisterMethod(const std::string& signature)
{
if (!m_HasCompiledSuccesfully)
return;
WrenVM* vm = ScriptingEngine::GetWrenVM();
WrenHandle* handle = wrenMakeCallHandle(vm, signature.c_str());
methods.emplace(signature, handle);
}
void WrenScript::CallMethod(const std::string& signature)
{
if (!m_HasCompiledSuccesfully)
return;
WrenVM* vm = ScriptingEngine::GetWrenVM();
// Not found. maybe try to register it?
if (methods.find(signature) == methods.end())
return;
wrenSetSlotHandle(vm, 0, this->m_Instance);
WrenHandle* handle = methods[signature];
WrenInterpretResult result = wrenCall(vm, handle);
}
Ref<File> WrenScript::GetFile() const
{
return mFile;
}
void WrenScript::SetScriptableEntityID(int id)
{
if (!m_HasCompiledSuccesfully)
return;
WrenVM* vm = ScriptingEngine::GetWrenVM();
wrenSetSlotHandle(vm, 0, this->m_Instance);
wrenSetSlotDouble(vm, 1, id);
WrenInterpretResult result = wrenCall(vm, this->m_SetEntityIDHandle);
}
}

View File

@@ -1,53 +0,0 @@
#pragma once
#include "ScriptingEngine.h"
#include <map>
#include <string>
struct WrenHandle;
namespace Nuake
{
class File;
class WrenScript
{
private:
bool m_HasCompiledSuccesfully;
bool m_IsEntityScript = false;
std::vector<std::string> modules;
Ref<File> mFile;
std::map <std::string, WrenHandle*> methods;
WrenHandle* m_Instance = nullptr;
WrenHandle* m_OnInitHandle;
WrenHandle* m_OnUpdateHandle;
WrenHandle* m_OnFixedUpdateHandle;
WrenHandle* m_OnExitHandle;
WrenHandle* m_SetEntityIDHandle;
public:
WrenScript(Ref<File> file, bool isEntityScript);
void ParseModules();
void Build(unsigned int moduleId, bool isEntityScript = false);
// Method calls
void CallInit();
void CallUpdate(float timestep);
void CallFixedUpdate(float timestep);
void CallExit();
void RegisterMethod(const std::string& signature);
void CallMethod(const std::string& signature);
Ref<File> GetFile() const;
void SetScriptableEntityID(int id);
bool HasCompiledSuccesfully() const { return m_HasCompiledSuccesfully; }
std::vector<std::string> GetModules() const;
WrenHandle* GetWrenInstanceHandle() const { return m_Instance; }
};
}