132 lines
4.8 KiB
C++
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
|