// // Lol Engine — base class for Lua script loading // // Copyright © 2009—2015 Sam Hocevar // © 2009—2015 Benjamin “Touky” Huet // // Lol Engine is free software. It comes without any warranty, to // the extent permitted by applicable law. You can redistribute it // and/or modify it under the terms of the Do What the Fuck You Want // to Public License, Version 2, as published by the WTFPL Task Force. // See http://www.wtfpl.net/ for more details. // #include "lua/lua.hpp" //#include "lua/luawrapper.hpp" #pragma once namespace lol { typedef lua_State LuaState; //----------------------------------------------------------------------------- namespace Lolua { //----------------------------------------------------------------------------- typedef luaL_Reg ClassMethod; typedef struct ClassVar { const char *name; lua_CFunction get; lua_CFunction set; } ClassVar; //----------------------------------------------------------------------------- struct ObjectLib { typedef struct ClassVarStr { ClassVarStr() { } ClassVarStr(String var_name, lua_CFunction get, lua_CFunction set) { m_get_name = String("Get") + var_name; m_set_name = String("Set") + var_name; m_get = get; m_set = set; } String m_get_name = ""; String m_set_name = ""; lua_CFunction m_get = nullptr; lua_CFunction m_set = nullptr; } ClassVarStr; ObjectLib(String class_name, array const& statics, array const& methods, array const& variables) { m_class_name = class_name; m_static_name = class_name + "_lib"; m_method_name = class_name + "_inst"; m_statics = statics; if (m_statics.count() == 0 || m_statics.last().name != nullptr || m_statics.last().func != nullptr) m_statics.push({ nullptr, nullptr }); m_methods = methods; if (m_methods.count() == 0 || m_methods.last().name != nullptr || m_methods.last().func != nullptr) m_methods.push({ nullptr, nullptr }); for (ClassVar const& cv : variables) { if (cv.name && cv.get && cv.set) { m_variables.push({ cv.name, cv.get, cv.set }); } } if (m_variables.count() == 0 || variables.last().name != nullptr || variables.last().get != nullptr || variables.last().set != nullptr) m_variables.push(ClassVarStr()); } String m_class_name = ""; String m_static_name = ""; String m_method_name = ""; array m_statics; array m_methods; array m_variables; }; //----------------------------------------------------------------------------- class Object { public: Object() { } virtual ~Object() { } static Object* New(LuaState* l, int arg_nb) { UNUSED(l); UNUSED(arg_nb); ASSERT(false); return nullptr; } static const ObjectLib* GetLib() { ASSERT(false); return nullptr; } }; //----------------------------------------------------------------------------- // Class available to link C++ class to Lua methods //-- class ObjectDef { public: //------------------------------------------------------------------------- ObjectDef() { } virtual ~ObjectDef() { } //------------------------------------------------------------------------- template static void Register(LuaState *l) { //Default statics static const luaL_Reg default_statics[] { { "New", New }, { "Store", Store }, { "__gc", Del }, { NULL, NULL } }; //TODO: Touky: Implement that //__tostring : ToString //__add : Addition(+) //__sub : Subtraction(-) //__mul : Multiplication(*) //__div : Division(/ ) //__mod : Modulos(%) //__unm : Unary - , used for negation on numbers //__concat : Concatenation(..) //__eq : Equality(== ) //__lt : Less than(<) //__le : Less than or equal to(<= ) //Create Static metatable luaL_newmetatable(l, GetStaticName()); //Register default statics and template one luaL_setfuncs(l, default_statics, 0); luaL_setfuncs(l, GetStaticMethods(), 0); //Push metatable on stack lua_pushvalue(l, -1); //Set the "__index" field of the metatable to point to itself, pops the stack lua_setfield(l, -1, "__index"); //Set it global to validate the operation lua_setglobal(l, GetObjectName()); //Repeat all the operations for instance metatable luaL_newmetatable(l, GetMethodName()); luaL_setfuncs(l, GetInstanceMethods(), 0); lua_pushvalue(l, -1); lua_setfield(l, -1, "__index"); //Create variables Get/Set const array& variables = GetVariables(); for (const ObjectLib::ClassVarStr& var : variables) { if (!var.m_get || !var.m_set) continue; //Add getter lua_pushcfunction(l, var.m_get); lua_setfield(l, -2, var.m_get_name.C()); //Add setter lua_pushcfunction(l, var.m_set); lua_setfield(l, -2, var.m_set_name.C()); } //Don't set it to global, but pop the stack to hide the metatable lua_pop(l, 1); } private: template static const ObjectLib* GetLib() { const ObjectLib* lib = TLuaClass::GetLib(); ASSERT(lib); return lib; } public: template static const char* GetObjectName() { return GetLib()->m_class_name.C(); } template static const char* GetStaticName() { return GetLib()->m_static_name.C(); } template static const char* GetMethodName() { return GetLib()->m_method_name.C(); } template static const ClassMethod* GetStaticMethods() { return GetLib()->m_statics.data(); } template static const ClassMethod* GetInstanceMethods() { return GetLib()->m_methods.data(); } template static const array& GetVariables() { return GetLib()->m_variables; } protected: //------------------------------------------------------------------------- template static int New(LuaState* l) { //Number of arguments int n_args = lua_gettop(l); //Create user data TLuaClass** data = (TLuaClass**)lua_newuserdata(l, sizeof(TLuaClass*)); *data = TLuaClass::New(l, n_args); //Retrieve instance table luaL_getmetatable(l, GetMethodName()); //Set metatable to instance lua_setmetatable(l, -2); //Return 1 so Lua will get the UserData and clean the stack. return 1; } //------------------------------------------------------------------------- template static int Store(LuaState * l); template static int Del(LuaState * l); }; //----------------------------------------------------------------------------- class Function { public: Function(LuaState* l, const char* name, int(*function)(LuaState*)) { lua_pushcfunction(l, function); lua_setglobal(l, name); } }; //----------------------------------------------------------------------------- template class VarPtr { protected: T* m_value = nullptr; bool m_optional = false; public: VarPtr(bool optional = false) { m_optional = optional; } VarPtr(T* value, bool optional = false) : VarPtr(optional) { m_value = value; } VarPtr(LuaState* l, int& index, bool optional = false) : VarPtr(optional) { GetInc(l, index); } VarPtr(T* value, LuaState* l, int& index, bool optional = false) : VarPtr(value, optional) { GetInc(l, index); } inline T* operator ()() { return m_value; } inline T* operator ->() { return m_value; } inline T* operator=(T* value) { m_value = value; } inline T* GetValue() { return m_value; } inline bool IsValid(LuaState* l, int index) { return InnerIsValid(l, index); } inline bool IsOptional() { return m_optional; } private: inline void GetInc(LuaState* l, int& index) { bool is_nil = lua_isnil(l, index); if (!m_optional || (!is_nil && InnerIsValid(l, index))) { ASSERT(!is_nil); InnerGet(l, index); } } public: inline void Get(LuaState* l, int index) { int idx = index; GetInc(l, idx); } inline int Return(LuaState* l) { InnerPush(l); return 1; } protected: virtual bool InnerIsValid(LuaState* l, int index) { return !!lua_isuserdata(l, index); } virtual void InnerGet(LuaState* l, int& index) { T** obj = static_cast(luaL_checkudata(l, index++, ObjectDef::GetMethodName())); m_value = obj ? *obj : nullptr; } void InnerPush(LuaState* l) { T** data = (T**)lua_newuserdata(l, sizeof(T*)); *data = m_value; } }; //----------------------------------------------------------------------------- /* TODO: FIX THAT TOUKY !! template class VarPtrLight { public: VarPtrLight(bool optional = false) : VarPtr(optional) { } VarPtrLight(T* value, bool optional = false) : VarPtr(value, optional) { } VarPtrLight(LuaState* l, int& index, bool optional = false) : VarPtr(l, index, optional) { } VarPtrLight(T* value, LuaState* l, int& index, bool optional = false) : VarPtr(value, l, index, optional) { } protected: virtual void InnerGet(LuaState* l, int& index) { T** obj = static_cast(luaL_testudata(l, index++, ObjectDef::GetMethodName())); m_value = obj ? *obj : nullptr; } }; */ //----------------------------------------------------------------------------- template class Var { protected: bool m_optional = false; T m_value; public: Var(bool optional = false) { m_optional = optional; InnerInit(); } Var(T value, bool optional = false) { m_optional = optional; m_value = value; } Var(LuaState* l, int& index, bool optional = false) { m_optional = optional; GetInc(l, index); } Var(T value, LuaState* l, int& index, bool optional = false) { m_optional = optional; m_value = value; GetInc(l, index); } inline operator T() { return m_value; } inline T& operator ()() { return m_value; } inline T& GetValue() { return m_value; } inline bool IsValid(LuaState* l, int index) { return InnerIsValid(l, index); } inline bool IsOptional() { return m_optional; } private: void GetInc(LuaState* l, int& index) { bool is_nil = lua_isnil(l, index); if (!m_optional || (!is_nil && InnerIsValid(l, index))) { ASSERT(!is_nil); InnerGet(l, index); } } public: inline void Get(LuaState* l, int index) { int idx = index; GetInc(l, idx); } inline int Return(LuaState* l) { return InnerPush(l); } inline Var& operator-(const T& value) { m_value - value; return *this; } inline Var& operator+(const T& value) { m_value + value; return *this; } inline Var& operator*(const T& value) { m_value * value; return *this; } inline Var& operator/(const T& value) { m_value / value; return *this; } inline Var& operator=(const T& value) { m_value = value; return *this; } inline Var& operator-=(const T& value) { m_value -= value; return *this; } inline Var& operator+=(const T& value) { m_value += value; return *this; } inline Var& operator*=(const T& value) { m_value *= value; return *this; } inline Var& operator/=(const T& value) { m_value /= value; return *this; } inline Var& operator-(const Var& o) { m_value - o.m_value; return *this; } inline Var& operator+(const Var& o) { m_value + o.m_value; return *this; } inline Var& operator*(const Var& o) { m_value * o.m_value; return *this; } inline Var& operator/(const Var& o) { m_value / o.m_value; return *this; } inline Var& operator=(const Var& o) { m_value = o.m_value; return *this; } inline Var& operator-=(const Var& o) { m_value -= o.m_value; return *this; } inline Var& operator+=(const Var& o) { m_value += o.m_value; return *this; } inline Var& operator*=(const Var& o) { m_value *= o.m_value; return *this; } inline Var& operator/=(const Var& o) { m_value /= o.m_value; return *this; } inline bool operator==(const T& value) { return m_value == value; } inline bool operator!=(const T& value) { return m_value != value; } inline bool operator==(const Var& o) { return m_value == o.m_value; } inline bool operator!=(const Var& o) { return m_value != o.m_value; } protected: void InnerInit() { m_value = T(0); } bool InnerIsValid(LuaState* l, int index) { UNUSED(l); UNUSED(index); ASSERT(false); return false; } void InnerGet(LuaState* l, int& index) { UNUSED(l); UNUSED(index); ASSERT(false); } int InnerPush(LuaState* l) { UNUSED(l); ASSERT(false); return 0; } }; //----------------------------------------------------------------------------- template<> inline bool Var::InnerIsValid(LuaState* l, int index) { return lua_isboolean(l, index); } template<> inline void Var::InnerGet(LuaState* l, int& index) { m_value = !!lua_toboolean(l, index++); } template<> inline int Var::InnerPush(LuaState* l) { lua_pushboolean(l, m_value); return 1; } //----------------------------------------------------------------------------- template<> inline bool Var::InnerIsValid(LuaState* l, int index) { return !!lua_isstring(l, index); } template<> inline void Var::InnerGet(LuaState* l, int& index) { m_value = lua_tostring(l, index++); } template<> inline int Var::InnerPush(LuaState* l) { lua_pushstring(l, m_value); return 1; } //----------------------------------------------------------------------------- template<> inline void Var::InnerInit() { m_value = String(); } template<> inline bool Var::InnerIsValid(LuaState* l, int index) { Var v; return v.IsValid(l, index); } template<> inline void Var::InnerGet(LuaState* l, int& index) { Var v(l, index); m_value = v(); } template<> inline int Var::InnerPush(LuaState* l) { Var v; v = m_value.C(); return v.Return(l); } //----------------------------------------------------------------------------- template<> inline bool Var::InnerIsValid(LuaState* l, int index) { return !!lua_isnumber(l, index); } template<> inline void Var::InnerGet(LuaState* l, int& index) { m_value = lua_tonumber(l, index++); } template<> inline int Var::InnerPush(LuaState* l) { lua_pushnumber(l, m_value); return 1; } //----------------------------------------------------------------------------- template<> inline bool Var::InnerIsValid(LuaState* l, int index) { Var v; return v.IsValid(l, index); } template<> inline void Var::InnerGet(LuaState* l, int& index) { Var v(l, index); m_value = (float)v(); } template<> inline int Var::InnerPush(LuaState* l) { Var v = (double)m_value; return v.Return(l); } #if 0 //----------------------------------------------------------------------------- template<> inline bool Var::InnerIsValid(LuaState* l, int index) { return !!lua_isnumber(l, index); } template<> inline void Var::InnerGet(LuaState* l, int& index) { m_value = lua_tointeger(l, index++); } template<> inline int Var::InnerPush(LuaState* l) { lua_pushinteger(l, m_value); return 1; } #endif //----------------------------------------------------------------------------- template<> inline bool Var::InnerIsValid(LuaState* l, int index) { Var v; return v.IsValid(l, index); } template<> inline void Var::InnerGet(LuaState* l, int& index) { Var v(l, index); m_value = (int32_t)v(); } template<> inline int Var::InnerPush(LuaState* l) { Var v = (int64_t)m_value; return v.Return(l); } //----------------------------------------------------------------------------- template<> inline bool Var::InnerIsValid(LuaState* l, int index) { return !!lua_isnumber(l, index); } template<> inline void Var::InnerGet(LuaState* l, int& index) { m_value = (uint32_t)(lua_Unsigned)lua_tointeger(l, index++); } template<> inline int Var::InnerPush(LuaState* l) { lua_pushinteger(l, (lua_Integer)m_value); return 1; } #if 0 //----------------------------------------------------------------------------- template<> inline bool Var::InnerIsValid(LuaState* l, int index) { Var v; return v.IsValid(l, index); } template<> inline void Var::InnerGet(LuaState* l, int& index) { Var v(l, index); m_value = (uint64_t)v(); } template<> inline int Var::InnerPush(LuaState* l) { Var v = (uint32_t)m_value; return v.Return(l); } #endif //----------------------------------------------------------------------------- template<> inline bool Var::InnerIsValid(LuaState* l, int index) { Var x; return x.IsValid(l, index); } template<> inline void Var::InnerGet(LuaState* l, int& index) { Var x(l, index); Var y(x(), l, index, true); m_value = vec2(x, y); } template<> inline int Var::InnerPush(LuaState* l) { Var x = m_value.x; Var y = m_value.y; return (x.Return(l) + y.Return(l)); } //----------------------------------------------------------------------------- template<> inline bool Var::InnerIsValid(LuaState* l, int index) { Var x; return x.IsValid(l, index); } template<> inline void Var::InnerGet(LuaState* l, int& index) { Var x(l, index); Var y(x(), l, index, true); Var z(x(), l, index, true); m_value = vec3(x, y, z); } template<> inline int Var::InnerPush(LuaState* l) { Var x = m_value.x; Var y = m_value.y; Var z = m_value.z; return (x.Return(l) + y.Return(l) + z.Return(l)); } //----------------------------------------------------------------------------- template<> inline bool Var::InnerIsValid(LuaState* l, int index) { Var x; return x.IsValid(l, index); } template<> inline void Var::InnerGet(LuaState* l, int& index) { Var x(l, index); Var y(x(), l, index, true); Var z(x(), l, index, true); Var w(x(), l, index, true); m_value = vec4(x, y, z, w); } template<> inline int Var::InnerPush(LuaState* l) { Var x = m_value.x; Var y = m_value.y; Var z = m_value.z; Var w = m_value.w; return (x.Return(l) + y.Return(l) + z.Return(l) + w.Return(l)); } //----------------------------------------------------------------------------- class VarColor { protected: Var m_value; public: VarColor(bool optional = false) { m_value = Var(optional); InnerInit(); } VarColor(vec4 value, bool optional = false) { m_value = Var(value, optional); } VarColor(LuaState* l, int& index, bool optional = false) : VarColor(optional) { GetInc(l, index); } VarColor(vec4 value, LuaState* l, int& index, bool optional = false) : VarColor(value, optional) { GetInc(l, index); } inline operator vec4() { return m_value; } inline vec4& operator ()() { return m_value(); } inline vec4& GetValue() { return m_value.GetValue(); } inline bool IsValid(LuaState* l, int index) { return InnerIsValid(l, index); } inline bool IsOptional() { return m_value.IsOptional(); } private: void GetInc(LuaState* l, int& index) { bool is_nil = lua_isnil(l, index); if (!m_value.IsOptional() || (!is_nil && InnerIsValid(l, index))) { ASSERT(!is_nil); InnerGet(l, index); } } public: inline void Get(LuaState* l, int index) { int idx = index; GetInc(l, idx); } inline int Return(LuaState* l) { return InnerPush(l); } inline VarColor& operator-(const vec4& value) { m_value - value; return *this; } inline VarColor& operator+(const vec4& value) { m_value + value; return *this; } inline VarColor& operator*(const vec4& value) { m_value * value; return *this; } inline VarColor& operator/(const vec4& value) { m_value / value; return *this; } inline VarColor& operator=(const vec4& value) { m_value = value; return *this; } inline VarColor& operator-=(const vec4& value) { m_value -= value; return *this; } inline VarColor& operator+=(const vec4& value) { m_value += value; return *this; } inline VarColor& operator*=(const vec4& value) { m_value *= value; return *this; } inline VarColor& operator/=(const vec4& value) { m_value /= value; return *this; } inline VarColor& operator-(const Var& o) { m_value - o; return *this; } inline VarColor& operator+(const Var& o) { m_value + o; return *this; } inline VarColor& operator*(const Var& o) { m_value * o; return *this; } inline VarColor& operator/(const Var& o) { m_value / o; return *this; } inline VarColor& operator=(const Var& o) { m_value = o; return *this; } inline VarColor& operator-=(const Var& o) { m_value -= o; return *this; } inline VarColor& operator+=(const Var& o) { m_value += o; return *this; } inline VarColor& operator*=(const Var& o) { m_value *= o; return *this; } inline VarColor& operator/=(const Var& o) { m_value /= o; return *this; } inline bool operator==(const vec4& value) { return m_value == value; } inline bool operator!=(const vec4& value) { return m_value != value; } inline bool operator==(const Var& o) { return m_value == o; } inline bool operator!=(const Var& o) { return m_value != o; } inline VarColor& operator-(const VarColor& v) { m_value - v.m_value; return *this; } inline VarColor& operator+(const VarColor& v) { m_value + v.m_value; return *this; } inline VarColor& operator*(const VarColor& v) { m_value * v.m_value; return *this; } inline VarColor& operator/(const VarColor& v) { m_value / v.m_value; return *this; } inline VarColor& operator=(const VarColor& v) { m_value = v.m_value; return *this; } inline VarColor& operator-=(const VarColor& v) { m_value -= v.m_value; return *this; } inline VarColor& operator+=(const VarColor& v) { m_value += v.m_value; return *this; } inline VarColor& operator*=(const VarColor& v) { m_value *= v.m_value; return *this; } inline VarColor& operator/=(const VarColor& v) { m_value /= v.m_value; return *this; } inline bool operator==(const VarColor& v) { return m_value == v.m_value; } inline bool operator!=(const VarColor& v) { return m_value != v.m_value; } protected: void InnerInit() { m_value = vec4::zero; } bool InnerIsValid(LuaState* l, int index) { Var s; return m_value.IsValid(l, index) || s.IsValid(l, index); } void InnerGet(LuaState* l, int& index) { //Try vec4 first if (m_value.IsValid(l, index)) { m_value.Get(l, index); } else { Var c(l, index); *this = Color::C8BppHexString(c); } } int InnerPush(LuaState* l) { Var c = Color::HexString8Bpp(m_value); return c.Return(l); } }; //----------------------------------------------------------------------------- template class VarEnum { protected: SafeEnum m_value; bool m_optional = false; public: VarEnum(bool optional = false) { m_optional = optional; InnerInit(); } VarEnum(SafeEnum value, bool optional = false) : VarEnum(optional) { m_value = value; } VarEnum(LuaState* l, int& index, bool optional = false) : VarEnum(optional) { GetInc(l, index); } VarEnum(SafeEnum value, LuaState* l, int& index, bool optional = false) : VarEnum(value, optional) { GetInc(l, index); } inline operator SafeEnum() { return m_value; } inline SafeEnum& operator ()() { return m_value; } inline SafeEnum& GetValue() { return m_value; } inline bool IsValid(LuaState* l, int index) { return InnerIsValid(l, index); } inline bool IsOptional() { return m_optional; } private: void GetInc(LuaState* l, int& index) { bool is_nil = lua_isnil(l, index); if (!m_optional || (!is_nil && InnerIsValid(l, index))) { ASSERT(!is_nil); InnerGet(l, index); } } public: inline void Get(LuaState* l, int index) { int idx = index; GetInc(l, idx); } inline int Return(LuaState* l) { return InnerPush(l); } inline VarEnum& operator-(const SafeEnum& value) { m_value - value; return *this; } inline VarEnum& operator+(const SafeEnum& value) { m_value + value; return *this; } inline VarEnum& operator*(const SafeEnum& value) { m_value * value; return *this; } inline VarEnum& operator/(const SafeEnum& value) { m_value / value; return *this; } inline VarEnum& operator=(const SafeEnum& value) { m_value = value; return *this; } inline VarEnum& operator-=(const SafeEnum& value) { m_value -= value; return *this; } inline VarEnum& operator+=(const SafeEnum& value) { m_value += value; return *this; } inline VarEnum& operator*=(const SafeEnum& value) { m_value *= value; return *this; } inline VarEnum& operator/=(const SafeEnum& value) { m_value /= value; return *this; } inline bool operator==(const SafeEnum& value) { return m_value == value; } inline bool operator!=(const SafeEnum& value) { return m_value != value; } inline VarEnum& operator-(const VarEnum& v) { m_value - v.m_value; return *this; } inline VarEnum& operator+(const VarEnum& v) { m_value + v.m_value; return *this; } inline VarEnum& operator*(const VarEnum& v) { m_value * v.m_value; return *this; } inline VarEnum& operator/(const VarEnum& v) { m_value / v.m_value; return *this; } inline VarEnum& operator=(const VarEnum& v) { m_value = v.m_value; return *this; } inline VarEnum& operator-=(const VarEnum& v) { m_value -= v.m_value; return *this; } inline VarEnum& operator+=(const VarEnum& v) { m_value += v.m_value; return *this; } inline VarEnum& operator*=(const VarEnum& v) { m_value *= v.m_value; return *this; } inline VarEnum& operator/=(const VarEnum& v) { m_value /= v.m_value; return *this; } inline bool operator==(const VarEnum& v) { return m_value == v.m_value; } inline bool operator!=(const VarEnum& v) { return m_value != v.m_value; } protected: void InnerInit() { m_value = SafeEnum(0); } bool InnerIsValid(LuaState* l, int index) { Var s; return s.IsValid(l, index); } void InnerGet(LuaState* l, int& index) { Var c(l, index); *this = FindValue >(c); } int InnerPush(LuaState* l) { Var s = this->GetValue().ToString(); return s.Return(l); } }; //----------------------------------------------------------------------------- class Stack { public: Stack(LuaState* l, int32_t start_index = 1) { m_state = l; m_index = start_index; } virtual ~Stack() { } inline operator int32_t() { return m_result; } int32_t GetArgs() { return lua_gettop(m_state); } //------------------------------------------------------------------------- template Stack& operator>>(T& var) { var = T(var.GetValue(), m_state, m_index, var.IsOptional()); return *this; } /* template Stack& operator>>(Var& var) { var = Var(var.GetValue(), m_state, m_index, var.IsOptional()); return *this; } template Stack& operator>>(Var& var) { var = Var(var.GetValue(), m_state, m_index, var.IsOptional()); return *this; } template Stack& operator>>(VarPtr& var) { var = VarPtr(m_state, m_index); return *this; } */ /* template Stack& operator>>(T& var) { Var ret(m_state, m_index); var = ret.GetValue(); return *this; } template Stack& operator>>(VarPtrLight& var) { var = VarPtrLight(m_state, m_index); return *this; } */ //------------------------------------------------------------------------- template Stack& operator<<(T& var) { m_result += var.Return(m_state); return *this; } /* template Stack& operator<<(T& var) { Var ret(var, false); m_result += ret.Return(m_state); return *this; } template Stack& operator<<(VarPtr& var) { m_result += var.Return(m_state); return *this; } template Stack& operator<<(VarPtrLight& var) { m_result += var.Return(m_state); return *this; } */ private: LuaState* m_state = nullptr; int32_t m_index = 1; int32_t m_result = 0; }; //----------------------------------------------------------------------------- class Loader { friend class ObjectDef; public: Loader(); virtual ~Loader(); bool ExecLuaFile(String const &lua); bool ExecLuaCode(String const &lua); template T GetVar(String const &name) { lua_getglobal(m_lua_state, name.C()); Var var; var.Get(m_lua_state, -1); lua_pop(m_lua_state, 1); return var; } template T* GetPtr(String const &name) { lua_getglobal(m_lua_state, name.C()); VarPtr var; var.Get(m_lua_state, -1); lua_pop(m_lua_state, 1); return var(); } protected: LuaState* GetLuaState(); static void Store(LuaState* l, Loader* loader); static Loader *Find(LuaState* l); static void Release(LuaState* l, Loader* loader); static void StoreObject(LuaState* l, Object* obj); //Virtual Store lua object ------------------------------------------------ virtual void Store(Object* obj) { UNUSED(obj); } private: LuaState* m_lua_state; }; //----------------------------------------------------------------------------- // ObjectDef member implementations that require VarPtr template int ObjectDef::Store(LuaState * l) { VarPtr obj; obj.Get(l, 1); ASSERT(obj()); Loader::StoreObject(l, obj()); return 0; } template int ObjectDef::Del(LuaState * l) { VarPtr obj; obj.Get(l, 1); ASSERT(obj()); delete obj(); return 0; } } /* namespace Lolua */ typedef Lolua::Function LuaFunction; typedef Lolua::ObjectDef LuaObjectDef; typedef Lolua::Object LuaObject; typedef Lolua::ObjectLib LuaObjectLib; typedef Lolua::Loader LuaLoader; typedef Lolua::Var LuaBool; typedef Lolua::Var LuaCharPtr; typedef Lolua::Var LuaString; typedef Lolua::Var LuaDouble; typedef Lolua::Var LuaFloat; typedef Lolua::Var LuaInt64; typedef Lolua::Var LuaInt32; typedef Lolua::Var LuaUInt32; typedef Lolua::Var LuaUInt64; typedef Lolua::Var LuaVec2; typedef Lolua::Var LuaVec3; typedef Lolua::Var LuaVec4; typedef Lolua::VarColor LuaColor; typedef Lolua::Stack LuaStack; } /* namespace lol */