summaryrefslogtreecommitdiff
path: root/Source/3rdParty/Luax/luax_class.inl
diff options
context:
space:
mode:
Diffstat (limited to 'Source/3rdParty/Luax/luax_class.inl')
-rw-r--r--Source/3rdParty/Luax/luax_class.inl182
1 files changed, 162 insertions, 20 deletions
diff --git a/Source/3rdParty/Luax/luax_class.inl b/Source/3rdParty/Luax/luax_class.inl
index 8cf0f55..bbda6de 100644
--- a/Source/3rdParty/Luax/luax_class.inl
+++ b/Source/3rdParty/Luax/luax_class.inl
@@ -5,7 +5,7 @@ namespace Luax
// ӿ
///
- /// ԲͬͣͨGetLuaClassName
+ /// ԲͬͣͨGetLuaClassName࣬GetClassNameᱻǣָluax_c_getupvalue
///
template<typename T>
int LuaxClass<T>::l_GetClassName(lua_State* L)
@@ -33,7 +33,6 @@ namespace Luax
state.RegisterMethods(regTable);
}
-
///
/// ijԱעclass table
///
@@ -48,7 +47,6 @@ namespace Luax
state.RegisterMethods(regTable);
}
-
///
/// ʵijԱעinterface table
///
@@ -56,14 +54,14 @@ namespace Luax
void LuaxClass<T>::RegisterLuaxInterface(LuaxState& state)
{
luaL_Reg regTable[] = {
- { "__gc", l___gc },
- { NULL, NULL }
+ { "GetClass", l_GetClass },
+ { "GetRefTable", l_GetRefTable },
+ { NULL, NULL }
};
state.RegisterMethods(regTable);
}
-
///
/// ijԱעclass table
///
@@ -107,30 +105,55 @@ namespace Luax
template<typename T>
LuaxClass<T>::LuaxClass()
- : mRC(1) // ʱĬһ
- , mSafer(false)
{
}
template<typename T>
LuaxClass<T>::~LuaxClass()
{
- assert(mSafer);
}
template<typename T>
- void LuaxClass<T>::Retain()
+ template<typename U>
+ void LuaxClass<T>::LuaRetain(LuaxState& state, U* userdata)
{
- ++mRC;
+ if (PushLuaxRefTable(state))
+ {
+ if (userdata->PushLuaxUserdata(state))
+ {
+ lua_pushvalue(state, -1); // copy the userdata
+ lua_gettable(state, -3); // get the count (or nil)
+ u32 count = state.GetValue<u32>(-1, 0); // get the count (or 0)
+ lua_pop(state, 1); // pop the old count
+ lua_pushnumber(state, count + 1); // push the new count
+ lua_settable(state, -3); // save it in the table: reftable[userdata] = count
+ }
+ }
}
template<typename T>
- void LuaxClass<T>::Release()
+ template<typename U>
+ void LuaxClass<T>::LuaRelease(LuaxState& state, U* userdata)
{
- if (--mRC <= 0)
+ if (PushLuaxRefTable(state))
{
- mSafer = true; // safer
- delete this;
+ if (userdata->PushLuaxUserdata(state))
+ {
+ lua_pushvalue(state, -1); // copy the userdata
+ lua_gettable(state, -3); // get the count (or nil)
+ u32 count = state.GetValue<u32>(-1, 0); // get the count (or 0)
+ lua_pop(state, 1); // pop the old count
+
+ if (count == 0) return; // nothing to do
+
+ if (count > 1) {
+ lua_pushnumber(state, count - 1); // push the new count
+ }
+ else {
+ lua_pushnil(state); // maybe cause gc
+ }
+ lua_settable(state, -3); // save it in the table
+ }
}
}
@@ -197,6 +220,12 @@ namespace Luax
return false;
}
+ ///
+ /// userdataԴref tablemember tableinterface table
+ /// ref table kvǿtableuserdataüͨuserdataΪkeyΪvalueԼԱ
+ /// member table luaʵijԱ
+ /// interface table б͵ʵеijԱ
+ ///
template<typename T>
void LuaxClass<T>::BindToLua(LuaxState& state)
{
@@ -221,14 +250,14 @@ namespace Luax
int memberTable = top - 1;
int refTable = top - 2;
- // ref table ע __gc__tostring
+ // ref table ע __gc __tostring
lua_pushcfunction(state, l___gc);
lua_setfield(state, refTable, "__gc");
lua_pushcfunction(state, l___tostring);
lua_setfield(state, refTable, "__tostring");
- // member table Ϊ ref table __index __newindex
+ // ref table __index __newindex Ϊ member table
lua_pushvalue(state, memberTable);
lua_setfield(state, refTable, "__index");
@@ -245,6 +274,59 @@ namespace Luax
assert(mUserdata);
}
+ ///
+ /// Աù
+ ///
+ template<typename T>
+ void LuaxClass<T>::SetMemberRef(LuaxState& state, LuaxMemberRef& memRef, int idx)
+ {
+ ClearMemberRef(state, memRef);
+ if (!lua_isnil(state, idx))
+ {
+ idx = state.AbsIndex(idx);
+ if (PushLuaxRefTable(state))
+ {
+ lua_pushvalue(state, idx);
+ memRef.refID = luaL_ref(state, -2);
+ state.Pop(); // ref table
+ }
+ }
+ }
+
+ template<typename T>
+ bool LuaxClass<T>::PushMemberRef(LuaxState& state, LuaxMemberRef& memRef)
+ {
+ if (memRef)
+ {
+ if (PushLuaxRefTable(state))
+ {
+ lua_rawgeti(state, -1, memRef.refID);
+ lua_replace(state, -2); // ref table
+ if (lua_isnil(state, -1))
+ goto failed;
+ return true;
+ }
+ }
+ lua_pushnil(state);
+ failed:
+ memRef.refID = LUA_NOREF;
+ return false;
+ }
+
+ template<typename T>
+ void LuaxClass<T>::ClearMemberRef(LuaxState& state, LuaxMemberRef& memRef)
+ {
+ if (memRef)
+ {
+ if (PushLuaxRefTable(state))
+ {
+ luaL_unref(state, -1, memRef.refID);
+ state.Pop(); // ref table
+ }
+ memRef.refID = LUA_NOREF;
+ }
+ }
+
//--------------------------------------------------------------------------------------------------------------
///
@@ -258,15 +340,51 @@ namespace Luax
return 0;
}
+ ///
+ /// ʽ:
+ /// ַ
+ ///
template<typename T>
int LuaxClass<T>::l___tostring(lua_State* L)
{
+ LUAX_STATE(L);
+ T* self = state.GetLuaUserdata<T>(1);
+ if (self)
+ {
+ char buf[1024] = {0};
+ const char* fmt = "%p <%s>";
+ cc8* classname = "";
+ lua_getfield(state, 1, "GetClassName");
+ if (state.IsType(-1, LUA_TFUNCTION))
+ {
+ lua_pushvalue(L, 1); // userdata
+ state.Call(1, 1); // GetClassName
+ classname = state.GetValue<cc8*>(-1, "");
+ }
+ else
+ {
+ classname = T::GetLuaxClassName();
+ }
+ sprintf(buf, fmt, self, classname);
+ lua_pushstring(L, buf);
+ return 1;
+ }
return 0;
}
template<typename T>
int LuaxClass<T>::l_ExtendFactory(lua_State* L)
{
+
+
+ return 0;
+ }
+
+ template<typename T>
+ int LuaxClass<T>::l_ExtendSingleton(lua_State* L)
+ {
+
+
return 0;
}
@@ -274,9 +392,33 @@ namespace Luax
int LuaxClass<T>::l_GetInterfaceTable(lua_State* L)
{
LUAX_STATE(L);
- assert(mInterfaceTable);
- mInterfaceTable.PushRef(state);
- return 0;
+ if (!mInterfaceTable)
+ lua_pushnil(L);
+ else
+ mInterfaceTable.PushRef(state);
+ return 1;
+ }
+
+ template<typename T>
+ int LuaxClass<T>::l_GetClass(lua_State* L)
+ {
+ LUAX_STATE(L);
+ if (!mClassTable)
+ lua_pushnil(L);
+ else
+ mClassTable.PushRef(state);
+ return 1;
+ }
+
+ template<typename T>
+ int LuaxClass<T>::l_GetRefTable(lua_State* L)
+ {
+ LUAX_STATE(L);
+ T* self = state.GetLuaUserdata<T>(1);
+ bool success = self->PushLuaxRefTable(state);
+ if (!success)
+ lua_pushnil(L);
+ return 1;
}
template<typename T> LuaxStrongRef LuaxClass<T>::mInterfaceTable; // interface table