Permalink
Browse files

Eluna add new system for userdata management. single userdata with GC.

Note that this will still need the core side destructors to have the ref remove function used in order to have invalid pointer errors.
  • Loading branch information...
1 parent 74aaea3 commit e131f36d390996d7279804ba012f718b9c0e21b7 @Rochet2 Rochet2 committed with Foereaper May 28, 2014
Showing with 301 additions and 176 deletions.
  1. +5 −0 .gitignore
  2. +20 −6 HookMgr.cpp
  3. +4 −1 HookMgr.h
  4. +15 −7 LuaEngine.cpp
  5. +239 −149 LuaEngine.h
  6. +18 −13 LuaFunctions.cpp
View
@@ -0,0 +1,5 @@
+*.orig
+*.rej
+*.bak
+*.patch
+*.diff
View
@@ -7,6 +7,20 @@
#include "LuaEngine.h"
#include "HookMgr.h"
+void HookMgr::RemoveRef(const void* obj) const
+{
+ lua_rawgeti(sEluna->L, LUA_REGISTRYINDEX, sHookMgr->userdata_table);
+ lua_pushfstring(sEluna->L, "%p", obj);
+ lua_gettable(sEluna->L, -2);
+ if (!lua_isnoneornil(sEluna->L, -1))
+ {
+ lua_pushfstring(sEluna->L, "%p", obj);
+ lua_pushnil(sEluna->L);
+ lua_settable(sEluna->L, -4);
+ }
+ lua_pop(sEluna->L, 2);
+}
+
void HookMgr::OnEngineRestart()
{
if (!sEluna->ServerEventBindings.HasEvents(ELUNA_EVENT_ON_RESTART))
@@ -205,8 +219,8 @@ bool HookMgr::OnPacketReceive(WorldSession* session, WorldPacket& packet)
bool HookMgr::OnAddonMessage(Player* sender, uint32 type, std::string& msg, Player* receiver, Guild* guild, Group* group, Channel* channel)
{
if (!sEluna->ServerEventBindings.HasEvents(ADDON_EVENT_ON_MESSAGE))
- return false;
- ELUNA_GUARD();
+ return false;
+ ELUNA_GUARD();
sEluna->ServerEventBindings.BeginCall(ADDON_EVENT_ON_MESSAGE);
sEluna->Push(sEluna->L, sender);
sEluna->Push(sEluna->L, type);
@@ -223,16 +237,16 @@ bool HookMgr::OnAddonMessage(Player* sender, uint32 type, std::string& msg, Play
sEluna->Push(sEluna->L, channel->GetChannelId());
else
sEluna->Push(sEluna->L);
- sEluna->ServerEventBindings.ExecuteCall();
- sEluna->ServerEventBindings.EndCall();
+ sEluna->ServerEventBindings.ExecuteCall();
+ sEluna->ServerEventBindings.EndCall();
return true;
}
#ifndef MANGOS
class ElunaWorldAI : public WorldScript
{
public:
- ElunaWorldAI() : WorldScript("ElunaWorldAI") {}
+ ElunaWorldAI(): WorldScript("ElunaWorldAI") {}
~ElunaWorldAI() {}
void OnOpenStateChange(bool open) override
@@ -1582,7 +1596,7 @@ struct ElunaCreatureAI : ScriptedAI
#define me m_creature
#endif
- ElunaCreatureAI(Creature* creature) : ScriptedAI(creature)
+ ElunaCreatureAI(Creature* creature): ScriptedAI(creature)
{
JustRespawned();
}
View
@@ -37,6 +37,8 @@ struct AreaTriggerEntry;
class ReactorAI;
typedef ReactorAI ScriptedAI;
#else
+#undef UNORDERED_MAP
+#define UNORDERED_MAP std::unordered_map
struct ScriptedAI;
#endif
class AuctionHouseObject;
@@ -321,7 +323,8 @@ enum GossipEvents
class HookMgr
{
public:
- friend class ACE_Singleton<HookMgr, ACE_Thread_Mutex>;
+ int userdata_table;
+ void RemoveRef(const void* obj) const;
CreatureAI* GetAI(Creature* creature);
View
@@ -74,6 +74,14 @@ bool StartEluna()
luaL_openlibs(sEluna->L);
RegisterFunctions(sEluna->L);
+ // Create hidden table with weak values
+ lua_newtable(sEluna->L);
+ lua_newtable(sEluna->L);
+ lua_pushstring(sEluna->L, "v");
+ lua_setfield(sEluna->L, -2, "__mode");
+ lua_setmetatable(sEluna->L, -2);
+ sHookMgr->userdata_table = luaL_ref(sEluna->L, LUA_REGISTRYINDEX);
+
ScriptPaths scripts;
std::string folderpath = sConfigMgr->GetStringDefault("Eluna.ScriptPath", "lua_scripts");
#if PLATFORM == PLATFORM_UNIX || PLATFORM == PLATFORM_APPLE
@@ -83,7 +91,7 @@ bool StartEluna()
#endif
ELUNA_LOG_INFO("[Eluna]: Searching scripts from `%s`", folderpath.c_str());
sEluna->GetScripts(folderpath, scripts);
- sEluna->GetScripts(folderpath+"/extensions", scripts);
+ sEluna->GetScripts(folderpath + "/extensions", scripts);
sEluna->RunScripts(scripts);
/*
@@ -187,7 +195,7 @@ void Eluna::report(lua_State* L)
const char* msg = lua_tostring(L, -1);
while (msg)
{
- lua_pop(L, -1);
+ lua_pop(L, 1);
ELUNA_LOG_ERROR("%s", msg);
msg = lua_tostring(L, -1);
}
@@ -504,15 +512,15 @@ template<> int64 Eluna::CHECKVAL<int64>(lua_State* L, int narg, int64 def)
#define TEST_OBJ(T, O, E, F)\
{\
if (!O || !O->F())\
-{\
+ {\
if (E)\
-{\
+ {\
std::string errmsg(ElunaTemplate<T>::tname);\
errmsg += " expected";\
luaL_argerror(L, narg, errmsg.c_str());\
-}\
+ }\
return NULL;\
-}\
+ }\
return O->F();\
}
template<> Unit* Eluna::CHECKOBJ<Unit>(lua_State* L, int narg, bool error)
@@ -772,7 +780,7 @@ void Eluna::EntryBind::Insert(uint32 entryId, int eventId, int funcRef)
Bindings[entryId][eventId] = funcRef;
}
-EventMgr::LuaEvent::LuaEvent(EventProcessor* _events, int _funcRef, uint32 _delay, uint32 _calls, Object* _obj) :
+EventMgr::LuaEvent::LuaEvent(EventProcessor* _events, int _funcRef, uint32 _delay, uint32 _calls, Object* _obj):
events(_events), funcRef(_funcRef), delay(_delay), calls(_calls), obj(_obj)
{
if (_events)
Oops, something went wrong.

0 comments on commit e131f36

Please sign in to comment.