Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Index: src/scripts/src/LuaEngine/LUAEngine.cpp
- ===================================================================
- --- src/scripts/src/LuaEngine/LUAEngine.cpp (revision 4445)
- +++ src/scripts/src/LuaEngine/LUAEngine.cpp (working copy)
- @@ -280,9 +280,9 @@
- if(unit != NULL && unit->IsUnit())
- pUnit = TO_UNIT(unit);
- if(L == NULL)
- - ArcLuna<Unit>::push(lu, pUnit);
- + ArcSole<Unit>::push(lu, pUnit);
- else
- - ArcLuna<Unit>::push(L, pUnit);
- + ArcSole<Unit>::push(L, pUnit);
- }
- void LuaEngine::PushGo(Object* go, lua_State* L)
- {
- @@ -290,9 +290,9 @@
- if(go != NULL && go->IsGameObject())
- pGo = TO< GameObject* >(go);
- if(L == NULL)
- - ArcLuna<GameObject>::push(lu, pGo);
- + ArcSole<GameObject>::push(lu, pGo);
- else
- - ArcLuna<GameObject>::push(L, pGo);
- + ArcSole<GameObject>::push(L, pGo);
- }
- void LuaEngine::PushItem(Object* item, lua_State* L)
- {
- @@ -586,9 +586,9 @@
- RegisterGlobalFunctions(lu);
- - ArcLuna<Unit>::Register(lu);
- + ArcSole<Unit>::Register(lu);
- ArcLuna<Item>::Register(lu);
- - ArcLuna<GameObject>::Register(lu);
- + ArcSole<GameObject>::Register(lu);
- ArcLuna<WorldPacket>::Register(lu);
- ArcLuna<TaxiPath>::Register(lu);
- ArcLuna<Spell>::Register(lu);
- Index: src/scripts/src/LuaEngine/LUAEngine.h
- ===================================================================
- --- src/scripts/src/LuaEngine/LUAEngine.h (revision 4445)
- +++ src/scripts/src/LuaEngine/LUAEngine.h (working copy)
- @@ -301,13 +301,13 @@
- //Wrappers
- ARCEMU_INLINE Unit* CheckUnit(lua_State* L, int narg)
- {
- - if(L == NULL) return ArcLuna<Unit>::check(lu, narg);
- - else return ArcLuna<Unit>::check(L, narg);
- + if(L == NULL) return ArcSole<Unit>::check(lu, narg);
- + else return ArcSole<Unit>::check(L, narg);
- }
- ARCEMU_INLINE GameObject* CheckGo(lua_State* L, int narg)
- {
- - if(L == NULL) return ArcLuna<GameObject>::check(lu, narg);
- - else return ArcLuna<GameObject>::check(L, narg);
- + if(L == NULL) return ArcSole<GameObject>::check(lu, narg);
- + else return ArcSole<GameObject>::check(L, narg);
- }
- ARCEMU_INLINE Item* CheckItem(lua_State* L, int narg)
- {
- @@ -326,8 +326,8 @@
- }
- ARCEMU_INLINE Object* CheckObject(lua_State* L, int narg)
- {
- - if(L == NULL) return ArcLuna<Object>::check(lu, narg);
- - else return ArcLuna<Object>::check(L, narg);
- + if(L == NULL) return ArcSole<Object>::check(lu, narg);
- + else return ArcSole<Object>::check(L, narg);
- }
- ARCEMU_INLINE TaxiPath* CheckTaxiPath(lua_State* L, int narg)
- {
- @@ -775,6 +775,205 @@
- return 1;
- }
- };
- +
- + //As opposed to ArcLuna, this is meant to bring some light to this Lua Engine plagued by crashes since r1, caused by pushing on the stack Object*
- + //references that could point to free'd memory. It will push object* (and derived types) as guid + mapid + instanceid.
- + template <typename T>
- + class ArcSole
- + {
- + private:
- + uint64 guid;
- + uint32 mapId;
- + int32 instanceId;
- +
- + T* Get()
- + {
- + Object* object = NULL;
- + MapMgr* mapMgr = sInstanceMgr.GetMapMgr(mapId);
- + if(mapMgr == NULL)
- + {
- + //if mapMgr is NULL then it's probably an instance
- + Instance * instance = sInstanceMgr.GetInstanceByIds(mapId, instanceId);
- + if(instance != NULL)
- + object = instance->m_mapMgr->_GetObject(guid);
- + }
- + else
- + object = mapMgr->_GetObject(guid);
- + return TO<T*>(object);
- + }
- + public:
- + typedef int (*mfp)(lua_State *L, T* ptr);
- + typedef struct { const char *name; mfp mfunc; } RegType;
- +
- + static void Register(lua_State *L)
- + {
- + lua_newtable(L);
- + int methods = lua_gettop(L);
- +
- + luaL_newmetatable(L, GetTClassName<T>());
- + int metatable = lua_gettop(L);
- +
- + luaL_newmetatable(L,"DO NOT TRASH");
- + lua_pop(L,1);
- +
- + // store method table in globals so that
- + // scripts can add functions written in Lua.
- + lua_pushvalue(L, methods);
- + lua_setglobal(L,GetTClassName<T>());
- +
- + // hide metatable from Lua getmetatable()
- + lua_pushvalue(L, methods);
- + lua_setfield(L, metatable, "__metatable");
- +
- + lua_pushcfunction(L,index);
- + lua_setfield(L, metatable, "__index");
- +
- + lua_pushcfunction(L, tostring_T);
- + lua_setfield(L, metatable, "__tostring");
- +
- + //nil gc method because world will take care of created Objects
- + lua_pushnil(L);
- + lua_setfield(L, metatable, "__gc");
- +
- + lua_newtable(L); // mt for method table
- + lua_setmetatable(L, methods);
- +
- + // fill method table with methods from class T
- + for (RegType *l = ((RegType*)GetMethodTable<T>()); l->name; l++)
- + {
- + lua_pushstring(L, l->name);
- + lua_pushlightuserdata(L, (void*)l);
- + lua_pushcclosure(L, thunk, 1);
- + lua_settable(L, methods);
- + }
- + lua_pop(L, 2); // drop metatable and method table
- + }
- +
- + // push onto the Lua stack a userdata containing a pointer to T object
- + static int push(lua_State *L, T *obj, bool gc=false)
- + {
- + if(obj == NULL)
- + {
- + lua_pushnil(L);
- + return lua_gettop(L);
- + }
- +
- + luaL_getmetatable(L, GetTClassName<T>()); // lookup metatable in Lua registry
- + if (lua_isnil(L, -1)) luaL_error(L, "%s missing metatable", GetTClassName<T>());
- + int mt = lua_gettop(L);
- + ArcSole* holder = TO<ArcSole*>(lua_newuserdata(L,sizeof(ArcSole)));
- + int ud = lua_gettop(L);
- + if(holder != NULL)
- + {
- + holder->guid = obj->GetGUID();
- + holder->mapId = obj->GetMapId();
- + holder->instanceId = obj->GetInstanceID();
- +
- + lua_pushvalue(L, mt);
- + lua_setmetatable(L, -2);
- + char name[32];
- + tostring(name,obj);
- + lua_getfield(L,LUA_REGISTRYINDEX,"DO NOT TRASH");
- + if(lua_isnil(L,-1) )
- + {
- + luaL_newmetatable(L,"DO NOT TRASH");
- + lua_pop(L,1);
- + }
- + lua_getfield(L,LUA_REGISTRYINDEX,"DO NOT TRASH");
- + if(gc == false)
- + {
- + lua_pushboolean(L,1);
- + lua_setfield(L,-2,name);
- + }
- + lua_pop(L,1);
- + }
- + lua_settop(L,ud);
- + lua_replace(L, mt);
- + lua_settop(L, mt);
- + return mt; // index of userdata containing pointer to T object
- + }
- +
- + // get userdata from Lua stack and return pointer to T object
- + static T *check(lua_State *L, int narg)
- + {
- + ArcSole* holder = TO<ArcSole*>(lua_touserdata(L,narg));
- + if(holder == NULL)
- + return NULL;
- + return holder->Get();
- + }
- +
- + private:
- + // member function dispatcher
- + static int thunk(lua_State *L)
- + {
- + // stack has userdata, followed by method args
- + T *obj = check(L, 1); // get 'self', or if you prefer, 'this'
- + lua_remove(L, 1); // remove self so member function args start at index 1
- + // get member function from upvalue
- + RegType *l = static_cast<RegType*>(lua_touserdata(L, lua_upvalueindex(1)));
- + //return (obj->*(l->mfunc))(L); // call member function
- + return l->mfunc(L,obj);
- + }
- +
- + static int tostring_T (lua_State *L)
- + {
- + char buff[32];
- + T ** ptrHold = (T**)lua_touserdata(L,1);
- + T *obj = *ptrHold;
- + sprintf(buff, "%p", obj);
- + lua_pushfstring(L, "%s (%s)", GetTClassName<T>(), buff);
- + return 1;
- + }
- + ARCEMU_INLINE static void tostring(char * buff,void * obj)
- + {
- + sprintf(buff,"%p",obj);
- + }
- + static int index(lua_State * L)
- + {
- + /*Paroxysm : the table obj and the missing key are currently on the stack(index 1 & 2) */
- + lua_getglobal(L,GetTClassName<T>());
- + // string form of the key.
- + const char * key = lua_tostring(L,2);
- + if(lua_istable(L,-1) )
- + {
- + lua_pushvalue(L,2);
- + lua_rawget(L,-2);
- + //If the key were looking for is not in the table, retrieve its' metatables' index value.
- + if(lua_isnil(L,-1))
- + {
- + lua_getmetatable(L,-2);
- + if(lua_istable(L,-1) )
- + {
- + lua_getfield(L,-1,"__index");
- + if(lua_isfunction(L,-1) )
- + {
- + lua_pushvalue(L,1);
- + lua_pushvalue(L,2);
- + lua_pcall(L,2,1,0);
- + }
- + else if(lua_istable(L,-1) )
- + lua_getfield(L,-1,key);
- + else
- + lua_pushnil(L);
- + }
- + else
- + lua_pushnil(L);
- + }
- + else if(lua_istable(L,-1) )
- + {
- + lua_pushvalue(L,2);
- + lua_rawget(L,-2);
- + }
- + }
- + else
- + lua_pushnil(L);
- +
- + lua_insert(L,1);
- + lua_settop(L,1);
- + return 1;
- + }
- + };
- +
- class GUID_MGR
- {
- static const char* GetName() { return "WoWGUID"; }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement