From ee2626b928fc0564675581fbae830f686d8d1c0a Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 17 Dec 2015 13:41:13 +0100 Subject: [PATCH] Lua: Optimize binding Former-commit-id: 647a1731f75098b4a8b8f8785e683533931e085a --- include/Nazara/Lua/LuaClass.hpp | 10 +- include/Nazara/Lua/LuaClass.inl | 65 ++++--- include/Nazara/Lua/LuaInstance.hpp | 2 +- include/Nazara/Lua/LuaInstance.inl | 300 +++++++++++++++-------------- 4 files changed, 198 insertions(+), 179 deletions(-) diff --git a/include/Nazara/Lua/LuaClass.hpp b/include/Nazara/Lua/LuaClass.hpp index 7494dbe83..b4aa9d87b 100644 --- a/include/Nazara/Lua/LuaClass.hpp +++ b/include/Nazara/Lua/LuaClass.hpp @@ -46,14 +46,14 @@ namespace Nz void SetFinalizer(FinalizerFunc finalizer); void SetGetter(ClassIndexFunc getter); void SetMethod(const String& name, ClassFunc method); - template std::enable_if_t::value> SetMethod(const String& name, R(P::*func)(Args...), DefArgs... defArgs); - template std::enable_if_t::value> SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs... defArgs); - template std::enable_if_t::type>::value> SetMethod(const String& name, R(P::*func)(Args...), DefArgs... defArgs); - template std::enable_if_t::type>::value> SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs... defArgs); + template std::enable_if_t::value> SetMethod(const String& name, R(P::*func)(Args...), DefArgs&&... defArgs); + template std::enable_if_t::value> SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs&&... defArgs); + template std::enable_if_t::type>::value> SetMethod(const String& name, R(P::*func)(Args...), DefArgs&&... defArgs); + template std::enable_if_t::type>::value> SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs&&... defArgs); void SetSetter(ClassIndexFunc setter); void SetStaticGetter(StaticIndexFunc getter); void SetStaticMethod(const String& name, StaticFunc func); - template void SetStaticMethod(const String& name, R(*func)(Args...), DefArgs... defArgs); + template void SetStaticMethod(const String& name, R(*func)(Args...), DefArgs&&... defArgs); void SetStaticSetter(StaticIndexFunc getter); private: diff --git a/include/Nazara/Lua/LuaClass.inl b/include/Nazara/Lua/LuaClass.inl index 5ca323a79..ea86b6f1a 100644 --- a/include/Nazara/Lua/LuaClass.inl +++ b/include/Nazara/Lua/LuaClass.inl @@ -201,53 +201,57 @@ namespace Nz template template - std::enable_if_t::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...), DefArgs... defArgs) + std::enable_if_t::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...), DefArgs&&... defArgs) { - SetMethod(name, [func, defArgs...] (LuaInstance& instance, T& object) -> int - { - typename LuaImplMethodProxy::template Impl handler(instance, object, defArgs...); - handler.ProcessArgs(); + typename LuaImplMethodProxy::template Impl handler(std::forward(defArgs)...); - return handler.Invoke(func); + SetMethod(name, [func, handler] (LuaInstance& lua, T& object) -> int + { + handler.ProcessArgs(lua); + + return handler.Invoke(lua, object, func); }); } template template - std::enable_if_t::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs... defArgs) + std::enable_if_t::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs&&... defArgs) { - SetMethod(name, [func, defArgs...] (LuaInstance& instance, T& object) -> int - { - typename LuaImplMethodProxy::template Impl handler(instance, object, defArgs...); - handler.ProcessArgs(); + typename LuaImplMethodProxy::template Impl handler(std::forward(defArgs)...); - return handler.Invoke(func); + SetMethod(name, [func, handler] (LuaInstance& lua, T& object) -> int + { + handler.ProcessArgs(lua); + + return handler.Invoke(lua, object, func); }); } template template - std::enable_if_t::type>::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...), DefArgs... defArgs) + std::enable_if_t::type>::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...), DefArgs&&... defArgs) { - SetMethod(name, [func, defArgs...](LuaInstance& instance, T& object) -> int - { - typename LuaImplMethodProxy::template Impl handler(instance, object, defArgs...); - handler.ProcessArgs(); + typename LuaImplMethodProxy::template Impl handler(std::forward(defArgs)...); - return handler.Invoke(func); + SetMethod(name, [func, handler](LuaInstance& lua, T& object) -> int + { + handler.ProcessArgs(lua); + + return handler.Invoke(lua, object, func); }); } template template - std::enable_if_t::type>::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs... defArgs) + std::enable_if_t::type>::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...) const, DefArgs&&... defArgs) { - SetMethod(name, [func, defArgs...](LuaInstance& instance, T& object) -> int - { - typename LuaImplMethodProxy::template Impl handler(instance, object, defArgs...); - handler.ProcessArgs(); + typename LuaImplMethodProxy::template Impl handler(std::forward(defArgs)...); - return handler.Invoke(func); + SetMethod(name, [func, handler](LuaInstance& lua, T& object) -> int + { + handler.ProcessArgs(lua); + + return handler.Invoke(lua, object, func); }); } @@ -271,14 +275,15 @@ namespace Nz template template - void LuaClass::SetStaticMethod(const String& name, R(*func)(Args...), DefArgs... defArgs) + void LuaClass::SetStaticMethod(const String& name, R(*func)(Args...), DefArgs&&... defArgs) { - SetStaticMethod(name, [func, defArgs...] (LuaInstance& instance) -> int - { - typename LuaImplFunctionProxy::template Impl handler(instance); - handler.ProcessArgs(); + typename LuaImplFunctionProxy::template Impl handler(std::forward(defArgs)...); - return handler.Invoke(func); + SetStaticMethod(name, [func, handler] (LuaInstance& lua) -> int + { + handler.ProcessArgs(lua); + + return handler.Invoke(lua, func); }); } diff --git a/include/Nazara/Lua/LuaInstance.hpp b/include/Nazara/Lua/LuaInstance.hpp index 504a79254..9dbb72edf 100644 --- a/include/Nazara/Lua/LuaInstance.hpp +++ b/include/Nazara/Lua/LuaInstance.hpp @@ -116,7 +116,7 @@ namespace Nz void PushBoolean(bool value); void PushCFunction(LuaCFunction func, unsigned int upvalueCount = 0); void PushFunction(LuaFunction func); - template void PushFunction(R(*func)(Args...), DefArgs... defArgs); + template void PushFunction(R(*func)(Args...), DefArgs&&... defArgs); template void PushInstance(const char* tname, T* instance); template void PushInstance(const char* tname, Args&&... args); void PushInteger(long long value); diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index 47712161c..9034e2cc8 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -9,126 +9,121 @@ namespace Nz { // Functions args - inline bool LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) + inline unsigned int LuaImplQueryArg(LuaInstance& instance, int index, bool* arg, TypeTag) { - return instance.CheckBoolean((*index)++); + *arg = instance.CheckBoolean(index); + return 1; } - inline bool LuaImplQueryArg(LuaInstance& instance, unsigned int* index, bool defValue, TypeTag) + inline unsigned int LuaImplQueryArg(LuaInstance& instance, int index, bool* arg, bool defValue, TypeTag) { - return instance.CheckBoolean((*index)++, defValue); - } - - inline double LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) - { - return instance.CheckNumber((*index)++); - } - - inline double LuaImplQueryArg(LuaInstance& instance, unsigned int* index, double defValue, TypeTag) - { - return instance.CheckNumber((*index)++, defValue); - } - - inline float LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) - { - return static_cast(instance.CheckNumber((*index)++)); - } - - inline float LuaImplQueryArg(LuaInstance& instance, unsigned int* index, float defValue, TypeTag) - { - return static_cast(instance.CheckNumber((*index)++, defValue)); + *arg = instance.CheckBoolean(index, defValue); + return 1; } template - std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) - { - return static_cast(LuaImplQueryArg(instance, index, TypeTag::type>())); - } - - template - std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int* index, T defValue, TypeTag) + std::enable_if_t::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, TypeTag) { using UnderlyingT = std::underlying_type_t; - return static_cast(LuaImplQueryArg(instance, index, static_cast(defValue), TypeTag())); + *arg = static_cast(LuaImplQueryArg(instance, index, reinterpret_cast(arg), TypeTag())); + + return 1; } template - std::enable_if_t::value && !std::is_unsigned::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) + std::enable_if_t::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, T defValue, TypeTag) { - return static_cast(instance.CheckInteger((*index)++)); + using UnderlyingT = std::underlying_type_t; + *arg = static_cast(LuaImplQueryArg(instance, index, reinterpret_cast(arg), static_cast(defValue), TypeTag())); + + return 1; } template - std::enable_if_t::value && !std::is_unsigned::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int* index, T defValue, TypeTag) + std::enable_if_t::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, TypeTag) { - return static_cast(instance.CheckInteger((*index)++, defValue)); + *arg = static_cast(instance.CheckNumber(index)); + return 1; } template - std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) + std::enable_if_t::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, T defValue, TypeTag) + { + *arg = static_cast(instance.CheckNumber(index, static_cast(defValue))); + return 1; + } + + template + std::enable_if_t::value && !std::is_unsigned::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, TypeTag) + { + *arg = static_cast(instance.CheckInteger(index)); + return 1; + } + + template + std::enable_if_t::value && !std::is_unsigned::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, T defValue, TypeTag) + { + *arg = static_cast(instance.CheckInteger(index, defValue)); + return 1; + } + + template + std::enable_if_t::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, TypeTag) { using SignedT = std::make_signed_t; - return static_cast(LuaImplQueryArg(instance, index, TypeTag())); + return LuaImplQueryArg(instance, index, reinterpret_cast(arg), TypeTag()); } template - std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int* index, T defValue, TypeTag) + std::enable_if_t::value, unsigned int> LuaImplQueryArg(LuaInstance& instance, int index, T* arg, T defValue, TypeTag) { using SignedT = std::make_signed_t; - return static_cast(LuaImplQueryArg(instance, index, static_cast(defValue), TypeTag())); + + return LuaImplQueryArg(instance, index, reinterpret_cast(arg), static_cast(defValue), TypeTag()); } - inline std::string LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) + inline unsigned int LuaImplQueryArg(LuaInstance& instance, int index, std::string* arg, TypeTag) { std::size_t strLength = 0; - const char* str = instance.CheckString((*index)++, &strLength); + const char* str = instance.CheckString(index, &strLength); - return std::string(str, strLength); + arg->assign(str, strLength); + + return 1; } - inline std::string LuaImplQueryArg(LuaInstance& instance, unsigned int* index, const std::string& defValue, TypeTag) + inline unsigned int LuaImplQueryArg(LuaInstance& instance, int index, String* arg, TypeTag) { std::size_t strLength = 0; - const char* str = instance.CheckString((*index)++, defValue.c_str(), &strLength); + const char* str = instance.CheckString(index, &strLength); - return std::string(str, strLength); - } + arg->Set(str, strLength); - inline String LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) - { - std::size_t strLength = 0; - const char* str = instance.CheckString((*index)++, &strLength); - - return String(str, strLength); - } - - inline String LuaImplQueryArg(LuaInstance& instance, unsigned int* index, const String& defValue, TypeTag) - { - std::size_t strLength = 0; - const char* str = instance.CheckString((*index)++, defValue.GetConstBuffer(), &strLength); - - return String(str, strLength); + return 1; } template - T LuaImplQueryArg(LuaInstance& instance, unsigned int* index, TypeTag) + unsigned int LuaImplQueryArg(LuaInstance& instance, int index, T* arg, const T& defValue, TypeTag tag) { - return LuaImplQueryArg(instance, index, TypeTag()); - } - - template - T LuaImplQueryArg(LuaInstance& instance, unsigned int* index, const T& defValue, TypeTag tag) - { - if (instance.IsValid(*index)) - return LuaImplQueryArg(instance, index, tag); + if (instance.IsValid(index)) + return LuaImplQueryArg(instance, index, arg, tag); else - return defValue; + { + *arg = defValue; + return 1; + } } template - T LuaImplQueryArg(LuaInstance& instance, unsigned int* index, const T& defValue, TypeTag) + unsigned int LuaImplQueryArg(LuaInstance& instance, int index, T* arg, TypeTag) { - return LuaImplQueryArg(instance, index, defValue, TypeTag()); + return LuaImplQueryArg(instance, index, arg, TypeTag()); + } + + template + unsigned int LuaImplQueryArg(LuaInstance& instance, int index, T* arg, const T& defValue, TypeTag) + { + return LuaImplQueryArg(instance, index, arg, defValue, TypeTag()); } // Function returns @@ -203,9 +198,9 @@ namespace Nz struct LuaImplArgProcesser { template - static void Process(LuaInstance& instance, unsigned int* argIndex, ArgContainer& args, DefArgContainer& defArgs) + static unsigned int Process(LuaInstance& instance, unsigned int argIndex, ArgContainer& args, DefArgContainer& defArgs) { - std::get(args) = std::move(LuaImplQueryArg(instance, argIndex, std::get() - N + FirstDefArg - 1>(defArgs), TypeTag())); + return LuaImplQueryArg(instance, argIndex, &std::get(args), std::get() - N + FirstDefArg - 1>(defArgs), TypeTag()); } }; @@ -213,11 +208,11 @@ namespace Nz struct LuaImplArgProcesser { template - static void Process(LuaInstance& instance, unsigned int* argIndex, ArgContainer& args, DefArgContainer& defArgs) + static unsigned int Process(LuaInstance& instance, unsigned int argIndex, ArgContainer& args, DefArgContainer& defArgs) { NazaraUnused(defArgs); - std::get(args) = std::move(LuaImplQueryArg(instance, argIndex, TypeTag())); + return LuaImplQueryArg(instance, argIndex, &std::get(args), TypeTag()); } }; @@ -237,27 +232,28 @@ namespace Nz public: Impl(LuaInstance& instance, DefArgs... defArgs) : - m_defaultArgs(std::forward(defArgs)...), - m_instance(instance) + m_defaultArgs(std::forward(defArgs)...) { } - void ProcessArgs() + void ProcessArgs(LuaInstance& instance) const { m_index = 1; - ProcessArgs<0, Args...>(); + ProcessArgs<0, Args...>(instance); } - int Invoke(void (*func)(Args...)) + int Invoke(LuaInstance& instance, void (*func)(Args...)) const { + NazaraUnused(instance); + Apply(func, m_args); return 0; } template - int Invoke(Ret (*func)(Args...)) + int Invoke(LuaInstance& instance, Ret (*func)(Args...)) const { - return LuaImplReplyVal(m_instance, std::move(Apply(func, m_args)), TypeTag()); + return LuaImplReplyVal(instance, std::move(Apply(func, m_args)), TypeTag()); } private: @@ -265,32 +261,33 @@ namespace Nz using DefArgContainer = std::tuple>...>; template - void ProcessArgs() + void ProcessArgs(LuaInstance& instance) const { + NazaraUnused(instance); + // No argument to process } template - void ProcessArgs() + void ProcessArgs(LuaInstance& instance) const { - LuaImplArgProcesser<(N >= FirstDefArg)>::template Process(m_instance, &m_index, m_args, m_defaultArgs); + LuaImplArgProcesser<(N >= FirstDefArg)>::template Process(instance, &m_index, m_args, m_defaultArgs); } template - void ProcessArgs() + void ProcessArgs(LuaInstance& instance) const { - ProcessArgs(); - ProcessArgs(); + ProcessArgs(instance); + ProcessArgs(instance); } - ArgContainer m_args; + mutable ArgContainer m_args; DefArgContainer m_defaultArgs; - LuaInstance& m_instance; - unsigned int m_index; + mutable unsigned int m_index; }; }; - template + template class LuaImplMethodProxy { public: @@ -305,69 +302,75 @@ namespace Nz static constexpr std::size_t FirstDefArg = ArgCount - DefArgCount; public: - Impl(LuaInstance& instance, T& object, DefArgs... defArgs) : - m_defaultArgs(std::forward(defArgs)...), - m_instance(instance), - m_object(object) + Impl(DefArgs... defArgs) : + m_defaultArgs(std::forward(defArgs)...) { } - void ProcessArgs() + void ProcessArgs(LuaInstance& instance) const { m_index = 1; - ProcessArgs<0, Args...>(); + ProcessArgs<0, Args...>(instance); } - template - std::enable_if_t::value, int> Invoke(void(P::*func)(Args...)) + template + std::enable_if_t::value, int> Invoke(LuaInstance& instance, T& object, void(P::*func)(Args...)) const { - Apply(m_object, func, m_args); + NazaraUnused(instance); + + Apply(object, func, m_args); return 0; } - template - std::enable_if_t::value, int> Invoke(Ret(P::*func)(Args...)) + template + std::enable_if_t::value, int> Invoke(LuaInstance& instance, T& object, Ret(P::*func)(Args...)) const { - return LuaImplReplyVal(m_instance, std::move(Apply(m_object, func, m_args)), TypeTag()); + return LuaImplReplyVal(instance, std::move(Apply(object, func, m_args)), TypeTag()); } - template - std::enable_if_t::value, int> Invoke(void(P::*func)(Args...) const) + template + std::enable_if_t::value, int> Invoke(LuaInstance& instance, const T& object, void(P::*func)(Args...) const) const { - Apply(m_object, func, m_args); + NazaraUnused(instance); + + Apply(object, func, m_args); return 0; } - template - std::enable_if_t::value, int> Invoke(Ret(P::*func)(Args...) const) + template + std::enable_if_t::value, int> Invoke(LuaInstance& instance, const T& object, Ret(P::*func)(Args...) const) const { - return LuaImplReplyVal(m_instance, std::move(Apply(m_object, func, m_args)), TypeTag()); + return LuaImplReplyVal(instance, std::move(Apply(object, func, m_args)), TypeTag()); } - template - std::enable_if_t::type>::value, int> Invoke(void(P::*func)(Args...)) + template + std::enable_if_t::type>::value, int> Invoke(LuaInstance& instance, T& object, void(P::*func)(Args...)) const { - Apply(*m_object, func, m_args); + NazaraUnused(instance); + + Apply(*object, func, m_args); return 0; } - template - std::enable_if_t::type>::value, int> Invoke(Ret(P::*func)(Args...)) + template + std::enable_if_t::type>::value, int> Invoke(LuaInstance& instance, T& object, Ret(P::*func)(Args...)) const { - return LuaImplReplyVal(m_instance, std::move(Apply(*m_object, func, m_args)), TypeTag()); + return LuaImplReplyVal(instance, std::move(Apply(*object, func, m_args)), TypeTag()); } - template - std::enable_if_t::type>::value, int> Invoke(void(P::*func)(Args...) const) + template + std::enable_if_t::type>::value, int> Invoke(LuaInstance& instance, const T& object, void(P::*func)(Args...) const) const { - Apply(*m_object, func, m_args); + NazaraUnused(instance); + + Apply(*object, func, m_args); return 0; } - template - std::enable_if_t::type>::value, int> Invoke(Ret(P::*func)(Args...) const) + template + std::enable_if_t::type>::value, int> Invoke(LuaInstance& instance, const T& object, Ret(P::*func)(Args...) const) const { - return LuaImplReplyVal(m_instance, std::move(Apply(*m_object, func, m_args)), TypeTag()); + return LuaImplReplyVal(instance, std::move(Apply(*object, func, m_args)), TypeTag()); } private: @@ -375,44 +378,54 @@ namespace Nz using DefArgContainer = std::tuple>...>; template - void ProcessArgs() + void ProcessArgs(LuaInstance& instance) const { + NazaraUnused(instance); + // No argument to process } template - void ProcessArgs() + void ProcessArgs(LuaInstance& instance) const { - LuaImplArgProcesser<(N >= FirstDefArg)>::template Process(m_instance, &m_index, m_args, m_defaultArgs); + m_index += LuaImplArgProcesser<(N >= FirstDefArg)>::template Process(instance, m_index, m_args, m_defaultArgs); } template - void ProcessArgs() + void ProcessArgs(LuaInstance& instance) const { - ProcessArgs(); - ProcessArgs(); + ProcessArgs(instance); + ProcessArgs(instance); } - ArgContainer m_args; + mutable ArgContainer m_args; DefArgContainer m_defaultArgs; - LuaInstance& m_instance; - T& m_object; - unsigned int m_index; + mutable unsigned int m_index; }; }; template T LuaInstance::Check(unsigned int* index) { - return LuaImplQueryArg(*this, index, TypeTag()); + NazaraAssert(index, "Invalid index pointer"); + + T object; + *index += LuaImplQueryArg(*this, index, &object, TypeTag()); + + return object; } template T LuaInstance::Check(unsigned int* index, T defValue) { - return LuaImplQueryArg(*this, index, defValue, TypeTag()); - } + NazaraAssert(index, "Invalid index pointer"); + T object; + *index += LuaImplQueryArg(*this, index, &object, defValue, TypeTag()); + + return object; + } + template int LuaInstance::Push(T arg) { @@ -420,14 +433,15 @@ namespace Nz } template - void LuaInstance::PushFunction(R (*func)(Args...), DefArgs... defArgs) + void LuaInstance::PushFunction(R (*func)(Args...), DefArgs&&... defArgs) { - PushFunction([func, defArgs...](LuaInstance& instance) -> int - { - typename LuaImplFunctionProxy::template Impl handler(instance, defArgs...); - handler.ProcessArgs(); + typename LuaImplFunctionProxy::template Impl handler(std::forward(defArgs)...); - return handler.Invoke(func); + PushFunction([func, handler](LuaInstance& lua) -> int + { + handler.ProcessArgs(lua); + + return handler.Invoke(lua, func); }); }