Skip to content

Commit

Permalink
Eluna add new system for userdata management. single userdata with GC.
Browse files Browse the repository at this point in the history
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
Rochet2 authored and Foereaper committed Jun 29, 2014
1 parent 74aaea3 commit e131f36
Show file tree
Hide file tree
Showing 6 changed files with 301 additions and 176 deletions.
5 changes: 5 additions & 0 deletions .gitignore
@@ -0,0 +1,5 @@
*.orig
*.rej
*.bak
*.patch
*.diff
26 changes: 20 additions & 6 deletions HookMgr.cpp
Expand Up @@ -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))
Expand Down Expand Up @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -1582,7 +1596,7 @@ struct ElunaCreatureAI : ScriptedAI
#define me m_creature
#endif

ElunaCreatureAI(Creature* creature) : ScriptedAI(creature)
ElunaCreatureAI(Creature* creature): ScriptedAI(creature)
{
JustRespawned();
}
Expand Down
5 changes: 4 additions & 1 deletion HookMgr.h
Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand Down
22 changes: 15 additions & 7 deletions LuaEngine.cpp
Expand Up @@ -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
Expand All @@ -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);

/*
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit e131f36

Please sign in to comment.