14 void Register(lua_State* L);
16 static void RegisterTypes(lua_State* L);
18 [[nodiscard]]
auto IsDerivedClass()
const ->
bool
20 return GetClassName() != GetBaseClassName();
22 [[nodiscard]]
virtual auto GetClassName()
const ->
const std::string& = 0;
23 [[nodiscard]]
virtual auto GetBaseClassName()
const
24 ->
const std::string& = 0;
26 static void ApplyDerivedType(Lua* L,
27 const std::string& sClassname,
29 static auto CheckLuaObjectType(lua_State* L,
31 std::string
const& szType) -> bool;
34 virtual void Register(Lua* L,
int iMethods,
int iMetatable) = 0;
36 static void CreateMethodsTable(lua_State* L,
const std::string& szName);
37 static auto GetPointerFromStack(Lua* L,
const std::string& sType,
int iArg)
40 static auto Equal(lua_State* L) -> bool;
41 static auto PushEqual(lua_State* L) -> int;
50 using binding_t = int(T*, lua_State*);
58 void Register(Lua* L,
int iMethods,
int iMetatable)
override
60 lua_pushcfunction(L, tostring_T);
61 lua_setfield(L, iMetatable,
"__tostring");
64 for (
auto const& m : m_aMethods) {
65 lua_pushlightuserdata(L,
reinterpret_cast<void*
>(m.mfunc));
66 lua_pushcclosure(L, thunk, 1);
67 lua_setfield(L, iMethods, m.regName.c_str());
72 [[nodiscard]]
auto GetClassName() const -> const std::
string&
override
76 [[nodiscard]]
auto GetBaseClassName() const -> const std::
string&
override
78 return m_sBaseClassName;
80 static std::string m_sClassName;
81 static std::string m_sBaseClassName;
84 static auto check(lua_State* L,
int narg,
bool bIsSelf =
false) -> T*
86 if (!LuaBinding::CheckLuaObjectType(L, narg, m_sClassName)) {
88 luaL_typerror(L, narg, m_sClassName.c_str());
90 LuaHelpers::TypeError(L, narg, m_sClassName);
96 static auto get(lua_State* L,
int narg) -> T*
98 return reinterpret_cast<T*
>(GetPointerFromStack(L, m_sClassName, narg));
103 static void PushObject(Lua* L,
const std::string& sDerivedClassName, T* p);
106 void AddMethod(std::string
const& regName,
int (*pFunc)(T* p, lua_State* L))
108 RegType r = { regName, pFunc };
109 m_aMethods.push_back(r);
114 static auto thunk(Lua* L) ->
int
117 T* obj = check(L, 1,
true);
121 auto* pFunc =
reinterpret_cast<binding_t*
>(lua_touserdata(L, lua_upvalueindex(1)));
122 return pFunc(obj, L);
125 std::vector<RegType> m_aMethods;
127 static auto tostring_T(lua_State* L) ->
int
130 const void* pData = check(L, 1);
131 snprintf(buff,
sizeof(buff),
"%p", pData);
132 lua_pushfstring(L,
"%s (%s)", m_sClassName.c_str(), buff);