From ddef13c674f0bd042bda50ead70a56ff25d75502 Mon Sep 17 00:00:00 2001 From: Dave Schuyler Date: Thu, 9 Jun 2005 04:00:28 +0000 Subject: [PATCH] set location for quests --- direct/src/distributed/DoCollectionManager.py | 725 +++++++++--------- 1 file changed, 368 insertions(+), 357 deletions(-) diff --git a/direct/src/distributed/DoCollectionManager.py b/direct/src/distributed/DoCollectionManager.py index 7f163914fa..e51c13c1f3 100755 --- a/direct/src/distributed/DoCollectionManager.py +++ b/direct/src/distributed/DoCollectionManager.py @@ -1,357 +1,368 @@ -#hack: -BAD_DO_ID = BAD_ZONE_ID = -1 - -class DoCollectionManager: - def __init__(self): - # Dict of {DistributedObject ids : DistributedObjects} - self.doId2do = {} - if wantOtpServer: - # Dict of { - # parent DistributedObject id: - # { zoneIds : [child DistributedObject ids] }} - self.__doHierarchy = {} - - def doFind(self, str): - """ - Returns list of distributed objects with matching str in value. - """ - for value in self.doId2do.values(): - if `value`.find(str) >= 0: - return value - - def doFindAll(self, str): - """ - Returns list of distributed objects with matching str in value. - """ - matches = [] - for value in self.doId2do.values(): - if `value`.find(str) >= 0: - matches.append(value) - return matches - - def getDoHierarchy(self): - return self.__doHierarchy - - if __debug__: - def printObjects(self): - format="%10s %10s %10s %30s %20s" - title=format%("parentId", "zoneId", "doId", "dclass", "name") - print title - print '-'*len(title) - for distObj in self.doId2do.values(): - print format%( - distObj.__dict__.get("parentId"), - distObj.__dict__.get("zoneId"), - distObj.__dict__.get("doId"), - distObj.dclass.getName(), - distObj.__dict__.get("name")) - - def getDoList(self, parentId, zoneId=None, classType=None): - """ - parentId is any distributed object id. - zoneId is a uint32, defaults to None (all zones). Try zone 2 if - you're not sure which zone to use (0 is a bad/null zone and - 1 has had reserved use in the past as a no messages zone, while - 2 has traditionally been a global, uber, misc stuff zone). - dclassType is a distributed class type filter, defaults - to None (no filter). - - If dclassName is None then all objects in the zone are returned; - otherwise the list is filtered to only include objects of that type. - """ - parent=self.__doHierarchy.get(parentId) - if parent is None: - return [] - if zoneId is None: - r = [] - for zone in parent.values(): - for obj in zone: - r.append(obj) - else: - r = parent.get(zoneId, []) - if classType is not None: - a = [] - for obj in r: - if isinstance(obj, classType): - a.append(obj) - r = a - return r - - def countObjects(self, classType): - """ - Counts the number of objects of the given type in the - repository (for testing purposes) - """ - count = 0; - for dobj in self.doId2do.values(): - if isinstance(dobj, classType): - count += 1 - return count - - - def getAllOfType(self, type): - # Returns a list of all DistributedObjects in the repository - # of a particular type. - result = [] - for obj in self.doId2do.values(): - if isinstance(obj, type): - result.append(obj) - return result - - def findAnyOfType(self, type): - # Searches the repository for any object of the given type. - for obj in self.doId2do.values(): - if isinstance(obj, type): - return obj - return None - - #---------------------------------- - - def deleteDistributedObjects(self): - # Get rid of all the distributed objects - for doId in self.doId2do.keys(): - # Look up the object - do = self.doId2do[doId] - self.deleteDistObject(do) - - # Get rid of everything that manages distributed objects - self.deleteObjects() - - # the zoneId2doIds table should be empty now - if len(self.zoneId2doIds) > 0: - AIRepository.notify.warning( - 'zoneId2doIds table not empty: %s' % self.zoneId2doIds) - self.zoneId2doIds = {} - - if wantOtpServer: - def handleObjectLocation(self, di): - # CLIENT_OBJECT_LOCATION - doId = di.getUint32() - parentId = di.getUint32() - zoneId = di.getUint32() - obj = self.doId2do.get(doId) - if obj is not None: - self.notify.info( - "handleObjectLocation: doId: %s parentId: %s zoneId: %s"% - (doId, parentId, zoneId)) - # Let the object finish the job - obj.setLocation(parentId, zoneId) - self.storeObjectLocation(doId, parentId, zoneId) - else: - self.notify.warning( - "handleObjectLocation: Asked to update non-existent obj: %s" % (doId)) - - def storeObjectLocation(self, doId, parentId, zoneId): - if (parentId is None) or (zoneId is None): - # Do not store null values - return - # TODO: check current location - obj = self.doId2do.get(doId) - oldParentId = obj.parentId - oldZoneId = obj.zoneId - - if oldParentId != parentId: - # Remove old location - parentZoneDict = self.__doHierarchy.get(oldParentId) - if parentZoneDict is not None: - zoneDoSet = parentZoneDict.get(oldZoneId) - if zoneDoSet is not None and doId in zoneDoSet: - zoneDoSet.remove(doId) - if len(zoneDoSet) == 0: - del parentZoneDict[oldZoneId] - # Add to new location - parentZoneDict = self.__doHierarchy.setdefault(parentId, {}) - zoneDoSet = parentZoneDict.setdefault(zoneId, set()) - zoneDoSet.add(doId) - - ## if oldParentId == parentId: - ## # Case 1: Same parent, new zone - ## parentZoneDict = self.__doHierarchy.setdefault(parentId, {}) - ## # Remove this doId from the old zone list - ## zoneDoSet = parentZoneDict.setdefault(oldZoneId, set()) - ## if doId in zoneDoSet: - ## zoneDoSet.remove(doId) - ## # Add it to the new zone list - ## zoneDoSet = parentZoneDict.setdefault(zoneId, {}) - ## zoneDoSet[doId] = None - ## ## if zoneDoSet is None: - ## ## # No existing objList for this zone, let's make a new one - ## ## parentZoneDict[zoneId] = [doId] - ## ## else: - ## ## # Just add this doId to the existing list - ## ## assert(doId not in objList) - ## ## zoneDoSet.append(doId) - ## else: - ## # Case 2: New parent, valid old parent - ## if (oldParentId is not None) and (oldZoneId is not None): - ## # First delete the old location - ## self.deleteObjectLocation(doId, oldParentId, oldZoneId) - ## # Case 2: continued, already deleted from old location - ## # Case 3: New parent - no old parent - ## parentZoneDict = self.__doHierarchy.setdefault(parentId, {}) - ## zoneDoSet = parentZoneDict.setdefault(zoneId, {}) - ## zoneDoSet[doId] = None - ## ## if parentZoneDict is None: - ## ## # This parent is not here, just fill the whole entry in - ## ## self.__doHierarchy[parentId] = {zoneId : {doId: None}} - ## ## else: - ## ## zoneDoSet = parentZoneDict.setdefault(zoneId, {}) - ## ## zoneDoSet[doId] = None - ## ## objList = parentZoneDict.get(zoneId) - ## ## if objList is None: - ## ## # This parent has no objects in this zone before - ## ## # create a new entry for this zone and list this doId - ## ## parentZoneDict[zoneId] = {doId: None} - ## ## else: - ## ## assert doId not in objList - ## ## # Just add this doId to the existing list - ## ## objList[doId] = None - - def deleteObjectLocation(self, objId, parentId, zoneId): - # Do not worry about null values - if ((parentId is None) or (zoneId is None)): - return - parentZoneDict = self.__doHierarchy.get(parentId) - assert(parentZoneDict is not None, "deleteObjectLocation: parentId: %s not found" % (parentId)) - objList = parentZoneDict.get(zoneId) - assert(objList is not None, "deleteObjectLocation: zoneId: %s not found" % (zoneId)) - assert(objId in objList, "deleteObjectLocation: objId: %s not found" % (objId)) - if len(objList) == 1: - # If this is the last obj in this zone, delete the entire entry - del parentZoneDict[zoneId] - else: - # Just remove the object - objList.remove(objId) - - if wantOtpServer: - def addDOToTables(self, do, location=None): - assert self.notify.debugStateCall(self) - if location is None: - location = (do.parentId, do.zoneId) - - assert do.doId not in self.doId2do - self.doId2do[do.doId]=do - - if location is not None: - assert do.doId not in self.zoneId2doIds.get(location,{}) - self.zoneId2doIds.setdefault(location, {}) - self.zoneId2doIds[location][do.doId]=do - else: - # NON OTP - def addDOToTables(self, do, zoneId=None): - assert self.notify.debugStateCall(self) - if zoneId is None: - zoneId = do.zoneId - - assert do.doId not in self.doId2do - self.doId2do[do.doId]=do - - if zoneId is not None: - assert do.doId not in self.zoneId2doIds.get(zoneId,{}) - self.zoneId2doIds.setdefault(zoneId, {}) - self.zoneId2doIds[zoneId][do.doId]=do - - if wantOtpServer: - def removeDOFromTables(self, do): - assert self.notify.debugStateCall(self) - assert do.doId in self.doId2do - location = do.getLocation() - if location is not None: - if location not in self.zoneId2doIds: - AIRepository.notify.warning( - 'dobj %s (%s) has invalid location: %s' % - (do, do.doId, location)) - else: - assert do.doId in self.zoneId2doIds[location] - del(self.zoneId2doIds[location][do.doId]) - if len(self.zoneId2doIds[location]) == 0: - del self.zoneId2doIds[location] - - del(self.doId2do[do.doId]) - else: - def removeDOFromTables(self, do): - assert self.notify.debugStateCall(self) - assert do.doId in self.doId2do - if do.zoneId is not None: - if do.zoneId not in self.zoneId2doIds: - AIRepository.notify.warning( - 'dobj %s (%s) has invalid zoneId: %s' % - (do, do.doId, do.zoneId)) - else: - assert do.doId in self.zoneId2doIds[do.zoneId] - del(self.zoneId2doIds[do.zoneId][do.doId]) - if len(self.zoneId2doIds[do.zoneId]) == 0: - del self.zoneId2doIds[do.zoneId] - - del(self.doId2do[do.doId]) - - if wantOtpServer: - def changeDOZoneInTables(self, do, newParentId, newZoneId, oldParentId, oldZoneId): - oldLocation = (oldParentId, oldZoneId) - newLocation = (newParentId, newZoneId) - # HACK: DistributedGuildMemberUD starts in -1,-1, which isnt ever put in the - # zoneId2doIds table - if oldLocation != (BAD_DO_ID, BAD_ZONE_ID): - assert self.notify.debugStateCall(self) - assert oldLocation in self.zoneId2doIds - assert do.doId in self.zoneId2doIds[oldLocation] - assert do.doId not in self.zoneId2doIds.get(newLocation,{}) - # remove from old zone - del(self.zoneId2doIds[oldLocation][do.doId]) - if len(self.zoneId2doIds[oldLocation]) == 0: - del self.zoneId2doIds[oldLocation] - # add to new zone - self.zoneId2doIds.setdefault(newLocation, {}) - self.zoneId2doIds[newLocation][do.doId]=do - - def getObjectsInZone(self, location): - """ 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(location, {})) - - def getObjectsOfClassInZone(self, location, objClass): - """ returns dict of doId:object for a zone, containing all objects - that inherit from 'class'. returned dict is safely mutable. """ - assert self.notify.debugStateCall(self) - doDict = {} - for doId, do in self.zoneId2doIds.get(location, {}).items(): - if isinstance(do, objClass): - doDict[doId] = do - return doDict - - else: - # NON OTP - - def changeDOZoneInTables(self, do, newZoneId, oldZoneId): - ##print "changeDOZoneInTables:%s, dclass:%s, newZoneId:%s OldZoneId:%s"%(do.doId, do.dclass.getName(), newZoneId,oldZoneId); - - assert self.notify.debugStateCall(self) - assert oldZoneId in self.zoneId2doIds - assert do.doId in self.zoneId2doIds[oldZoneId] - assert do.doId not in self.zoneId2doIds.get(newZoneId,{}) - # remove from old zone - del(self.zoneId2doIds[oldZoneId][do.doId]) - if len(self.zoneId2doIds[oldZoneId]) == 0: - del self.zoneId2doIds[oldZoneId] - # add to new zone - self.zoneId2doIds.setdefault(newZoneId, {}) - self.zoneId2doIds[newZoneId][do.doId]=do - - def getObjectsInZone(self, 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(zoneId, {})) - - def getObjectsOfClassInZone(self, zoneId, objClass): - """ returns dict of doId:object for a zone, containing all objects - that inherit from 'class'. returned dict is safely mutable. """ - assert self.notify.debugStateCall(self) - doDict = {} - for doId, do in self.zoneId2doIds.get(zoneId, {}).items(): - if isinstance(do, objClass): - doDict[doId] = do - return doDict +#hack: +BAD_DO_ID = BAD_ZONE_ID = -1 + +class DoCollectionManager: + def __init__(self): + # Dict of {DistributedObject ids : DistributedObjects} + self.doId2do = {} + if wantOtpServer: + # Dict of { + # parent DistributedObject id: + # { zoneIds : [child DistributedObject ids] }} + self.__doHierarchy = {} + + def doFind(self, str): + """ + Returns list of distributed objects with matching str in value. + """ + for value in self.doId2do.values(): + if `value`.find(str) >= 0: + return value + + def doFindAll(self, str): + """ + Returns list of distributed objects with matching str in value. + """ + matches = [] + for value in self.doId2do.values(): + if `value`.find(str) >= 0: + matches.append(value) + return matches + + def getDoHierarchy(self): + return self.__doHierarchy + + if __debug__: + def printObjects(self): + format="%10s %10s %10s %30s %20s" + title=format%("parentId", "zoneId", "doId", "dclass", "name") + print title + print '-'*len(title) + for distObj in self.doId2do.values(): + print format%( + distObj.__dict__.get("parentId"), + distObj.__dict__.get("zoneId"), + distObj.__dict__.get("doId"), + distObj.dclass.getName(), + distObj.__dict__.get("name")) + + def getDoList(self, parentId, zoneId=None, classType=None): + """ + parentId is any distributed object id. + zoneId is a uint32, defaults to None (all zones). Try zone 2 if + you're not sure which zone to use (0 is a bad/null zone and + 1 has had reserved use in the past as a no messages zone, while + 2 has traditionally been a global, uber, misc stuff zone). + dclassType is a distributed class type filter, defaults + to None (no filter). + + If dclassName is None then all objects in the zone are returned; + otherwise the list is filtered to only include objects of that type. + """ + parent=self.__doHierarchy.get(parentId) + if parent is None: + return [] + if zoneId is None: + r = [] + for zone in parent.values(): + for obj in zone: + r.append(obj) + else: + r = parent.get(zoneId, []) + if classType is not None: + a = [] + for obj in r: + if isinstance(obj, classType): + a.append(obj) + r = a + return r + + def countObjects(self, classType): + """ + Counts the number of objects of the given type in the + repository (for testing purposes) + """ + count = 0; + for dobj in self.doId2do.values(): + if isinstance(dobj, classType): + count += 1 + return count + + + def getAllOfType(self, type): + # Returns a list of all DistributedObjects in the repository + # of a particular type. + result = [] + for obj in self.doId2do.values(): + if isinstance(obj, type): + result.append(obj) + return result + + def findAnyOfType(self, type): + # Searches the repository for any object of the given type. + for obj in self.doId2do.values(): + if isinstance(obj, type): + return obj + return None + + #---------------------------------- + + def deleteDistributedObjects(self): + # Get rid of all the distributed objects + for doId in self.doId2do.keys(): + # Look up the object + do = self.doId2do[doId] + self.deleteDistObject(do) + + # Get rid of everything that manages distributed objects + self.deleteObjects() + + # the zoneId2doIds table should be empty now + if len(self.zoneId2doIds) > 0: + AIRepository.notify.warning( + 'zoneId2doIds table not empty: %s' % self.zoneId2doIds) + self.zoneId2doIds = {} + + if wantOtpServer: + def handleObjectLocation(self, di): + # CLIENT_OBJECT_LOCATION + doId = di.getUint32() + parentId = di.getUint32() + zoneId = di.getUint32() + obj = self.doId2do.get(doId) + if obj is not None: + self.notify.info( + "handleObjectLocation: doId: %s parentId: %s zoneId: %s"% + (doId, parentId, zoneId)) + # Let the object finish the job + obj.setLocation(parentId, zoneId) + self.storeObjectLocation(doId, parentId, zoneId) + else: + self.notify.warning( + "handleObjectLocation: Asked to update non-existent obj: %s" % (doId)) + + def handleSetLocation(self, di): + # This was initially added because creating a distributed quest + # object would cause a message like this to be generated. + assert self.notify.debugStateCall(self) + parentId = di.getUint32() + zoneId = di.getUint32() + distObj = self.doId2do.get(self.getMsgChannel()) + if distObj is not None: + distObj.setLocation(parentId, zoneId) + + def storeObjectLocation(self, doId, parentId, zoneId): + if (parentId is None) or (zoneId is None): + # Do not store null values + return + # TODO: check current location + obj = self.doId2do.get(doId) + if obj is not None: + oldParentId = obj.parentId + oldZoneId = obj.zoneId + + if oldParentId != parentId: + # Remove old location + parentZoneDict = self.__doHierarchy.get(oldParentId) + if parentZoneDict is not None: + zoneDoSet = parentZoneDict.get(oldZoneId) + if zoneDoSet is not None and doId in zoneDoSet: + zoneDoSet.remove(doId) + if len(zoneDoSet) == 0: + del parentZoneDict[oldZoneId] + # Add to new location + parentZoneDict = self.__doHierarchy.setdefault(parentId, {}) + zoneDoSet = parentZoneDict.setdefault(zoneId, set()) + zoneDoSet.add(doId) + + ## if oldParentId == parentId: + ## # Case 1: Same parent, new zone + ## parentZoneDict = self.__doHierarchy.setdefault(parentId, {}) + ## # Remove this doId from the old zone list + ## zoneDoSet = parentZoneDict.setdefault(oldZoneId, set()) + ## if doId in zoneDoSet: + ## zoneDoSet.remove(doId) + ## # Add it to the new zone list + ## zoneDoSet = parentZoneDict.setdefault(zoneId, {}) + ## zoneDoSet[doId] = None + ## ## if zoneDoSet is None: + ## ## # No existing objList for this zone, let's make a new one + ## ## parentZoneDict[zoneId] = [doId] + ## ## else: + ## ## # Just add this doId to the existing list + ## ## assert(doId not in objList) + ## ## zoneDoSet.append(doId) + ## else: + ## # Case 2: New parent, valid old parent + ## if (oldParentId is not None) and (oldZoneId is not None): + ## # First delete the old location + ## self.deleteObjectLocation(doId, oldParentId, oldZoneId) + ## # Case 2: continued, already deleted from old location + ## # Case 3: New parent - no old parent + ## parentZoneDict = self.__doHierarchy.setdefault(parentId, {}) + ## zoneDoSet = parentZoneDict.setdefault(zoneId, {}) + ## zoneDoSet[doId] = None + ## ## if parentZoneDict is None: + ## ## # This parent is not here, just fill the whole entry in + ## ## self.__doHierarchy[parentId] = {zoneId : {doId: None}} + ## ## else: + ## ## zoneDoSet = parentZoneDict.setdefault(zoneId, {}) + ## ## zoneDoSet[doId] = None + ## ## objList = parentZoneDict.get(zoneId) + ## ## if objList is None: + ## ## # This parent has no objects in this zone before + ## ## # create a new entry for this zone and list this doId + ## ## parentZoneDict[zoneId] = {doId: None} + ## ## else: + ## ## assert doId not in objList + ## ## # Just add this doId to the existing list + ## ## objList[doId] = None + + def deleteObjectLocation(self, objId, parentId, zoneId): + # Do not worry about null values + if ((parentId is None) or (zoneId is None)): + return + parentZoneDict = self.__doHierarchy.get(parentId) + assert(parentZoneDict is not None, "deleteObjectLocation: parentId: %s not found" % (parentId)) + objList = parentZoneDict.get(zoneId) + assert(objList is not None, "deleteObjectLocation: zoneId: %s not found" % (zoneId)) + assert(objId in objList, "deleteObjectLocation: objId: %s not found" % (objId)) + if len(objList) == 1: + # If this is the last obj in this zone, delete the entire entry + del parentZoneDict[zoneId] + else: + # Just remove the object + objList.remove(objId) + + if wantOtpServer: + def addDOToTables(self, do, location=None): + assert self.notify.debugStateCall(self) + if location is None: + location = (do.parentId, do.zoneId) + + assert do.doId not in self.doId2do + self.doId2do[do.doId]=do + + if location is not None: + assert do.doId not in self.zoneId2doIds.get(location,{}) + self.zoneId2doIds.setdefault(location, {}) + self.zoneId2doIds[location][do.doId]=do + else: + # NON OTP + def addDOToTables(self, do, zoneId=None): + assert self.notify.debugStateCall(self) + if zoneId is None: + zoneId = do.zoneId + + assert do.doId not in self.doId2do + self.doId2do[do.doId]=do + + if zoneId is not None: + assert do.doId not in self.zoneId2doIds.get(zoneId,{}) + self.zoneId2doIds.setdefault(zoneId, {}) + self.zoneId2doIds[zoneId][do.doId]=do + + if wantOtpServer: + def removeDOFromTables(self, do): + assert self.notify.debugStateCall(self) + assert do.doId in self.doId2do + location = do.getLocation() + if location is not None: + if location not in self.zoneId2doIds: + AIRepository.notify.warning( + 'dobj %s (%s) has invalid location: %s' % + (do, do.doId, location)) + else: + assert do.doId in self.zoneId2doIds[location] + del(self.zoneId2doIds[location][do.doId]) + if len(self.zoneId2doIds[location]) == 0: + del self.zoneId2doIds[location] + + del(self.doId2do[do.doId]) + else: + def removeDOFromTables(self, do): + assert self.notify.debugStateCall(self) + assert do.doId in self.doId2do + if do.zoneId is not None: + if do.zoneId not in self.zoneId2doIds: + AIRepository.notify.warning( + 'dobj %s (%s) has invalid zoneId: %s' % + (do, do.doId, do.zoneId)) + else: + assert do.doId in self.zoneId2doIds[do.zoneId] + del(self.zoneId2doIds[do.zoneId][do.doId]) + if len(self.zoneId2doIds[do.zoneId]) == 0: + del self.zoneId2doIds[do.zoneId] + + del(self.doId2do[do.doId]) + + if wantOtpServer: + def changeDOZoneInTables(self, do, newParentId, newZoneId, oldParentId, oldZoneId): + oldLocation = (oldParentId, oldZoneId) + newLocation = (newParentId, newZoneId) + # HACK: DistributedGuildMemberUD starts in -1,-1, which isnt ever put in the + # zoneId2doIds table + if oldLocation != (BAD_DO_ID, BAD_ZONE_ID): + assert self.notify.debugStateCall(self) + assert oldLocation in self.zoneId2doIds + assert do.doId in self.zoneId2doIds[oldLocation] + assert do.doId not in self.zoneId2doIds.get(newLocation,{}) + # remove from old zone + del(self.zoneId2doIds[oldLocation][do.doId]) + if len(self.zoneId2doIds[oldLocation]) == 0: + del self.zoneId2doIds[oldLocation] + # add to new zone + self.zoneId2doIds.setdefault(newLocation, {}) + self.zoneId2doIds[newLocation][do.doId]=do + + def getObjectsInZone(self, location): + """ 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(location, {})) + + def getObjectsOfClassInZone(self, location, objClass): + """ returns dict of doId:object for a zone, containing all objects + that inherit from 'class'. returned dict is safely mutable. """ + assert self.notify.debugStateCall(self) + doDict = {} + for doId, do in self.zoneId2doIds.get(location, {}).items(): + if isinstance(do, objClass): + doDict[doId] = do + return doDict + + else: + # NON OTP + + def changeDOZoneInTables(self, do, newZoneId, oldZoneId): + ##print "changeDOZoneInTables:%s, dclass:%s, newZoneId:%s OldZoneId:%s"%(do.doId, do.dclass.getName(), newZoneId,oldZoneId); + + assert self.notify.debugStateCall(self) + assert oldZoneId in self.zoneId2doIds + assert do.doId in self.zoneId2doIds[oldZoneId] + assert do.doId not in self.zoneId2doIds.get(newZoneId,{}) + # remove from old zone + del(self.zoneId2doIds[oldZoneId][do.doId]) + if len(self.zoneId2doIds[oldZoneId]) == 0: + del self.zoneId2doIds[oldZoneId] + # add to new zone + self.zoneId2doIds.setdefault(newZoneId, {}) + self.zoneId2doIds[newZoneId][do.doId]=do + + def getObjectsInZone(self, 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(zoneId, {})) + + def getObjectsOfClassInZone(self, zoneId, objClass): + """ returns dict of doId:object for a zone, containing all objects + that inherit from 'class'. returned dict is safely mutable. """ + assert self.notify.debugStateCall(self) + doDict = {} + for doId, do in self.zoneId2doIds.get(zoneId, {}).items(): + if isinstance(do, objClass): + doDict[doId] = do + return doDict