AngelscriptLanguageServer/server/src/src/Database.cpp

106 lines
4.1 KiB
C++

#if !TESTS_BUILD
#include "Database.hpp"
#include <sstream>
#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<Napi::Number>().Int32Value();
auto value = info[1].As<Napi::Number>().Int32Value();
_engine->SetEngineProperty(static_cast<asEEngineProp>(property), value);
}
void Database::Reset(const Napi::CallbackInfo&) {
std::lock_guard<std::mutex> 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<Napi::String>().Utf8Value();
auto script = info[1].As<Napi::String>().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<Napi::String>().Utf8Value();
auto script = info[1].As<Napi::String>().Utf8Value();
ASTypeDefParser::Parser::ParseAndRegister(_result, script);
}
Napi::Value Database::Build(const Napi::CallbackInfo& info) {
std::lock_guard<std::mutex> 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