From 26eca10a196fe14b034ce9dbc55b658f647890f5 Mon Sep 17 00:00:00 2001 From: Darren Ranalli Date: Thu, 4 May 2006 23:21:34 +0000 Subject: [PATCH] added InterestWatcher --- direct/src/distributed/DoCollectionManager.py | 16 ++-- direct/src/distributed/DoInterestManager.py | 13 ++++ direct/src/distributed/InterestWatcher.py | 75 +++++++++++++++++++ direct/src/showbase/EventGroup.py | 12 +-- 4 files changed, 105 insertions(+), 11 deletions(-) create mode 100755 direct/src/distributed/InterestWatcher.py diff --git a/direct/src/distributed/DoCollectionManager.py b/direct/src/distributed/DoCollectionManager.py index e71238cea3..90b50d1af1 100755 --- a/direct/src/distributed/DoCollectionManager.py +++ b/direct/src/distributed/DoCollectionManager.py @@ -373,12 +373,16 @@ class DoCollectionManager: ## self.zoneId2doIds.setdefault(newLocation, {}) ## self.zoneId2doIds[newLocation][do.doId]=do - ## def getObjectsInZone(self, parentId, zoneId): - ## """ call this to get a dict of doId:distObj for a zone. - ## Creates a shallow copy, so you can do whatever you want with the - ## dict. """ - ## assert self.notify.debugStateCall(self) - ## return copy.copy(self.zoneId2doIds.get((parentId, zoneId), {})) + def getObjectsInZone(self, parentId, zoneId): + """ + returns dict of doId:distObj for a zone. + returned dict is safely mutable. + """ + assert self.notify.debugStateCall(self) + doDict = {} + for doId in self.getDoIdList(parentId, zoneId): + doDict[doId] = self.getDo(doId) + return doDict def getObjectsOfClassInZone(self, parentId, zoneId, objClass): """ diff --git a/direct/src/distributed/DoInterestManager.py b/direct/src/distributed/DoInterestManager.py index 7b2fd7ec5c..988c0b18dc 100755 --- a/direct/src/distributed/DoInterestManager.py +++ b/direct/src/distributed/DoInterestManager.py @@ -78,6 +78,8 @@ class DoInterestManager(DirectObject.DirectObject): def __init__(self): assert DoInterestManager.notify.debugCall() DirectObject.DirectObject.__init__(self) + self._addInterestEvent = uniqueName('DoInterestManager-Add') + self._removeInterestEvent = uniqueName('DoInterestManager-Remove') def addInterest(self, parentId, zoneIdList, description, event=None): """ @@ -92,6 +94,8 @@ class DoInterestManager(DirectObject.DirectObject): print 'INTEREST DEBUG: addInterest(): handle=%s, parent=%s, zoneIds=%s, description=%s, event=%s' % ( handle, parentId, zoneIdList, description, event) self._sendAddInterest(handle, scopeId, parentId, zoneIdList, description) + if event: + messenger.send(self._getAddInterestEvent(), [event]) assert self.printInterestsIfDebug() return handle @@ -115,6 +119,9 @@ class DoInterestManager(DirectObject.DirectObject): if DoInterestManager._interests.has_key(handle): existed = True intState = DoInterestManager._interests[handle] + if event: + messenger.send(self._getRemoveInterestEvent(), + [event, intState.parentId, intState.zoneIdList]) if intState.isPendingDelete(): self.notify.warning( 'removeInterest: interest %s already pending removal' % @@ -184,6 +191,12 @@ class DoInterestManager(DirectObject.DirectObject): "alterInterest: handle not found: %s" % (handle)) return exists + # events for InterestWatcher + def _getAddInterestEvent(self): + return self._addInterestEvent + def _getRemoveInterestEvent(self): + return self._removeInterestEvent + def _getInterestState(self, handle): return DoInterestManager._interests[handle] diff --git a/direct/src/distributed/InterestWatcher.py b/direct/src/distributed/InterestWatcher.py new file mode 100755 index 0000000000..2d59d6d99c --- /dev/null +++ b/direct/src/distributed/InterestWatcher.py @@ -0,0 +1,75 @@ +from direct.directnotify.DirectNotifyGlobal import directNotify +from direct.showbase.DirectObject import DirectObject +from direct.showbase.EventGroup import EventGroup + +class InterestWatcher(DirectObject): + """Object that observes all interests adds/removes over a period of time, + and sends out an event when all of those interests have closed""" + notify = directNotify.newCategory('InterestWatcher') + + def __init__(self, interestMgr, name, doneEvent=None, + recurse=True, start=True, mustCollect=False, doCollectionMgr=None): + DirectObject.__init__(self) + self._interestMgr = interestMgr + if doCollectionMgr is None: + doCollectionMgr = interestMgr + self._doCollectionMgr = doCollectionMgr + self._eGroup = EventGroup(name, doneEvent=doneEvent) + self._doneEvent = self._eGroup.getDoneEvent() + self._gotEvent = False + self._recurse = recurse + if self._recurse: + # this will hold a dict of parentId to set(zoneIds) that are closing + self.closingParent2zones = {} + if start: + self.startCollect(mustCollect) + + def startCollect(self, mustCollect=False): + self._mustCollect = mustCollect + + self.accept(self._interestMgr._getAddInterestEvent(), self._handleInterestOpenEvent) + self.accept(self._interestMgr._getRemoveInterestEvent(), self._handleInterestCloseEvent) + + def stopCollect(self): + self.ignore(self._interestMgr._getAddInterestEvent()) + self.ignore(self._interestMgr._getRemoveInterestEvent()) + + mustCollect = self._mustCollect + del self._mustCollect + if not self._gotEvent: + if mustCollect: + logFunc = self.notify.error + else: + logFunc = self.notify.warning + logFunc('%s: empty interest-complete set' % self.getName()) + self.destroy() + else: + self.accept(self.getDoneEvent(), self.destroy) + + def destroy(self): + if hasattr(self, '_eGroup'): + self._eGroup.destroy() + del self._eGroup + del self._gotEvent + del self._interestMgr + self.ignoreAll() + + def getName(self): + return self._eGroup.getName() + def getDoneEvent(self): + return self._doneEvent + + def _handleInterestOpenEvent(self, event): + self._gotEvent = True + self._eGroup.addEvent(event) + def _handleInterestCloseEvent(self, event, parentId, zoneIdList): + self._gotEvent = True + self._eGroup.addEvent(event) + """ + if self._recurse: + # this interest is in the process of closing. If an interest + # underneath any objects in that interest close, we need to know + # about it. + self.closingParent2zones.setdefault(parentId, set()) + self.closingParent2zones[parentId].union(set(zoneIdList)) + """ diff --git a/direct/src/showbase/EventGroup.py b/direct/src/showbase/EventGroup.py index d1090a84fd..85120887e6 100755 --- a/direct/src/showbase/EventGroup.py +++ b/direct/src/showbase/EventGroup.py @@ -45,11 +45,13 @@ class EventGroup(DirectObject.DirectObject): self.addEvent(event) def destroy(self): - del self._name - del self._subEvents - del self._completedEvents - del self._doneEvent - self.ignoreAll() + if hasattr(self, '_name'): + # keep this around + #del self._doneEvent + del self._name + del self._subEvents + del self._completedEvents + self.ignoreAll() def getName(self): return self._name