@@ -215,6 +215,18 @@ namespace Util
215215 ToDo: Implement a proper class like gmod has with CLuaCLass/CLuaLibrary & use thoes instead for everything.
216216*/
217217
218+ /*
219+ * How to properly push & clean up LuaUserData.
220+ *
221+ * First, use the proper function for the userdata you want to push.
222+ *
223+ * Push_LuaClass - Use this macro if you want the Lua GC to free the userdata.
224+ * PushReferenced_LuaClass - Use this macro if you want to manually delete the userdata, it will hold a reference of itself stopping the GC.
225+ *
226+ * NOTE: If you use PushReferenced_LuaClass you should ALWAYS call DeleteAll_[YourClass] for your userdata
227+ * as else it COULD persist across lua states which is VERY BAD as the references will ALL be INVALID.
228+ */
229+
218230struct LuaUserData ;
219231extern bool g_pRemoveLuaUserData;
220232extern std::unordered_set<LuaUserData*> g_pLuaUserData; // A set containing all LuaUserData that actually hold a reference.
@@ -373,6 +385,7 @@ className* Get_##className(int iStackPos, bool bError) \
373385 return (className*)pLuaData->GetData (); \
374386}
375387
388+ // Only used by CBaseClient & CHLTVClient as they both work with each other / a CHLTVClient can use all CBaseClient functions.
376389#define SpecialGet_LuaClass ( className, luaType, luaType2, strName ) \
377390static std::string invalidType_##className = MakeString(" Tried to use something that wasn't a " , strName, " !" ); \
378391static std::string triedNull_##className = MakeString(" Tried to use a NULL " , strName, " !" ); \
@@ -482,6 +495,9 @@ static void DeleteAll_##className() \
482495 (vec).erase (_it); \
483496}
484497
498+ // A default index function for userData,
499+ // which handles everything like finding the functions in the metatable
500+ // or getting vars on the object like: print(userData.value)
485501#define Default__index (className ) \
486502LUA_FUNCTION_STATIC (className ## __index) \
487503{ \
@@ -498,6 +514,23 @@ LUA_FUNCTION_STATIC(className ## __index) \
498514 return 1 ; \
499515}
500516
517+ // A default newindex function for userData,
518+ // handles setting vars on the object like: userData.value = true
519+ #define Default__newindex (className ) \
520+ LUA_FUNCTION_STATIC (className ## __newindex) \
521+ { \
522+ Util::ReferencePush (LUA, Get_##className##_Data (1 , true )->GetLuaTable ()); \
523+ LUA->Push (2 ); \
524+ LUA->Push (3 ); \
525+ LUA->RawSet (-3 ); \
526+ LUA->Pop (1 ); \
527+ \
528+ return 0 ; \
529+ }
530+
531+ // A default gc function for userData,
532+ // handles garbage collection, inside the func argument you can use pData as a variable
533+ // like pData->GetData() to get your class. Just see how it's done inside the bf_read gc definition.
501534#define Default__gc (className, func ) \
502535LUA_FUNCTION_STATIC (className ## __gc) \
503536{ \
@@ -512,18 +545,7 @@ LUA_FUNCTION_STATIC(className ## __gc) \
512545 return 0 ; \
513546} \
514547
515- #define Default__newindex (className ) \
516- LUA_FUNCTION_STATIC (className ## __newindex) \
517- { \
518- Util::ReferencePush (LUA, Get_##className##_Data (1 , true )->GetLuaTable ()); \
519- LUA->Push (2 ); \
520- LUA->Push (3 ); \
521- LUA->RawSet (-3 ); \
522- LUA->Pop (1 ); \
523- \
524- return 0 ; \
525- }
526-
548+ // Default function for GetTable. Simple.
527549#define Default__GetTable (className ) \
528550LUA_FUNCTION_STATIC (className ## _GetTable) \
529551{ \
0 commit comments