| #include "CAngelScriptEngine.h"
|
| #include <string>
|
| #include <sstream>
|
| #include <iostream>
|
| #include <fstream>
|
|
|
| #include "CEngine.h"
|
| #include "CLogger.h"
|
| #include "U_Log.h"
|
|
|
| #include "scriptbuilder/scriptbuilder.h"
|
| #include "scriptstdstring/scriptstdstring.h"
|
| #include "scriptarray/scriptarray.h"
|
|
|
| void MessageCallback(const asSMessageInfo* msg, void*)
|
| {
|
| std::string type = "ERR";
|
| if (msg->type == asMSGTYPE_WARNING) { type = "WARN"; }
|
| else if (msg->type == asMSGTYPE_INFORMATION) { type = "INFO"; }
|
|
|
| std::stringstream msg_err;
|
| msg_err << type << " (" << msg->row << ", " << msg->col << "): " << msg->message;
|
|
|
| Log::Err(msg_err.str());
|
| }
|
|
|
| CAngelScriptEngine::CAngelScriptEngine()
|
| {
|
|
|
| }
|
|
|
| CAngelScriptEngine::~CAngelScriptEngine()
|
| {
|
| Reset();
|
| }
|
|
|
| void CAngelScriptEngine::LoadDirectory(const std::string& moduleName, const std::filesystem::path& dir)
|
| {
|
| if (!std::filesystem::exists(dir) || !std::filesystem::is_directory(dir)) { return; }
|
| std::vector<std::filesystem::path> as_files;
|
|
|
| for (const auto& entry : std::filesystem::recursive_directory_iterator(dir))
|
| {
|
| if (entry.is_regular_file() && entry.path().extension() == ".as")
|
| {
|
| as_files.push_back(entry.path());
|
| }
|
| }
|
|
|
| std::vector<std::pair<std::string, std::string>> scripts;
|
| for(auto& path : as_files)
|
| {
|
| std::ifstream file(path);
|
| if(!file.is_open())
|
| {
|
| continue;
|
| }
|
|
|
| std::stringstream stream;
|
|
|
| stream << std::noskipws << file.rdbuf();
|
| std::string code = stream.str();
|
|
|
| file.close();
|
| scripts.push_back({ path.stem().string(), std::move(code) });
|
| }
|
|
|
| LoadModule(moduleName, scripts);
|
| }
|
|
|
| void CAngelScriptEngine::CallInitFunctions()
|
| {
|
| for(const auto& sn : SectionNames)
|
| {
|
| std::string funcName = sn + "_init";
|
| asIScriptFunction* func = Module->GetFunctionByName(funcName.c_str());
|
|
|
| Context->Prepare(func);
|
| Context->Execute();
|
| Context->Unprepare();
|
| }
|
| }
|
|
|
| void CAngelScriptEngine::LoadModule(const std::string& name, const std::vector<std::pair<std::string, std::string>>& scripts)
|
| {
|
| CScriptBuilder builder;
|
| builder.StartNewModule(Engine, name.c_str());
|
|
|
| for (const auto& [nm, sc] : scripts)
|
| {
|
| std::cout << "Section " << nm << std::endl;
|
| auto err = builder.AddSectionFromMemory(nm.c_str(), sc.c_str(), sc.size());
|
|
|
| if(err < 0)
|
| {
|
| std::cout << "Err " << err << '\n';
|
| }
|
| else
|
| {
|
| SectionNames.push_back(nm);
|
| //TODO error handling
|
| std::cout << "Added\n";
|
| }
|
|
|
| }
|
| if (builder.BuildModule() < 0) { } //TODO error handling
|
|
|
| Module = Engine->GetModule(name.c_str());
|
| std::cout << "Module " << name << std::endl;
|
| }
|
|
|
| void __log(const std::string& msg)
|
| {
|
| Log::Out(msg);
|
| std::cout << msg;
|
| }
|
|
|
| void __logf(float msg)
|
| {
|
| Log::Instance() << msg << Log::Endl;
|
| }
|
|
|
| CComponent* CM_GetComponent(CComponentsManager* mgr, const std::string& name)
|
| {
|
| std::string lower = name;
|
| std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
|
|
|
| return mgr->GetComponentRaw(lower);
|
| }
|
|
|
| CComponent* CM_Create(CComponentsManager* mgr, const std::string& type, bool instantInit)
|
| {
|
| std::string lower = type;
|
| std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
|
|
|
| if(!mgr->IsComponentPresent(lower))
|
| {
|
| mgr->CreateComponent(lower, instantInit);
|
| }
|
|
|
| return mgr->GetComponentRaw(lower);
|
| }
|
|
|
| bool CM_IsComponentPresent(CComponentsManager* _mgr, const std::string& _type)
|
| {
|
| return _mgr->IsComponentPresent(_type);
|
| }
|
|
|
| void RegisterComponentsManager(asIScriptEngine* engine)
|
| {
|
| engine->RegisterObjectType("CComponentsManager", 0, asOBJ_REF | asOBJ_NOCOUNT);
|
|
|
| engine->RegisterObjectMethod
|
| (
|
| "CComponentsManager",
|
| "bool IsComponentPresent(const string &in name)",
|
| asFUNCTION(CM_IsComponentPresent),
|
| asCALL_CDECL_OBJFIRST
|
| );
|
|
|
| engine->RegisterObjectMethod
|
| (
|
| "CComponentsManager",
|
| "Component@ GetComponent(const string &in name)",
|
| asFUNCTION(CM_GetComponent),
|
| asCALL_CDECL_OBJFIRST
|
| );
|
|
|
| engine->RegisterObjectMethod
|
| (
|
| "CComponentsManager",
|
| "Component@ Create(const string &in type, bool instantInit = true)",
|
| asFUNCTION(CM_Create),
|
| asCALL_CDECL_OBJFIRST
|
| );
|
| }
|
|
|
| void RegisterTime(asIScriptEngine* engine)
|
| {
|
| engine->RegisterObjectType("CTime", 0, asOBJ_REF | asOBJ_NOCOUNT);
|
|
|
| engine->RegisterObjectMethod("CTime", "void Init()", asMETHOD(CTime, Init), asCALL_THISCALL);
|
| engine->RegisterObjectMethod("CTime", "void NewTick()", asMETHOD(CTime, NewTick), asCALL_THISCALL);
|
| engine->RegisterObjectMethod("CTime", "void EndTick()", asMETHOD(CTime, EndTick), asCALL_THISCALL);
|
|
|
| engine->RegisterObjectMethod("CTime", "float GetDeltaTime()", asMETHOD(CTime, GetDeltaTime), asCALL_THISCALL);
|
| engine->RegisterObjectMethod("CTime", "float GetFPS()", asMETHOD(CTime, GetFPS), asCALL_THISCALL);
|
|
|
| engine->RegisterObjectMethod
|
| (
|
| "CTime",
|
| "float get_DeltaTime() property",
|
| asMETHOD(CTime, GetDeltaTime),
|
| asCALL_THISCALL
|
| );
|
| }
|
|
|
| void RegisterEngine(asIScriptEngine* engine)
|
| {
|
| engine->RegisterObjectType("CEngine", 0, asOBJ_REF | asOBJ_NOCOUNT);
|
|
|
| engine->RegisterObjectMethod("CEngine", "void Init()", asMETHOD(CEngine, Init), asCALL_THISCALL);
|
| engine->RegisterObjectMethod("CEngine", "void Update()", asMETHOD(CEngine, Update), asCALL_THISCALL);
|
| engine->RegisterObjectMethod("CEngine", "void Quit()", asMETHOD(CEngine, Quit), asCALL_THISCALL);
|
|
|
| engine->RegisterObjectProperty
|
| (
|
| "CEngine",
|
| "CTime Time",
|
| asOFFSET(CEngine, Time)
|
| );
|
| }
|
|
|
| void CAngelScriptEngine::Init()
|
| {
|
| Engine = asCreateScriptEngine();
|
| if(!Engine) { return; }
|
|
|
| RegisterStdString(Engine);
|
| RegisterScriptArray(Engine, true);
|
|
|
| RegisterTime(Engine);
|
| RegisterEngine(Engine);
|
|
|
| Engine->SetMessageCallback(asFUNCTION(MessageCallback), 0, asCALL_CDECL);
|
| Engine->RegisterGlobalFunction("void log(const string &in)", asFUNCTION(__log), asCALL_CDECL);
|
| Engine->RegisterGlobalFunction("void log(float)", asFUNCTION(__logf), asCALL_CDECL);
|
|
|
| Engine->RegisterGlobalProperty("CEngine Engine", CEngine::GetInstance());
|
|
|
| Context = Engine->CreateContext();
|
| }
|
|
|
| void CAngelScriptEngine::Reset()
|
| {
|
| if(Context)
|
| {
|
| Context->Release();
|
| Context = nullptr;
|
| }
|
| if(Engine)
|
| {
|
| Engine->ShutDownAndRelease();
|
| Engine = nullptr;
|
| }
|
| }
|
| |