Lua/LuaClass: Add possibility to set up a custom converter
Former-commit-id: 96cf62a16845b5cf44d5724bfd3b9e5b7672ad03
This commit is contained in:
parent
b6ea30f9c1
commit
b331d66c70
|
|
@ -29,14 +29,15 @@ namespace Nz
|
||||||
using ClassFunc = std::function<int(LuaInstance& lua, T& instance)>;
|
using ClassFunc = std::function<int(LuaInstance& lua, T& instance)>;
|
||||||
using ClassIndexFunc = std::function<bool(LuaInstance& lua, T& instance)>;
|
using ClassIndexFunc = std::function<bool(LuaInstance& lua, T& instance)>;
|
||||||
using ConstructorFunc = std::function<T*(LuaInstance& lua)>;
|
using ConstructorFunc = std::function<T*(LuaInstance& lua)>;
|
||||||
|
template<typename P> using ConvertToParent = std::function<P*(T*)>;
|
||||||
using FinalizerFunc = std::function<bool(LuaInstance& lua, T& instance)>;
|
using FinalizerFunc = std::function<bool(LuaInstance& lua, T& instance)>;
|
||||||
using StaticIndexFunc = std::function<bool(LuaInstance& lua)>;
|
using StaticIndexFunc = std::function<bool(LuaInstance& lua)>;
|
||||||
using StaticFunc = std::function<int(LuaInstance& lua)>;
|
using StaticFunc = std::function<int(LuaInstance& lua)>;
|
||||||
|
|
||||||
LuaClass(const String& name);
|
LuaClass(const String& name);
|
||||||
|
|
||||||
template<class P>
|
template<class P> void Inherit(LuaClass<P>& parent);
|
||||||
void Inherit(LuaClass<P>& parent);
|
template<class P> void Inherit(LuaClass<P>& parent, ConvertToParent<P> convertFunc);
|
||||||
|
|
||||||
void Register(LuaInstance& lua);
|
void Register(LuaInstance& lua);
|
||||||
|
|
||||||
|
|
@ -57,7 +58,7 @@ namespace Nz
|
||||||
void SetStaticSetter(StaticIndexFunc getter);
|
void SetStaticSetter(StaticIndexFunc getter);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using ParentFunc = std::function<void(LuaInstance& lua, T& instance)>;
|
using ParentFunc = std::function<void(LuaInstance& lua, T* instance)>;
|
||||||
using InstanceGetter = std::function<T*(LuaInstance& lua)>;
|
using InstanceGetter = std::function<T*(LuaInstance& lua)>;
|
||||||
|
|
||||||
struct ClassInfo
|
struct ClassInfo
|
||||||
|
|
@ -79,7 +80,7 @@ namespace Nz
|
||||||
static int ConstructorProxy(lua_State* state);
|
static int ConstructorProxy(lua_State* state);
|
||||||
static int FinalizerProxy(lua_State* state);
|
static int FinalizerProxy(lua_State* state);
|
||||||
static int InfoDestructor(lua_State* state);
|
static int InfoDestructor(lua_State* state);
|
||||||
static void Get(const std::shared_ptr<ClassInfo>& info, LuaInstance& lua, T& instance);
|
static void Get(const std::shared_ptr<ClassInfo>& info, LuaInstance& lua, T* instance);
|
||||||
static int GetterProxy(lua_State* state);
|
static int GetterProxy(lua_State* state);
|
||||||
static int MethodProxy(lua_State* state);
|
static int MethodProxy(lua_State* state);
|
||||||
static int SetterProxy(lua_State* state);
|
static int SetterProxy(lua_State* state);
|
||||||
|
|
|
||||||
|
|
@ -19,19 +19,29 @@ namespace Nz
|
||||||
template<class T>
|
template<class T>
|
||||||
template<class P>
|
template<class P>
|
||||||
inline void LuaClass<T>::Inherit(LuaClass<P>& parent)
|
inline void LuaClass<T>::Inherit(LuaClass<P>& parent)
|
||||||
|
{
|
||||||
|
Inherit<P>(parent, [] (T* instance) -> P*
|
||||||
|
{
|
||||||
|
return static_cast<P*>(instance);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
template<class P>
|
||||||
|
inline void LuaClass<T>::Inherit(LuaClass<P>& parent, ConvertToParent<P> convertFunc)
|
||||||
{
|
{
|
||||||
static_assert(!std::is_same<P, T>::value || std::is_base_of<P, T>::value, "P must be a base of T");
|
static_assert(!std::is_same<P, T>::value || std::is_base_of<P, T>::value, "P must be a base of T");
|
||||||
|
|
||||||
std::shared_ptr<typename LuaClass<P>::ClassInfo>& parentInfo = parent.m_info;
|
std::shared_ptr<typename LuaClass<P>::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<T**>(lua.CheckUserdata(1, info->name));
|
return convertFunc(*static_cast<T**>(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<P>::Get(parentInfo, lua, instance);
|
LuaClass<P>::Get(parentInfo, lua, convertFunc(instance));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -355,11 +365,11 @@ namespace Nz
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void LuaClass<T>::Get(const std::shared_ptr<ClassInfo>& info, LuaInstance& lua, T& instance)
|
void LuaClass<T>::Get(const std::shared_ptr<ClassInfo>& info, LuaInstance& lua, T* instance)
|
||||||
{
|
{
|
||||||
const ClassIndexFunc& getter = info->getter;
|
const ClassIndexFunc& getter = info->getter;
|
||||||
|
|
||||||
if (!getter || !getter(lua, instance))
|
if (!getter || !getter(lua, *instance))
|
||||||
{
|
{
|
||||||
// Query from the metatable
|
// Query from the metatable
|
||||||
lua.GetMetatable(info->name); //< Metatable
|
lua.GetMetatable(info->name); //< Metatable
|
||||||
|
|
@ -389,7 +399,7 @@ namespace Nz
|
||||||
|
|
||||||
std::shared_ptr<ClassInfo>& info = *static_cast<std::shared_ptr<ClassInfo>*>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
|
std::shared_ptr<ClassInfo>& info = *static_cast<std::shared_ptr<ClassInfo>*>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
|
||||||
|
|
||||||
T& instance = *(*static_cast<T**>(lua.CheckUserdata(1, info->name)));
|
T* instance = *static_cast<T**>(lua.CheckUserdata(1, info->name));
|
||||||
lua.Remove(1); //< Remove the instance from the Lua stack
|
lua.Remove(1); //< Remove the instance from the Lua stack
|
||||||
|
|
||||||
Get(info, lua, instance);
|
Get(info, lua, instance);
|
||||||
|
|
@ -415,9 +425,15 @@ namespace Nz
|
||||||
instance = it->second(lua);
|
instance = it->second(lua);
|
||||||
}
|
}
|
||||||
lua.Pop(2);
|
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<unsigned int>(lua.ToInteger(lua.GetIndexOfUpValue(2)));
|
unsigned int index = static_cast<unsigned int>(lua.ToInteger(lua.GetIndexOfUpValue(2)));
|
||||||
const ClassFunc& method = info->methods[index];
|
const ClassFunc& method = info->methods[index];
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue