#if !TESTS_BUILD #include "Database.hpp" #include #include "../angelscript/extensions/scriptarray/scriptarray.h" #include "../angelscript/extensions/scriptstdstring/scriptstdstring.h" #include "ASTypeDefParser/Parser.hpp" Napi::Object Database::Init(Napi::Env env, Napi::Object exports) { Napi::Function func = DefineClass(env, "Database", {InstanceMethod("reset", &Database::Reset), InstanceMethod("loadTypeDef", &Database::LoadTypeDef), InstanceMethod("loadScript", &Database::LoadScript), InstanceMethod("build", &Database::Build), InstanceMethod("messages", &Database::GetMessages), InstanceMethod("setEngineProperty", &Database::SetEngineProperty)}); auto* constructor = new Napi::FunctionReference(); *constructor = Napi::Persistent(func); env.SetInstanceData(constructor); exports.Set("Database", func); return exports; } void Database::MessageCallback(const asSMessageInfo* msg) { _messages.push_back(new Diagnostic(msg->section, msg->row, msg->col, msg->type, msg->message)); } void Database::SetupEngine() { _engine = asCreateScriptEngine(); _builder = {}; _engine->SetMessageCallback(asMETHOD(Database, MessageCallback), this, asCALL_THISCALL); _engine->SetEngineProperty(asEP_DISALLOW_EMPTY_LIST_ELEMENTS, true); _engine->SetEngineProperty(asEP_DISALLOW_VALUE_ASSIGN_FOR_REF_TYPE, false); _engine->SetEngineProperty(asEP_ALLOW_UNSAFE_REFERENCES, true); _engine->SetEngineProperty(asEP_ALWAYS_IMPL_DEFAULT_CONSTRUCT, true); _engine->SetEngineProperty(asEP_AUTO_GARBAGE_COLLECT, false); _engine->SetEngineProperty(asEP_REQUIRE_ENUM_SCOPE, true); _engine->SetEngineProperty(asEP_PROPERTY_ACCESSOR_MODE, 2); _engine->SetEngineProperty(asEP_COMPILER_WARNINGS, 2); RegisterStdString(_engine); RegisterScriptArray(_engine, true); _builder.StartNewModule(_engine, "Module"); } Database::Database(const Napi::CallbackInfo& info) : ObjectWrap(info) { Reset(info); } void Database::SetEngineProperty(const Napi::CallbackInfo& info) { auto property = info[0].As().Int32Value(); auto value = info[1].As().Int32Value(); _engine->SetEngineProperty(static_cast(property), value); } void Database::Reset(const Napi::CallbackInfo&) { std::lock_guard lck(_lock); if (_engine != nullptr){ _engine->DiscardModule("Module"); _engine->Release(); } SetupEngine(); _result.Clear(); } void Database::LoadScript(const Napi::CallbackInfo& info) { if (info.Length() < 2) throw std::logic_error("Not enough arguments"); auto name = info[0].As().Utf8Value(); auto script = info[1].As().Utf8Value(); _builder.AddSectionFromMemory(name.c_str(), script.c_str()); } void Database::LoadTypeDef(const Napi::CallbackInfo& info) { if (info.Length() < 2) throw std::logic_error("Not enough arguments"); auto name = info[0].As().Utf8Value(); auto script = info[1].As().Utf8Value(); ASTypeDefParser::Parser::ParseAndRegister(_result, script); } Napi::Value Database::Build(const Napi::CallbackInfo& info) { std::lock_guard lck(_lock); _messages.clear(); _result.RegisterTypes(_engine); _result.RegisterImplementation(_engine); _builder.BuildModule(); return Napi::Number::New(info.Env(), 0); } Napi::Value Database::GetMessages(const Napi::CallbackInfo& info) { auto messages = Napi::Array::New(info.Env()); for (auto msg : _messages) { auto obj = Napi::Object::New(info.Env()); obj.Set("section", Napi::String::New(info.Env(), msg->GetSection())); obj.Set("row", Napi::Number::New(info.Env(), msg->GetRow())); obj.Set("col", Napi::Number::New(info.Env(), msg->GetCol())); obj.Set("type", Napi::Number::New(info.Env(), msg->GetType())); obj.Set("message", Napi::String::New(info.Env(), msg->GetMessage())); messages[messages.Length()] = obj; } return messages; } #endif