|
- //
- // Lol Engine — base class for Lua script loading
- //
- // Copyright © 2009—2015 Sam Hocevar <sam@hocevar.net>
- // © 2009—2015 Benjamin “Touky” Huet <huet.benjamin@gmail.com>
- //
- // 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<ClassMethod> const& statics,
- array<ClassMethod> const& methods,
- array<ClassVar> 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<ClassMethod> m_statics;
- array<ClassMethod> m_methods;
- array<ClassVarStr> 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 <typename TLuaClass>
- static void Register(LuaState *l)
- {
- //Default statics
- static const luaL_Reg default_statics[]
- {
- { "New", New<TLuaClass> },
- { "Store", Store<TLuaClass> },
- { "__gc", Del<TLuaClass> },
- { 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<TLuaClass>());
- //Register default statics and template one
- luaL_setfuncs(l, default_statics, 0);
- luaL_setfuncs(l, GetStaticMethods<TLuaClass>(), 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<TLuaClass>());
-
- //Repeat all the operations for instance metatable
- luaL_newmetatable(l, GetMethodName<TLuaClass>());
- luaL_setfuncs(l, GetInstanceMethods<TLuaClass>(), 0);
- lua_pushvalue(l, -1);
- lua_setfield(l, -1, "__index");
-
- //Create variables Get/Set
- const array<ObjectLib::ClassVarStr>& variables = GetVariables<TLuaClass>();
- 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 <typename TLuaClass>
- static const ObjectLib* GetLib()
- {
- const ObjectLib* lib = TLuaClass::GetLib();
- ASSERT(lib);
- return lib;
- }
-
- public:
- template <typename TLuaClass>
- static const char* GetObjectName() { return GetLib<TLuaClass>()->m_class_name.C(); }
- template <typename TLuaClass>
- static const char* GetStaticName() { return GetLib<TLuaClass>()->m_static_name.C(); }
- template <typename TLuaClass>
- static const char* GetMethodName() { return GetLib<TLuaClass>()->m_method_name.C(); }
- template <typename TLuaClass>
- static const ClassMethod* GetStaticMethods() { return GetLib<TLuaClass>()->m_statics.data(); }
- template <typename TLuaClass>
- static const ClassMethod* GetInstanceMethods() { return GetLib<TLuaClass>()->m_methods.data(); }
- template <typename TLuaClass>
- static const array<ObjectLib::ClassVarStr>& GetVariables() { return GetLib<TLuaClass>()->m_variables; }
-
- protected:
- //-------------------------------------------------------------------------
- template <typename TLuaClass>
- 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<TLuaClass>());
- //Set metatable to instance
- lua_setmetatable(l, -2);
- //Return 1 so Lua will get the UserData and clean the stack.
- return 1;
- }
-
- //-------------------------------------------------------------------------
- template <typename TLuaClass> static int Store(LuaState * l);
- template <typename TLuaClass> 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<typename T>
- 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<T**>(luaL_checkudata(l, index++, ObjectDef::GetMethodName<T>()));
- 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<typename T>
- 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<T**>(luaL_testudata(l, index++, ObjectDef::GetMethodName<T>()));
- m_value = obj ? *obj : nullptr;
- }
- };
- */
- //-----------------------------------------------------------------------------
- template<typename T>
- 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<T>& operator-(const T& value) { m_value - value; return *this; }
- inline Var<T>& operator+(const T& value) { m_value + value; return *this; }
- inline Var<T>& operator*(const T& value) { m_value * value; return *this; }
- inline Var<T>& operator/(const T& value) { m_value / value; return *this; }
- inline Var<T>& operator=(const T& value) { m_value = value; return *this; }
- inline Var<T>& operator-=(const T& value) { m_value -= value; return *this; }
- inline Var<T>& operator+=(const T& value) { m_value += value; return *this; }
- inline Var<T>& operator*=(const T& value) { m_value *= value; return *this; }
- inline Var<T>& operator/=(const T& value) { m_value /= value; return *this; }
- inline Var<T>& operator-(const Var<T>& o) { m_value - o.m_value; return *this; }
- inline Var<T>& operator+(const Var<T>& o) { m_value + o.m_value; return *this; }
- inline Var<T>& operator*(const Var<T>& o) { m_value * o.m_value; return *this; }
- inline Var<T>& operator/(const Var<T>& o) { m_value / o.m_value; return *this; }
- inline Var<T>& operator=(const Var<T>& o) { m_value = o.m_value; return *this; }
- inline Var<T>& operator-=(const Var<T>& o) { m_value -= o.m_value; return *this; }
- inline Var<T>& operator+=(const Var<T>& o) { m_value += o.m_value; return *this; }
- inline Var<T>& operator*=(const Var<T>& o) { m_value *= o.m_value; return *this; }
- inline Var<T>& operator/=(const Var<T>& 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<T>& o) { return m_value == o.m_value; }
- inline bool operator!=(const Var<T>& 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<bool>::InnerIsValid(LuaState* l, int index)
- {
- return lua_isboolean(l, index);
- }
- template<> inline void Var<bool>::InnerGet(LuaState* l, int& index)
- {
- m_value = !!lua_toboolean(l, index++);
- }
- template<> inline int Var<bool>::InnerPush(LuaState* l)
- {
- lua_pushboolean(l, m_value);
- return 1;
- }
- //-----------------------------------------------------------------------------
- template<> inline bool Var<char const*>::InnerIsValid(LuaState* l, int index)
- {
- return !!lua_isstring(l, index);
- }
- template<> inline void Var<char const*>::InnerGet(LuaState* l, int& index)
- {
- m_value = lua_tostring(l, index++);
- }
- template<> inline int Var<char const*>::InnerPush(LuaState* l)
- {
- lua_pushstring(l, m_value);
- return 1;
- }
- //-----------------------------------------------------------------------------
- template<> inline void Var<String>::InnerInit()
- {
- m_value = String();
- }
- template<> inline bool Var<String>::InnerIsValid(LuaState* l, int index)
- {
- Var<char const*> v;
- return v.IsValid(l, index);
- }
- template<> inline void Var<String>::InnerGet(LuaState* l, int& index)
- {
- Var<char const*> v(l, index);
- m_value = v();
- }
- template<> inline int Var<String>::InnerPush(LuaState* l)
- {
- Var<char const*> v;
- v = m_value.C();
- return v.Return(l);
- }
- //-----------------------------------------------------------------------------
- template<> inline bool Var<double>::InnerIsValid(LuaState* l, int index)
- {
- return !!lua_isnumber(l, index);
- }
- template<> inline void Var<double>::InnerGet(LuaState* l, int& index)
- {
- m_value = lua_tonumber(l, index++);
- }
- template<> inline int Var<double>::InnerPush(LuaState* l)
- {
- lua_pushnumber(l, m_value);
- return 1;
- }
- //-----------------------------------------------------------------------------
- template<> inline bool Var<float>::InnerIsValid(LuaState* l, int index)
- {
- Var<double> v;
- return v.IsValid(l, index);
- }
- template<> inline void Var<float>::InnerGet(LuaState* l, int& index)
- {
- Var<double> v(l, index);
- m_value = (float)v();
- }
- template<> inline int Var<float>::InnerPush(LuaState* l)
- {
- Var<double> v = (double)m_value;
- return v.Return(l);
- }
-
- #if 0
- //-----------------------------------------------------------------------------
- template<> inline bool Var<int64_t>::InnerIsValid(LuaState* l, int index)
- {
- return !!lua_isnumber(l, index);
- }
- template<> inline void Var<int64_t>::InnerGet(LuaState* l, int& index)
- {
- m_value = lua_tointeger(l, index++);
- }
- template<> inline int Var<int64_t>::InnerPush(LuaState* l)
- {
- lua_pushinteger(l, m_value);
- return 1;
- }
- #endif
-
- //-----------------------------------------------------------------------------
- template<> inline bool Var<int32_t>::InnerIsValid(LuaState* l, int index)
- {
- Var<int64_t> v;
- return v.IsValid(l, index);
- }
- template<> inline void Var<int32_t>::InnerGet(LuaState* l, int& index)
- {
- Var<int64_t> v(l, index);
- m_value = (int32_t)v();
- }
- template<> inline int Var<int32_t>::InnerPush(LuaState* l)
- {
- Var<int64_t> v = (int64_t)m_value;
- return v.Return(l);
- }
-
- //-----------------------------------------------------------------------------
- template<> inline bool Var<uint32_t>::InnerIsValid(LuaState* l, int index)
- {
- return !!lua_isnumber(l, index);
- }
- template<> inline void Var<uint32_t>::InnerGet(LuaState* l, int& index)
- {
- m_value = (uint32_t)(lua_Unsigned)lua_tointeger(l, index++);
- }
- template<> inline int Var<uint32_t>::InnerPush(LuaState* l)
- {
- lua_pushinteger(l, (lua_Integer)m_value);
- return 1;
- }
-
- #if 0
- //-----------------------------------------------------------------------------
- template<> inline bool Var<uint64_t>::InnerIsValid(LuaState* l, int index)
- {
- Var<uint32_t> v;
- return v.IsValid(l, index);
- }
- template<> inline void Var<uint64_t>::InnerGet(LuaState* l, int& index)
- {
- Var<uint32_t> v(l, index);
- m_value = (uint64_t)v();
- }
- template<> inline int Var<uint64_t>::InnerPush(LuaState* l)
- {
- Var<uint32_t> v = (uint32_t)m_value;
- return v.Return(l);
- }
- #endif
-
- //-----------------------------------------------------------------------------
- template<> inline bool Var<vec2>::InnerIsValid(LuaState* l, int index)
- {
- Var<float> x;
- return x.IsValid(l, index);
- }
- template<> inline void Var<vec2>::InnerGet(LuaState* l, int& index)
- {
- Var<float> x(l, index);
- Var<float> y(x(), l, index, true);
- m_value = vec2(x, y);
- }
- template<> inline int Var<vec2>::InnerPush(LuaState* l)
- {
- Var<float> x = m_value.x;
- Var<float> y = m_value.y;
- return (x.Return(l) + y.Return(l));
- }
- //-----------------------------------------------------------------------------
- template<> inline bool Var<vec3>::InnerIsValid(LuaState* l, int index)
- {
- Var<float> x;
- return x.IsValid(l, index);
- }
- template<> inline void Var<vec3>::InnerGet(LuaState* l, int& index)
- {
- Var<float> x(l, index);
- Var<float> y(x(), l, index, true);
- Var<float> z(x(), l, index, true);
- m_value = vec3(x, y, z);
- }
- template<> inline int Var<vec3>::InnerPush(LuaState* l)
- {
- Var<float> x = m_value.x;
- Var<float> y = m_value.y;
- Var<float> z = m_value.z;
- return (x.Return(l) + y.Return(l) + z.Return(l));
- }
- //-----------------------------------------------------------------------------
- template<> inline bool Var<vec4>::InnerIsValid(LuaState* l, int index)
- {
- Var<float> x;
- return x.IsValid(l, index);
- }
- template<> inline void Var<vec4>::InnerGet(LuaState* l, int& index)
- {
- Var<float> x(l, index);
- Var<float> y(x(), l, index, true);
- Var<float> z(x(), l, index, true);
- Var<float> w(x(), l, index, true);
- m_value = vec4(x, y, z, w);
- }
- template<> inline int Var<vec4>::InnerPush(LuaState* l)
- {
- Var<float> x = m_value.x;
- Var<float> y = m_value.y;
- Var<float> z = m_value.z;
- Var<float> w = m_value.w;
- return (x.Return(l) + y.Return(l) + z.Return(l) + w.Return(l));
- }
-
- //-----------------------------------------------------------------------------
- class VarColor
- {
- protected:
- Var<vec4> m_value;
-
- public:
- VarColor(bool optional = false)
- {
- m_value = Var<vec4>(optional);
- InnerInit();
- }
- VarColor(vec4 value, bool optional = false)
- {
- m_value = Var<vec4>(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<vec4>& o) { m_value - o; return *this; }
- inline VarColor& operator+(const Var<vec4>& o) { m_value + o; return *this; }
- inline VarColor& operator*(const Var<vec4>& o) { m_value * o; return *this; }
- inline VarColor& operator/(const Var<vec4>& o) { m_value / o; return *this; }
- inline VarColor& operator=(const Var<vec4>& o) { m_value = o; return *this; }
- inline VarColor& operator-=(const Var<vec4>& o) { m_value -= o; return *this; }
- inline VarColor& operator+=(const Var<vec4>& o) { m_value += o; return *this; }
- inline VarColor& operator*=(const Var<vec4>& o) { m_value *= o; return *this; }
- inline VarColor& operator/=(const Var<vec4>& 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<vec4>& o) { return m_value == o; }
- inline bool operator!=(const Var<vec4>& 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<String> 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<String> c(l, index);
- *this = Color::C8BppHexString(c);
- }
- }
- int InnerPush(LuaState* l)
- {
- Var<String> c = Color::HexString8Bpp(m_value);
- return c.Return(l);
- }
- };
-
- //-----------------------------------------------------------------------------
- template<typename E>
- class VarEnum
- {
- protected:
- SafeEnum<E> m_value;
- bool m_optional = false;
-
- public:
- VarEnum(bool optional = false)
- {
- m_optional = optional;
- InnerInit();
- }
- VarEnum(SafeEnum<E> value, bool optional = false)
- : VarEnum(optional)
- {
- m_value = value;
- }
- VarEnum(LuaState* l, int& index, bool optional = false)
- : VarEnum(optional)
- {
- GetInc(l, index);
- }
- VarEnum(SafeEnum<E> value, LuaState* l, int& index, bool optional = false)
- : VarEnum(value, optional)
- {
- GetInc(l, index);
- }
-
- inline operator SafeEnum<E>() { return m_value; }
- inline SafeEnum<E>& operator ()() { return m_value; }
- inline SafeEnum<E>& 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<E>& operator-(const SafeEnum<E>& value) { m_value - value; return *this; }
- inline VarEnum<E>& operator+(const SafeEnum<E>& value) { m_value + value; return *this; }
- inline VarEnum<E>& operator*(const SafeEnum<E>& value) { m_value * value; return *this; }
- inline VarEnum<E>& operator/(const SafeEnum<E>& value) { m_value / value; return *this; }
- inline VarEnum<E>& operator=(const SafeEnum<E>& value) { m_value = value; return *this; }
- inline VarEnum<E>& operator-=(const SafeEnum<E>& value) { m_value -= value; return *this; }
- inline VarEnum<E>& operator+=(const SafeEnum<E>& value) { m_value += value; return *this; }
- inline VarEnum<E>& operator*=(const SafeEnum<E>& value) { m_value *= value; return *this; }
- inline VarEnum<E>& operator/=(const SafeEnum<E>& value) { m_value /= value; return *this; }
- inline bool operator==(const SafeEnum<E>& value) { return m_value == value; }
- inline bool operator!=(const SafeEnum<E>& value) { return m_value != value; }
- inline VarEnum<E>& operator-(const VarEnum<E>& v) { m_value - v.m_value; return *this; }
- inline VarEnum<E>& operator+(const VarEnum<E>& v) { m_value + v.m_value; return *this; }
- inline VarEnum<E>& operator*(const VarEnum<E>& v) { m_value * v.m_value; return *this; }
- inline VarEnum<E>& operator/(const VarEnum<E>& v) { m_value / v.m_value; return *this; }
- inline VarEnum<E>& operator=(const VarEnum<E>& v) { m_value = v.m_value; return *this; }
- inline VarEnum<E>& operator-=(const VarEnum<E>& v) { m_value -= v.m_value; return *this; }
- inline VarEnum<E>& operator+=(const VarEnum<E>& v) { m_value += v.m_value; return *this; }
- inline VarEnum<E>& operator*=(const VarEnum<E>& v) { m_value *= v.m_value; return *this; }
- inline VarEnum<E>& operator/=(const VarEnum<E>& v) { m_value /= v.m_value; return *this; }
- inline bool operator==(const VarEnum<E>& v) { return m_value == v.m_value; }
- inline bool operator!=(const VarEnum<E>& v) { return m_value != v.m_value; }
-
- protected:
- void InnerInit()
- {
- m_value = SafeEnum<E>(0);
- }
- bool InnerIsValid(LuaState* l, int index)
- {
- Var<String> s;
- return s.IsValid(l, index);
- }
- void InnerGet(LuaState* l, int& index)
- {
- Var<String> c(l, index);
- *this = FindValue<SafeEnum<E> >(c);
- }
- int InnerPush(LuaState* l)
- {
- Var<String> 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<typename T>
- Stack& operator>>(T& var)
- {
- var = T(var.GetValue(), m_state, m_index, var.IsOptional());
- return *this;
- }
-
- /*
- template<typename T>
- Stack& operator>>(Var<T>& var)
- {
- var = Var<T>(var.GetValue(), m_state, m_index, var.IsOptional());
- return *this;
- }
- template<typename T>
- Stack& operator>>(Var<T>& var)
- {
- var = Var<T>(var.GetValue(), m_state, m_index, var.IsOptional());
- return *this;
- }
- template<typename T>
- Stack& operator>>(VarPtr<T>& var)
- {
- var = VarPtr<T>(m_state, m_index);
- return *this;
- }
- */
- /*
- template<typename T>
- Stack& operator>>(T& var)
- {
- Var<T> ret(m_state, m_index);
- var = ret.GetValue();
- return *this;
- }
- template<typename T>
- Stack& operator>>(VarPtrLight<T>& var)
- {
- var = VarPtrLight<T>(m_state, m_index);
- return *this;
- }
- */
-
- //-------------------------------------------------------------------------
- template<typename T>
- Stack& operator<<(T& var)
- {
- m_result += var.Return(m_state);
- return *this;
- }
- /*
- template<typename T>
- Stack& operator<<(T& var)
- {
- Var<T> ret(var, false);
- m_result += ret.Return(m_state);
- return *this;
- }
- template<typename T>
- Stack& operator<<(VarPtr<T>& var)
- {
- m_result += var.Return(m_state);
- return *this;
- }
- template<typename T>
- Stack& operator<<(VarPtrLight<T>& 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<typename T>
- T GetVar(String const &name)
- {
- lua_getglobal(m_lua_state, name.C());
- Var<T> var; var.Get(m_lua_state, -1);
- lua_pop(m_lua_state, 1);
- return var;
- }
- template<typename T>
- T* GetPtr(String const &name)
- {
- lua_getglobal(m_lua_state, name.C());
- VarPtr<T> 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 <typename TLuaClass>
- int ObjectDef::Store(LuaState * l)
- {
- VarPtr<TLuaClass> obj;
- obj.Get(l, 1);
- ASSERT(obj());
- Loader::StoreObject(l, obj());
- return 0;
- }
-
- template <typename TLuaClass>
- int ObjectDef::Del(LuaState * l)
- {
- VarPtr<TLuaClass> 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<bool> LuaBool;
- typedef Lolua::Var<char const*> LuaCharPtr;
- typedef Lolua::Var<String> LuaString;
- typedef Lolua::Var<double> LuaDouble;
- typedef Lolua::Var<float> LuaFloat;
- typedef Lolua::Var<int64_t> LuaInt64;
- typedef Lolua::Var<int32_t> LuaInt32;
- typedef Lolua::Var<uint32_t> LuaUInt32;
- typedef Lolua::Var<uint64_t> LuaUInt64;
- typedef Lolua::Var<vec2> LuaVec2;
- typedef Lolua::Var<vec3> LuaVec3;
- typedef Lolua::Var<vec4> LuaVec4;
- typedef Lolua::VarColor LuaColor;
- typedef Lolua::Stack LuaStack;
-
- } /* namespace lol */
|