Browse Source

added InterestWatcher

Darren Ranalli 19 years ago
parent
commit
26eca10a19

+ 10 - 6
direct/src/distributed/DoCollectionManager.py

@@ -373,12 +373,16 @@ class DoCollectionManager:
     ##             self.zoneId2doIds.setdefault(newLocation, {})
     ##             self.zoneId2doIds.setdefault(newLocation, {})
     ##             self.zoneId2doIds[newLocation][do.doId]=do
     ##             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):
     def getObjectsOfClassInZone(self, parentId, zoneId, objClass):
         """
         """

+ 13 - 0
direct/src/distributed/DoInterestManager.py

@@ -78,6 +78,8 @@ class DoInterestManager(DirectObject.DirectObject):
     def __init__(self):
     def __init__(self):
         assert DoInterestManager.notify.debugCall()
         assert DoInterestManager.notify.debugCall()
         DirectObject.DirectObject.__init__(self)
         DirectObject.DirectObject.__init__(self)
+        self._addInterestEvent = uniqueName('DoInterestManager-Add')
+        self._removeInterestEvent = uniqueName('DoInterestManager-Remove')
 
 
     def addInterest(self, parentId, zoneIdList, description, event=None):
     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' % (
             print 'INTEREST DEBUG: addInterest(): handle=%s, parent=%s, zoneIds=%s, description=%s, event=%s' % (
                 handle, parentId, zoneIdList, description, event)
                 handle, parentId, zoneIdList, description, event)
         self._sendAddInterest(handle, scopeId, parentId, zoneIdList, description)
         self._sendAddInterest(handle, scopeId, parentId, zoneIdList, description)
+        if event:
+            messenger.send(self._getAddInterestEvent(), [event])
         assert self.printInterestsIfDebug()
         assert self.printInterestsIfDebug()
         return handle
         return handle
 
 
@@ -115,6 +119,9 @@ class DoInterestManager(DirectObject.DirectObject):
         if DoInterestManager._interests.has_key(handle):
         if DoInterestManager._interests.has_key(handle):
             existed = True
             existed = True
             intState = DoInterestManager._interests[handle]
             intState = DoInterestManager._interests[handle]
+            if event:
+                messenger.send(self._getRemoveInterestEvent(),
+                               [event, intState.parentId, intState.zoneIdList])
             if intState.isPendingDelete():
             if intState.isPendingDelete():
                 self.notify.warning(
                 self.notify.warning(
                     'removeInterest: interest %s already pending removal' %
                     'removeInterest: interest %s already pending removal' %
@@ -184,6 +191,12 @@ class DoInterestManager(DirectObject.DirectObject):
                 "alterInterest: handle not found: %s" % (handle))
                 "alterInterest: handle not found: %s" % (handle))
         return exists
         return exists
 
 
+    # events for InterestWatcher
+    def _getAddInterestEvent(self):
+        return self._addInterestEvent
+    def _getRemoveInterestEvent(self):
+        return self._removeInterestEvent
+
     def _getInterestState(self, handle):
     def _getInterestState(self, handle):
         return DoInterestManager._interests[handle]
         return DoInterestManager._interests[handle]
 
 

+ 75 - 0
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))
+            """

+ 7 - 5
direct/src/showbase/EventGroup.py

@@ -45,11 +45,13 @@ class EventGroup(DirectObject.DirectObject):
                 self.addEvent(event)
                 self.addEvent(event)
 
 
     def destroy(self):
     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):
     def getName(self):
         return self._name
         return self._name