AngelscriptLanguageServer/server/src/src/ASTypeDefParser/TypeDefResult.hpp

132 lines
4.8 KiB
C++

#ifndef ASLSP_NATIVE_TYPEDEFRESULT_HPP
#define ASLSP_NATIVE_TYPEDEFRESULT_HPP
#include <angelscript.h>
#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <vector>
namespace ASTypeDefParser {
class TypeDefResult {
struct Type {
Type(std::string objectType, std::string classDef, std::string className, int flags,
std::vector<std::string> definitions, std::vector<std::tuple<int, std::string>> behaviours)
: ClassDef(std::move(classDef)), ClassName(std::move(className)), Definitions(std::move(definitions)),
Flags(flags), ObjectType(std::move(objectType)), Behaviours(behaviours) {}
std::string ObjectType;
std::string ClassDef;
std::string ClassName;
long Flags;
std::vector<std::string> Definitions;
std::vector<std::tuple<int, std::string>> Behaviours;
};
struct Enum {
Enum(std::string name, std::vector<std::tuple<std::string, int>> values)
: Name(std::move(name)), Values(std::move(values)) {}
std::string Name;
std::vector<std::tuple<std::string, int>> Values;
};
std::vector<Type> _types;
std::vector<Enum> _enums;
std::vector<std::string> _functions;
public:
void StoreType(const std::string& objType, const std::string& classDef, const std::string& className,
long flags, const std::vector<std::string>& definitions,
const std::vector<std::tuple<int, std::string>>& behaviours) {
_types.emplace_back(objType, classDef, className, flags, definitions, behaviours);
}
void StoreEnum(const std::string& name, const std::vector<std::tuple<std::string, int>>& values) {
_enums.emplace_back(name, values);
}
void StoreFunc(const std::string& function) { _functions.push_back(function); }
void Clear() {
_types.clear();
_enums.clear();
_functions.clear();
}
void RegisterTypes(asIScriptEngine* engine) {
for (auto& t : _types) {
try {
auto size = 0;
if (t.ObjectType == "valuetype") {
size = 1;
}
engine->RegisterObjectType(t.ClassDef.c_str(), size, t.Flags);
} catch (std::exception&) {
}
}
for (auto& t : _enums) {
try {
engine->RegisterEnum(t.Name.c_str());
} catch (std::exception&) {
}
}
}
private:
// As opposed to normal functions, behaviours can be called from the builder. If we pass a default value,
// this causes a segfault. As such, we have an empty function for them.
static void BehaviourPlaceHolder(void*){}
static void RegisterTypeImplementation(asIScriptEngine* engine, Type& t) {
for (auto& def : t.Definitions) {
auto i = engine->RegisterObjectMethod(t.ClassName.c_str(), def.c_str(), {}, asCALL_THISCALL);
if (i < 0) {
return;
}
}
for (auto& def : t.Behaviours) {
auto call = asCALL_CDECL;
if (std::get<0>(def) == 0 || std::get<0>(def) == 2) {
call = asCALL_CDECL_OBJLAST;
}
auto i =
engine->RegisterObjectBehaviour(t.ClassName.c_str(), static_cast<asEBehaviours>(std::get<0>(def)),
std::get<1>(def).c_str(), asFUNCTION(BehaviourPlaceHolder), call);
if (i < 0) {
return;
}
}
}
public:
void RegisterImplementation(asIScriptEngine* engine) {
for (auto& t : _types) {
if ((t.Flags & asOBJ_TEMPLATE) == 0) {
continue;
}
RegisterTypeImplementation(engine, t);
}
for (auto& t : _types) {
if ((t.Flags & asOBJ_TEMPLATE) != 0) {
continue;
}
RegisterTypeImplementation(engine, t);
}
for (auto& t : _enums) {
for (auto& v : t.Values) {
engine->RegisterEnumValue(t.Name.c_str(), std::get<0>(v).c_str(), std::get<1>(v));
}
}
for (auto& f : _functions) {
if (engine->GetGlobalFunctionByDecl(f.c_str()) != nullptr) {
continue;
}
engine->RegisterGlobalFunction(f.c_str(), {}, asCALL_CDECL);
}
}
};
}
#endif // ASLSP_NATIVE_TYPEDEFRESULT_HPP