From: <go...@us...> - 2002-09-16 19:17:09
|
Update of /cvsroot/decaldev/source/DecalFilters In directory usw-pr-cvs1:/tmp/cvs-serv950/DecalFilters Modified Files: World.cpp World.h Log Message: Modified to use the new ACHooks ObjectDestroyed event to determine when to clean up lists. This should help reduce both memory usage and lag. Index: World.cpp =================================================================== RCS file: /cvsroot/decaldev/source/DecalFilters/World.cpp,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** World.cpp 31 Jul 2002 02:29:01 -0000 1.39 --- World.cpp 16 Sep 2002 19:17:04 -0000 1.40 *************** *** 6,13 **** --- 6,25 ---- #include "WorldObject.h" #include "WorldIterator.h" + #include <time.h> #include <stdio.h> #include <math.h> + + const IID EVTID_AcHooks = { + 0xEB282FE5, 0x7170, 0x4a37, {0xA2, 0x6E, 0x92, 0xAF, 0x36, 0x38, 0x5D, 0x2C}} ; + + const IID LIBID_Decal = { + 0xFF7F5F6D, 0x34E0, 0x4B6F, {0xB3, 0xBB, 0x81, 0x41, 0xDE, 0x2E, 0xF7, 0x32}} ; + + const IID IID_Plugins = { + 0x702D3901, 0xC13A, 0x448e, {0x88, 0x71, 0xEC, 0xDC, 0x8B, 0xC8, 0xD0, 0x79}} ; + + ///////////////////////////////////////////////////////////////////////////// // cWorld *************** *** 117,120 **** --- 129,133 ---- { m_nNextTime = 0; + m_HookIsSet = false ; }; *************** *** 126,133 **** --- 139,193 ---- + void cWorld::SetHook() + { + CComPtr< IDecal > pDecal; + HRESULT hr = m_pService->get_Decal( &pDecal ); + if (SUCCEEDED(hr)) { + _DebugLog("\nGotDecal") ; + CComPtr< IInjectService > pInject; + HRESULT hr = pDecal->get_Object ( _bstr_t ( _T( "services\\DecalPlugins.InjectService" ) ), + __uuidof ( IInjectService ), reinterpret_cast< LPVOID * > ( &pInject ) ); + + if (SUCCEEDED(hr)) { + _DebugLog("\nGot Inject") ; + pInject->get_Site(&m_pPluginSite); + if (SUCCEEDED(hr)) { + _DebugLog("\nGot PluginSite") ; + hr = m_pPluginSite->get_Hooks(&m_pHooks) ; + if (SUCCEEDED(hr)) { + _DebugLog("\nGot Hooks") ; + IACHooksEventsImpl<HookDestroyObj, cWorld>::advise(m_pHooks) ; + m_HookIsSet = true ; + } else { + _DebugLog("\nFailed Get Hooks %x", hr) ; + } + } else { + _DebugLog("\nFailed to get PluginSite %x", hr) ; + } + } else { + _DebugLog("\nFailed to get Inject %x", hr) ; + } + } else { + _DebugLog("\nFailed to get Decal %x", hr) ; + } + } + + HRESULT cWorld::onTerminate() { _DebugLog("OnTerminate") ; _DebugLog("CLOSEFILE") ; + if (m_HookIsSet) { + IACHooksEventsImpl<HookDestroyObj, cWorld>::unadvise(m_pPluginSite) ; + if (m_pHooks!=NULL) { + m_pHooks.Release() ; + m_pHooks = NULL ; + } + if (m_pPluginSite!=NULL) { + m_pPluginSite.Release() ; + m_pPluginSite = NULL ; + } + m_HookIsSet = false ; + } return S_OK; } *************** *** 147,150 **** --- 207,223 ---- // Gouru: reset the player so next login the player gets updated... m_objects.player(0) ; + + if (m_HookIsSet) { + IACHooksEventsImpl<HookDestroyObj, cWorld>::unadvise(m_pPluginSite) ; + if (m_pHooks!=NULL) { + m_pHooks.Release() ; + m_pHooks = NULL ; + } + if (m_pPluginSite!=NULL) { + m_pPluginSite.Release() ; + m_pPluginSite = NULL ; + } + m_HookIsSet = false ; + } } *************** *** 178,182 **** } ! ReleaseAllPendingObjects() ; return S_OK; --- 251,255 ---- } ! // ReleaseAllPendingObjects() ; return S_OK; *************** *** 226,255 **** void cWorld::ReleaseAllPendingObjects() { ! if (m_nNextTime <= time(NULL)) ! { ! cWorldData *pData = NULL; ! ! for (cWorldDataMap::iterator iData = m_objects.begin(); iData != m_objects.end();) ! { ! pData = iData->second; ! ! if (pData && pData->m_tExpires && pData->m_tExpires <= time(NULL)) ! { ! _DebugLog("\nReleased object %x", pData->m_dwGUID) ; ! cWorldDataMap::iterator iSkip = iData; ! ! Fire_ReleaseObject(pData->m_p); ! ! iSkip++; ! m_objects.erase(pData->m_dwGUID); ! delete pData; ! iData = iSkip; ! } ! else ! ++iData; ! } ! m_nNextTime = time(NULL) + 5; // 5 seconds until next check } } --- 299,343 ---- void cWorld::ReleaseAllPendingObjects() { ! // if (m_nNextTime <= time(NULL)) ! // { ! // cWorldData *pData = NULL; ! // ! // for (cWorldDataMap::iterator iData = m_objects.begin(); iData != m_objects.end();) ! // { ! // pData = iData->second; ! // ! // if (pData && pData->m_tExpires && pData->m_tExpires <= time(NULL)) ! // { ! // _DebugLog("\nReleased object %x", pData->m_dwGUID) ; ! // cWorldDataMap::iterator iSkip = iData; ! // iSkip++; ! // ! // DestroyObject(pData) ; ! // ! // iData = iSkip; ! // } ! // else ! // ++iData; ! // } ! // m_nNextTime = time(NULL) + 5; // 5 seconds until next check ! // } ! } ! void cWorld::DestroyObject(cWorldData* pData) ! { ! _DebugLog("\nDestroyObject: %x", pData->m_dwGUID) ; ! ! if (pData->m_dwGUID != m_objects.player()) { ! _DebugLog(" : ReleaseObject") ; ! Fire_ReleaseObject(pData->m_p); ! _DebugLog(" : MoveSlotBack") ; ! MoveSlotBack(pData); ! ! _DebugLog(" : erase") ; ! m_objects.erase(pData->m_dwGUID); ! ! _DebugLog(" : delete") ; ! delete pData; } } *************** *** 390,407 **** void cWorld::DoDestroyObj(CComPtr< IMessageIterator > pMembers) { ! long nDestroyed; ! pMembers->get_NextInt(strdestroyed, &nDestroyed); ! _DebugLog("\n\nDestroyObj %x", nDestroyed) ; ! ! if (nDestroyed == m_objects.player()) return ; ! ! if (cWorldData *pData = Data(nDestroyed)) ! { ! Fire_ReleaseObject(pData->m_p); ! MoveSlotBack(pData); ! ! m_objects.erase(m_objects.find(nDestroyed)); ! delete pData; ! } } --- 478,490 ---- void cWorld::DoDestroyObj(CComPtr< IMessageIterator > pMembers) { ! // long nDestroyed; ! // pMembers->get_NextInt(strdestroyed, &nDestroyed); ! // _DebugLog("\n\nDestroyObj %x", nDestroyed) ; ! // ! // // if we know about this object ! // if (cWorldData *pData = Data(nDestroyed)) { ! // // remove it ! // DestroyObject(pData) ; ! // } } *************** *** 623,626 **** --- 706,712 ---- { _DebugLog("\n\nLogin") ; + if (!m_HookIsSet) { + SetHook() ; + } CComPtr<IMessageIterator> pItems, pItem; long nCount, ixSlot = 0, ixPack=0 ; *************** *** 1015,1034 **** void cWorld::DoRemoveItem(CComPtr<IMessageIterator> pMembers) { ! long nObject; ! pMembers->get_NextInt(strobject, &nObject); ! ! _DebugLog("\n\nRemoveItem %x", nObject) ; ! ! // never remove yourself ! if (nObject == m_objects.player()) return ; ! ! // don't remove it if we don't have a record of it ! if (cWorldData *pData = Data(nObject)) ! { ! Fire_ReleaseObject(pData->m_p); ! ! m_objects.erase(m_objects.find(nObject)); ! delete pData; ! } } --- 1101,1113 ---- void cWorld::DoRemoveItem(CComPtr<IMessageIterator> pMembers) { ! // long nObject; ! // pMembers->get_NextInt(strobject, &nObject); ! // ! // _DebugLog("\n\nRemoveItem %x", nObject) ; ! // ! // // don't remove it if we don't have a record of it ! // if (cWorldData *pData = Data(nObject)) { ! // DestroyObject(pData) ; ! // } } *************** *** 1058,1070 **** bool cWorld::OutsideCullDistance(cWorldData* data, long row, long col) { ! _DebugLog("\nCull Distance %d-%d, %d-%d", data->m_LandblockRow, row, ! data->m_LandblockCol, col) ; ! long x = abs(data->m_LandblockRow-row) ; ! long y = abs(data->m_LandblockCol-col) ; ! if (x>2 || y>2) { ! _DebugLog(" <true>") ; ! return true ; ! } ! _DebugLog(" <false>") ; return false ; } --- 1137,1150 ---- bool cWorld::OutsideCullDistance(cWorldData* data, long row, long col) { ! // _DebugLog("\nCull Distance %d-%d, %d-%d", data->m_LandblockRow, row, ! // data->m_LandblockCol, col) ; ! // long x = abs(data->m_LandblockRow-row) ; ! // long y = abs(data->m_LandblockCol-col) ; ! // if (x>2 || y>2) { ! // _DebugLog(" <true>") ; ! // return true ; ! // } ! // _DebugLog(" <false>") ; ! // return false ; return false ; } *************** *** 1076,1080 **** // Gouru: not normally logged as we get an S load of these messages, uncomment if you // really need it for testing... ! _DebugLog("\nSetObjectPosition %x", nObject) ; cWorldData *pData = Data(nObject); --- 1156,1160 ---- // Gouru: not normally logged as we get an S load of these messages, uncomment if you // really need it for testing... ! // _DebugLog("\nSetObjectPosition %x", nObject) ; cWorldData *pData = Data(nObject); *************** *** 1088,1099 **** pPos->get_NextInt(strlandblock, (long *)&dwLandblock); ! long oldLandblock = pData->m_dwLandblock ; ! long colLandblock = (dwLandblock>>24) & 0xff ; ! long rowLandblock = (dwLandblock>>16) & 0xff ; // store landblock and landblock h/v values so we don't have to recalculate them // everytime since we do this a lot pData->m_dwLandblock = dwLandblock; ! pData->m_LandblockCol = colLandblock ; ! pData->m_LandblockRow = rowLandblock ; pPos->get_NextFloat(strxOffset, &pData->m_fxOffset); pPos->get_NextFloat(stryOffset, &pData->m_fyOffset); --- 1168,1179 ---- pPos->get_NextInt(strlandblock, (long *)&dwLandblock); ! // long oldLandblock = pData->m_dwLandblock ; ! // long colLandblock = (dwLandblock>>24) & 0xff ; ! // long rowLandblock = (dwLandblock>>16) & 0xff ; // store landblock and landblock h/v values so we don't have to recalculate them // everytime since we do this a lot pData->m_dwLandblock = dwLandblock; ! pData->m_LandblockCol = (dwLandblock>>24) & 0xff ; ! pData->m_LandblockRow = (dwLandblock>>16) & 0xff ; pPos->get_NextFloat(strxOffset, &pData->m_fxOffset); pPos->get_NextFloat(stryOffset, &pData->m_fyOffset); *************** *** 1104,1177 **** // If moving object is player, and player changed landblocks... // if the object changed landblocks ! if (HIWORD(oldLandblock) != HIWORD(pData->m_dwLandblock)) { ! if (nObject == m_objects.player()) { ! _DebugLog("\n\nPlayer changed landblock!") ; ! // If the moving object was the player, scan all items and tag those ! // too far away with an expiration time ! for (cWorldDataMap::iterator i = m_objects.begin(); i != m_objects.end(); i++) ! { ! cWorldData *pObject = i->second; ! if (!pObject) { ! continue ; // can't process if we don't have the object... ! } ! ! // get the outmost container of this object, its landblock is used in ! // distance checking... ! cWorldData *pLbData = OuterContainer(pObject) ; ! ! // if the object moving is the player, or carried by the player ! // dont process it, it should not be culled ! if (pLbData->m_dwGUID == m_objects.player()) { ! _DebugLog("\nplayerobj: %x", pObject->m_dwGUID) ; ! continue ; ! } ! ! #ifdef LOGGING ! if (pLbData != pObject) { ! _DebugLog("object %x contained in %x", ! pObject->m_dwGUID, pLbData->m_dwGUID) ; ! } ! #endif ! // if the object is outside the culling distance ! if (OutsideCullDistance(pLbData, rowLandblock, colLandblock)) { ! // if the item is not already tagged, tag it to expire in 30 seconds ! if (!pObject->m_tExpires) { ! _DebugLog("\nculling %x", pObject->m_dwGUID) ; ! pObject->m_tExpires = time(NULL)+30 ; ! Fire_ChangeObject(pObject->m_p, strReleasePending); ! } else { ! _DebugLog("\n%x already tagged", pObject->m_dwGUID) ; ! } ! } else if (pObject->m_tExpires) { ! // else it is inside the culling distance and if tagged to expire ! // cance the expiration ! _DebugLog("\ncancelled cull %x", pObject->m_dwGUID) ; ! pObject->m_tExpires = 0 ; ! Fire_ChangeObject(pObject->m_p, strExpirationCancel); ! } ! } ! } else { ! _DebugLog("\n\nItem %x changed landblock!", nObject) ; ! // object is not a player, tag it to expire if it has moved to far away ! cWorldData* pLbData = OuterContainer(pData) ; ! cWorldData* pPlayer = Data(m_objects.player()) ; ! if ( OutsideCullDistance(pPlayer, pLbData->m_LandblockRow, pLbData->m_LandblockCol)){ ! // if not already tagged, tag it to expire ! if (!pData->m_tExpires) { ! _DebugLog("\nculling %x", pData->m_dwGUID) ; ! pData->m_tExpires = time(NULL) + 30 ; ! Fire_ChangeObject(pData->m_p, strReleasePending); ! } else { ! _DebugLog("%x already tagged", pData->m_dwGUID) ; ! } ! } else if (pData->m_tExpires) { ! _DebugLog("\ncancelled cull %x", pData->m_dwGUID) ; ! // else it is inside the culling distance and if tagged to expire ! // cancel the expiration ! pData->m_tExpires = 0 ; ! Fire_ChangeObject(pData->m_p, strExpirationCancel); ! } ! } ! } pData->m_flags |= FLAG_LOCATION; Fire_ChangeObject(pData->m_p, strLocationChange); --- 1184,1257 ---- // If moving object is player, and player changed landblocks... // if the object changed landblocks ! // if (HIWORD(oldLandblock) != HIWORD(pData->m_dwLandblock)) { ! // if (nObject == m_objects.player()) { ! // _DebugLog("\n\nPlayer changed landblock!") ; ! // // If the moving object was the player, scan all items and tag those ! // // too far away with an expiration time ! // for (cWorldDataMap::iterator i = m_objects.begin(); i != m_objects.end(); i++) ! // { ! // cWorldData *pObject = i->second; ! // if (!pObject) { ! // continue ; // can't process if we don't have the object... ! // } ! // ! // // get the outmost container of this object, its landblock is used in ! // // distance checking... ! // cWorldData *pLbData = OuterContainer(pObject) ; ! // ! // // if the object moving is the player, or carried by the player ! // // dont process it, it should not be culled ! // if (pLbData->m_dwGUID == m_objects.player()) { ! // _DebugLog("\nplayerobj: %x", pObject->m_dwGUID) ; ! // continue ; ! // } ! // ! //#ifdef LOGGING ! // if (pLbData != pObject) { ! // _DebugLog("object %x contained in %x", ! // pObject->m_dwGUID, pLbData->m_dwGUID) ; ! // } ! //#endif ! // // if the object is outside the culling distance ! // if (OutsideCullDistance(pLbData, rowLandblock, colLandblock)) { ! // // if the item is not already tagged, tag it to expire in 30 seconds ! // if (!pObject->m_tExpires) { ! // _DebugLog("\nculling %x", pObject->m_dwGUID) ; ! // pObject->m_tExpires = time(NULL)+30 ; ! // Fire_ChangeObject(pObject->m_p, strReleasePending); ! // } else { ! // _DebugLog("\n%x already tagged", pObject->m_dwGUID) ; ! // } ! // } else if (pObject->m_tExpires) { ! // // else it is inside the culling distance and if tagged to expire ! // // cance the expiration ! // _DebugLog("\ncancelled cull %x", pObject->m_dwGUID) ; ! // pObject->m_tExpires = 0 ; ! // Fire_ChangeObject(pObject->m_p, strExpirationCancel); ! // } ! // } ! // } else { ! // _DebugLog("\n\nItem %x changed landblock!", nObject) ; ! // // object is not a player, tag it to expire if it has moved to far away ! // cWorldData* pLbData = OuterContainer(pData) ; ! // cWorldData* pPlayer = Data(m_objects.player()) ; ! // if ( OutsideCullDistance(pPlayer, pLbData->m_LandblockRow, pLbData->m_LandblockCol)){ ! // // if not already tagged, tag it to expire ! // if (!pData->m_tExpires) { ! // _DebugLog("\nculling %x", pData->m_dwGUID) ; ! // pData->m_tExpires = time(NULL) + 30 ; ! // Fire_ChangeObject(pData->m_p, strReleasePending); ! // } else { ! // _DebugLog("%x already tagged", pData->m_dwGUID) ; ! // } ! // } else if (pData->m_tExpires) { ! // _DebugLog("\ncancelled cull %x", pData->m_dwGUID) ; ! // // else it is inside the culling distance and if tagged to expire ! // // cancel the expiration ! // pData->m_tExpires = 0 ; ! // Fire_ChangeObject(pData->m_p, strExpirationCancel); ! // } ! // } ! // } pData->m_flags |= FLAG_LOCATION; Fire_ChangeObject(pData->m_p, strLocationChange); *************** *** 1283,1286 **** --- 1363,1379 ---- + void cWorld::onObjectDestroyed(long nId) + { + _DebugLog("\nonObjectDestroyed %x", nId) ; + // if we know about this object + if (cWorldData *pData = Data(nId)) { + bool IsPlayer = pData->m_eType==ePlayer ; + // remove it + DestroyObject(pData) ; + if (IsPlayer) { + _DebugLog("\n Remove wielded items") ; + } + } + } #ifdef Logging Index: World.h =================================================================== RCS file: /cvsroot/decaldev/source/DecalFilters/World.h,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** World.h 1 Aug 2002 15:01:56 -0000 1.29 --- World.h 16 Sep 2002 19:17:05 -0000 1.30 *************** *** 7,10 **** --- 7,11 ---- #include "DecalNetImpl.h" #include "WorldObject.h" + #include "..\inject\inject.h" #include <deque> *************** *** 12,15 **** --- 13,30 ---- //#define Logging 1 + #define HookDestroyObj 101 + + extern const IID EVTID_AcHooks ; + + // Template class used to connect ACHooks events + template<UINT nID, class cImpl >class IACHooksEventsImpl + :public IDispEventImpl<nID, cImpl, &EVTID_AcHooks, + &LIBID_Decal, 1, 0 > + { + public: HRESULT advise(IUnknown *pUnk){return DispEventAdvise(pUnk);} + HRESULT unadvise(IUnknown *pUnk){return DispEventUnadvise(pUnk);} + }; + + // Gouru: added structure to store slot and slot type. Containers have two types of slots // we need to track, slots than can contain other containers, and slots that contain items *************** *** 160,163 **** --- 175,179 ---- public IDispatchImpl<IWorld, &IID_IWorld, &LIBID_DecalFilters>, public IProvideClassInfo2Impl<&CLSID_World, &DIID_IWorldEvents, &LIBID_DecalFilters>, + public IACHooksEventsImpl<HookDestroyObj, cWorld>, public INetworkFilterImpl<cWorld>, public CProxyIWorldEvents<cWorld> *************** *** 184,187 **** --- 200,207 ---- END_CONNECTION_POINT_MAP() + BEGIN_SINK_MAP(cWorld) + SINK_ENTRY_EX(HookDestroyObj, EVTID_AcHooks, 1, onObjectDestroyed) + END_SINK_MAP() + public: cWorldData *Data(DWORD nGuid); *************** *** 193,199 **** bool OutsideCullDistance(cWorldData* data, long row, long col) ; cWorldData* OuterContainer(cWorldData* obj) ; ! void FreeData(); void ReleaseAllPendingObjects() ; // AC message handlers --- 213,221 ---- bool OutsideCullDistance(cWorldData* data, long row, long col) ; cWorldData* OuterContainer(cWorldData* obj) ; ! void DestroyObject(cWorldData* pData) ; ! void FreeData(); void ReleaseAllPendingObjects() ; + void SetHook() ; // AC message handlers *************** *** 224,227 **** --- 246,254 ---- long m_nNextTime; + bool m_HookIsSet ; + CComPtr<IPluginSite> m_pPluginSite ; + CComPtr< IACHooks > m_pHooks ; + + void _stdcall onObjectDestroyed(long nId); public: |