|
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:
|