diff --git a/include/Nazara/Lua/LuaClass.hpp b/include/Nazara/Lua/LuaClass.hpp index 130ac2904..eb4cb51e3 100644 --- a/include/Nazara/Lua/LuaClass.hpp +++ b/include/Nazara/Lua/LuaClass.hpp @@ -29,14 +29,15 @@ namespace Nz using ClassFunc = std::function; using ClassIndexFunc = std::function; using ConstructorFunc = std::function; + template using ConvertToParent = std::function; using FinalizerFunc = std::function; using StaticIndexFunc = std::function; using StaticFunc = std::function; LuaClass(const String& name); - template - void Inherit(LuaClass

& parent); + template void Inherit(LuaClass

& parent); + template void Inherit(LuaClass

& parent, ConvertToParent

convertFunc); void Register(LuaInstance& lua); @@ -57,7 +58,7 @@ namespace Nz void SetStaticSetter(StaticIndexFunc getter); private: - using ParentFunc = std::function; + using ParentFunc = std::function; using InstanceGetter = std::function; struct ClassInfo @@ -79,7 +80,7 @@ namespace Nz static int ConstructorProxy(lua_State* state); static int FinalizerProxy(lua_State* state); static int InfoDestructor(lua_State* state); - static void Get(const std::shared_ptr& info, LuaInstance& lua, T& instance); + static void Get(const std::shared_ptr& info, LuaInstance& lua, T* instance); static int GetterProxy(lua_State* state); static int MethodProxy(lua_State* state); static int SetterProxy(lua_State* state); diff --git a/include/Nazara/Lua/LuaClass.inl b/include/Nazara/Lua/LuaClass.inl index 393225399..ffcc4b0d8 100644 --- a/include/Nazara/Lua/LuaClass.inl +++ b/include/Nazara/Lua/LuaClass.inl @@ -19,19 +19,29 @@ namespace Nz template template inline void LuaClass::Inherit(LuaClass

& parent) + { + Inherit

(parent, [] (T* instance) -> P* + { + return static_cast(instance); + }); + } + + template + template + inline void LuaClass::Inherit(LuaClass

& parent, ConvertToParent

convertFunc) { static_assert(!std::is_same::value || std::is_base_of::value, "P must be a base of T"); std::shared_ptr::ClassInfo>& parentInfo = parent.m_info; - - parentInfo->instanceGetters[m_info->name] = [info = m_info](LuaInstance& lua) -> P* + + parentInfo->instanceGetters[m_info->name] = [info = m_info, convertFunc] (LuaInstance& lua) -> P* { - return *static_cast(lua.CheckUserdata(1, info->name)); + return convertFunc(*static_cast(lua.CheckUserdata(1, info->name))); }; - m_info->parentGetters.emplace_back([parentInfo] (LuaInstance& lua, T& instance) + m_info->parentGetters.emplace_back([parentInfo, convertFunc] (LuaInstance& lua, T* instance) { - LuaClass

::Get(parentInfo, lua, instance); + LuaClass

::Get(parentInfo, lua, convertFunc(instance)); }); } @@ -112,7 +122,7 @@ namespace Nz lua.SetField(pair.first); // Method name } - m_info->instanceGetters[m_info->name] = [info = m_info](LuaInstance& lua) + m_info->instanceGetters[m_info->name] = [info = m_info] (LuaInstance& lua) { return *static_cast(lua.CheckUserdata(1, info->name)); }; @@ -242,7 +252,7 @@ namespace Nz { typename LuaImplMethodProxy::template Impl handler(std::forward(defArgs)...); - SetMethod(name, [func, handler](LuaInstance& lua, T& object) -> int + SetMethod(name, [func, handler] (LuaInstance& lua, T& object) -> int { handler.ProcessArgs(lua); @@ -256,7 +266,7 @@ namespace Nz { typename LuaImplMethodProxy::template Impl handler(std::forward(defArgs)...); - SetMethod(name, [func, handler](LuaInstance& lua, T& object) -> int + SetMethod(name, [func, handler] (LuaInstance& lua, T& object) -> int { handler.ProcessArgs(lua); @@ -355,11 +365,11 @@ namespace Nz } template - void LuaClass::Get(const std::shared_ptr& info, LuaInstance& lua, T& instance) + void LuaClass::Get(const std::shared_ptr& info, LuaInstance& lua, T* instance) { const ClassIndexFunc& getter = info->getter; - if (!getter || !getter(lua, instance)) + if (!getter || !getter(lua, *instance)) { // Query from the metatable lua.GetMetatable(info->name); //< Metatable @@ -389,7 +399,7 @@ namespace Nz std::shared_ptr& info = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - T& instance = *(*static_cast(lua.CheckUserdata(1, info->name))); + T* instance = *static_cast(lua.CheckUserdata(1, info->name)); lua.Remove(1); //< Remove the instance from the Lua stack Get(info, lua, instance); @@ -415,9 +425,15 @@ namespace Nz instance = it->second(lua); } lua.Pop(2); + + lua.Remove(1); //< Remove the instance from the Lua stack } - lua.Remove(1); //< Remove the instance from the Lua stack + if (!instance) + { + lua.Error("Method cannot be called without an object"); + return 0; + } unsigned int index = static_cast(lua.ToInteger(lua.GetIndexOfUpValue(2))); const ClassFunc& method = info->methods[index];