Files
2024-10-03 22:28:31 +08:00

176 lines
3.6 KiB
C++

#include "dl_as.h"
#include <scriptstdstring/scriptstdstring.h>
#include <scriptbuilder/scriptbuilder.h>
#include "script/dl_as_register.h"
#include "system/dl_platform.h"
namespace dl
{
AngelScript* g_as;
AngelScript::AngelScript() :
_fileExt{ "as" }
{
// 初始化引擎
_engine = asCreateScriptEngine();
if (!_engine)
{
log_err("asCreateScriptEngine 失败!");
return;
}
//
as_register_base(this);
as_register_ui(this);
}
void AngelScript::SetPathRoot(std::string_view str)
{
_pathRoot = File::GetAbsolute(str);
}
void AngelScript::SetFileExt(std::string_view str)
{
_fileExt = str;
}
void AngelScript::SetNamePrefix(std::string_view str)
{
_namePrefix = str;
}
void AngelScript::LoadModule(std::string_view path_name, std::string_view name)
{
std::string path_relative = File::GetRelative(path_name, _pathRoot);
std::string path_real;
std::string res_name;
if (!String::GetPathAndRes(_pathRoot, path_relative, path_real, res_name, name ))
{
log_err("获取资源名错误:{} -> {}", res_name, path_real);
return;
}
CScriptBuilder builder;
int r = builder.StartNewModule(_engine, res_name.data());
if (r < 0)
{
log_err("StartNewModule失败!");
return;
}
r = builder.AddSectionFromFile(path_real.data());
if (r < 0)
{
log_err("文件或预处理错误!");
return;
}
r = builder.BuildModule();
if (r < 0)
{
printf("编译错误!");
return;
}
std::string module_name{ name };
auto iter = _allModule.find(module_name);
if (iter == _allModule.end())
{
ModuleInfo info;
info._pathAbsolute = File::GetAbsolute(path_real);
_allModule.insert({ module_name, info });
}
else
{
ModuleInfo& info = iter->second;
if (info._pathAbsolute != path_real)
{
log_err("重载入路径不匹配:{} -> {}", path_real, info._pathAbsolute);
info._pathAbsolute = path_real;
}
}
}
void AngelScript::UnloadModule(std::string_view name)
{
}
static void Pointer_construct(void** p, asINT64 a)
{
new(p) uint64_t(a);
}
static asINT64 Pointer_opConvInt(void* p)
{
return (asINT64)p;
}
int AngelScript::RegisterPointer(std::string_view name)
{
//int r = _engine->RegisterObjectType(name.data(), sizeof(void*),
// asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE);
//assert(r >= 0);
//// 整形 -> 指针
//r = _engine->RegisterObjectBehaviour(name.data(), asBEHAVE_CONSTRUCT,
// "void f(int64)",
// asFUNCTION(Pointer_construct), asCALL_CDECL_OBJFIRST);
//assert(r >= 0);
//// 指针 -> 整形
//r = _engine->RegisterObjectMethod(name.data(), "int64 opConv()",
// asFUNCTIONPR(Pointer_opConvInt, (void*), asINT64), asCALL_CDECL_OBJLAST);
//assert(r >= 0);
int r = _engine->RegisterObjectType(name.data(), 0,
asOBJ_REF | asOBJ_NOCOUNT);
assert(r >= 0);
return r;
}
asIScriptFunction* AngelScript::GetModuleFunction(std::string_view name, std::string_view func_decl)
{
asIScriptModule* mod = _engine->GetModule(name.data());
if (!mod)
{
log_err("module不存在:{}", name);
return nullptr;
}
asIScriptFunction* func = mod->GetFunctionByDecl(func_decl.data());
if (func == 0)
{
log_err("函数不存在:{}", func_decl);
return nullptr;
}
return func;
}
void AngelScript::ExcuteModule(std::string_view name)
{
asIScriptFunction* func = GetModuleFunction(name, "void main()");
if (func == 0)
return;
asIScriptContext* ctx = _engine->CreateContext();
ctx->Prepare(func);
int r = ctx->Execute();
if (r != asEXECUTION_FINISHED)
{
if (r == asEXECUTION_EXCEPTION)
{
log_err("脚本出现异常:{}", ctx->GetExceptionString());
}
}
ctx->Release();
}
AngelScript::~AngelScript()
{
_engine->ShutDownAndRelease();
}
}