PkmnLib/src/ScriptResolving/AngelScript/TypeRegistry/HelperFile.hpp

95 lines
8.2 KiB
C++

#ifndef PKMNLIB_HELPERFILE_HPP
#define PKMNLIB_HELPERFILE_HPP
#include "NativeArray.hpp"
#define BORROWED_PTR_GETTER_FUNC(o, returns, funcName) \
static returns* funcName##Wrapper(o* obj) { return obj->funcName().GetRaw(); }
#define OPTIONAL_BORROWED_PTR_GETTER_FUNC(o, returns, funcName) \
static returns* funcName##Wrapper(o* obj) { return obj->funcName().GetValue(); }
#define UNIQUE_PTR_GETTER_FUNC(o, returns, funcName) \
static returns* funcName##Wrapper(o* obj) { return obj->funcName().get(); }
#define REGISTER_ENUM(enumName, asName) \
{ \
auto __r = engine->RegisterEnum(asName); \
Ensure(__r >= 0); \
for (auto val : enumName##Helper::GetValues()) { \
__r = engine->RegisterEnumValue(asName, enumName##Helper::ToString(val).c_str(), (i32)val); \
Ensure(__r >= 0); \
} \
}
// Hack to handle AngelScript not recognizing different sized enums on fields, and returning invalid values due to it.
#define ENUM__SIZE_WRAPPER(name, type, func) \
int32_t name(type* obj) { return static_cast<int32_t>(obj->func()); }
template <typename Test, template <typename...> class Ref> struct is_specialization : std::false_type {};
template <template <typename...> class Ref, typename... Args>
struct is_specialization<Ref<Args...>, Ref> : std::true_type {};
template <template <typename...> class Ref, typename... Args>
struct is_specialization<const Ref<Args...>&, Ref> : std::true_type {};
template <template <typename...> class Ref, typename... Args>
struct is_specialization<Ref<Args...>&, Ref> : std::true_type {};
#define __GETTER \
if constexpr (std::is_enum<R>()) { \
auto l = [](T* p) { return (i32)(p->*Method)(); }; \
Ensure(engine->RegisterObjectMethod(asType, asDef, asFUNCTIONPR(l, (T*), i32), asCALL_CDECL_OBJFIRST) >= 0); \
} else if constexpr (is_specialization<R, ArbUt::BorrowedPtr>::value) { \
auto l = [](T* p) { return (void*)(p->*Method)().GetRaw(); }; \
Ensure(engine->RegisterObjectMethod(asType, asDef, asFUNCTIONPR(l, (T*), void*), asCALL_CDECL_OBJFIRST) >= 0); \
} else if constexpr (is_specialization<R, std::unique_ptr>::value) { \
auto l = [](T* p) { return (void*)(p->*Method)().get(); }; \
Ensure(engine->RegisterObjectMethod(asType, asDef, asFUNCTIONPR(l, (T*), void*), asCALL_CDECL_OBJFIRST) >= 0); \
} else if constexpr (is_specialization<R, ArbUt::OptionalBorrowedPtr>::value) { \
auto l = [](T* p) { \
auto v = (p->*Method)(); \
if (v.HasValue()) { \
return (void*)v.GetValue(); \
} \
return (void*)nullptr; \
}; \
Ensure(engine->RegisterObjectMethod(asType, asDef, asFUNCTIONPR(l, (T*), void*), asCALL_CDECL_OBJFIRST) >= 0); \
} else if constexpr (is_specialization<R, ArbUt::List>::value) { \
using base_type = typename std::remove_cv<typename std::remove_reference<R>::type>::type; \
auto l = [](T* p) { return (void*)new NativeArray<base_type>(&((p->*Method)())); }; \
Ensure(engine->RegisterObjectMethod(asType, asDef, asFUNCTIONPR(l, (T*), void*), asCALL_CDECL_OBJFIRST) >= 0); \
} else if constexpr (is_specialization<R, ArbUt::UniquePtrList>::value) { \
using base_type = typename std::remove_cv<typename std::remove_reference<R>::type>::type; \
auto l = [](T* p) { return (void*)new NativeArray<base_type>(&((p->*Method)())); }; \
Ensure(engine->RegisterObjectMethod(asType, asDef, asFUNCTIONPR(l, (T*), void*), asCALL_CDECL_OBJFIRST) >= 0); \
} else if constexpr (is_specialization<R, ArbUt::OptionalUniquePtrList>::value) { \
using base_type = typename std::remove_cv<typename std::remove_reference<R>::type>::type; \
auto l = [](T* p) { return (void*)new NativeArray<base_type>(&((p->*Method)())); }; \
Ensure(engine->RegisterObjectMethod(asType, asDef, asFUNCTIONPR(l, (T*), void*), asCALL_CDECL_OBJFIRST) >= 0); \
} else if constexpr (std::is_reference<R>::value) { \
static_assert(!std::is_enum<R>()); \
static_assert(!is_specialization<R, ArbUt::List>::value); \
static_assert(!is_specialization<R, ArbUt::UniquePtrList>::value); \
auto l = [](T* p) { return (void*)&(p->*Method)(); }; \
Ensure(engine->RegisterObjectMethod(asType, asDef, asFUNCTIONPR(l, (T*), void*), asCALL_CDECL_OBJFIRST) >= 0); \
} else { \
static_assert(!std::is_enum<R>()); \
static_assert(!is_specialization<R, ArbUt::List>::value); \
static_assert(!is_specialization<R, ArbUt::UniquePtrList>::value); \
auto l = [](T* p) { return (p->*Method)(); }; \
Ensure(engine->RegisterObjectMethod(asType, asDef, asFUNCTIONPR(l, (T*), R), asCALL_CDECL_OBJFIRST) >= 0); \
}
template <typename T, typename R, R (T::*Method)() const>
void RegisterGetter(asIScriptEngine* engine, const char* asType, const char* asDef) {
__GETTER
}
template <typename T, typename R, R (T::*Method)()>
void RegisterGetter(asIScriptEngine* engine, const char* asType, const char* asDef) {
__GETTER
}
#define REGISTER_GETTER(asType, asDef, cType, cFunc) \
RegisterGetter<cType, decltype(std::declval<cType>().cFunc()), &cType::cFunc>(engine, asType, asDef);
#define REGISTER_EXPLICIT_GETTER(asType, asDef, cType, cFunc, returnType) \
RegisterGetter<cType, returnType, &cType::cFunc>(engine, asType, asDef);
#endif