| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359 |
- #hack:
- BAD_DO_ID = BAD_ZONE_ID = 0xFFFFFFFF
- BAD_CHANNEL_ID = 0xFFFFFFFFFFFFFFFF
- class DoCollectionManager:
- def __init__(self):
- # Dict of {DistributedObject ids : DistributedObjects}
- self.doId2do = {}
- # (parentId, zoneId) to dict of doId->DistributedObjectAI
- ## self.zoneId2doIds={}
- if self.hasOwnerView():
- # Dict of {DistributedObject ids : DistributedObjects} for 'owner' views of objects
- self.doId2ownerView = {}
- # Dict of {
- # parent DistributedObject id:
- # { zoneIds : [child DistributedObject ids] }}
- self.__doHierarchy = {}
- def getDo(self, doId):
- return self.doId2do.get(doId)
- def getOwnerView(self, doId):
- assert self.hasOwnerView()
- return self.doId2ownerView.get(doId)
- def getDoTable(self, ownerView):
- if ownerView:
- assert self.hasOwnerView()
- return self.doId2ownerView
- else:
- return self.doId2do
- 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.
- """
- return [self.doId2do.get(i)
- for i in self.getDoIdList(parentId, zoneId, classType)]
- def getDoIdList(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 getOwnerViewDoList(self, classType):
- assert self.hasOwnerView()
- l = []
- for obj in self.doId2ownerView.values():
- if isinstance(obj, classType):
- l.append(obj)
- return l
- def getOwnerViewDoIdList(self, classType):
- assert self.hasOwnerView()
- l = []
- for doId, obj in self.doId2ownerView.items():
- if isinstance(obj, classType):
- l.append(doId)
- return l
- 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.__doHierarchy) > 0:
- self.notify.warning(
- '__doHierarchy table not empty: %s' % self.__doHierarchy)
- self.__doHierarchy = {}
- 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.debug(
- "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):
- obj = self.doId2do.get(doId)
- if obj is not None:
- oldParentId = obj.parentId
- oldZoneId = obj.zoneId
- if oldParentId != parentId:
- # Remove old location
- self.deleteObjectLocation(doId, oldParentId, oldZoneId)
- if oldParentId == parentId and oldZoneId == zoneId:
- # object is already at that parent and zone
- return
- if (parentId is None) or (zoneId is None):
- # Do not store null values
- return
- # Add to new location
- parentZoneDict = self.__doHierarchy.setdefault(parentId, {})
- zoneDoSet = parentZoneDict.setdefault(zoneId, set())
- zoneDoSet.add(doId)
-
- # Set the new parent and zone on the object
- obj.parentId = parentId
- obj.zoneId = zoneId
-
- if 1:
- # Do we still need this
- if oldParentId != parentId:
- # Give the parent a chance to run code when a new child
- # sets location to it. For example, the parent may want to
- # scene graph reparent the child to some subnode it owns.
- parentObj = self.doId2do.get(parentId)
- if parentObj is not None:
- parentObj.handleChildArrive(obj, zoneId)
- def deleteObjectLocation(self, doId, parentId, zoneId):
- # Do not worry about null values
- if (parentId is None) or (zoneId is None):
- return
- if 1:
- # Do we still need this
-
- # notify any existing parent that we're moving away
- oldParentObj = self.doId2do.get(parentId)
- obj = self.doId2do.get(doId)
- if oldParentObj is not None and obj is not None:
- oldParentObj.handleChildLeave(obj, zoneId)
- parentZoneDict = self.__doHierarchy.get(parentId)
- if parentZoneDict is not None:
- zoneDoSet = parentZoneDict.get(zoneId)
- if zoneDoSet is not None:
- if doId in zoneDoSet:
- zoneDoSet.remove(doId)
- if len(zoneDoSet) == 0:
- del parentZoneDict[zoneId]
- else:
- self.notify.warning(
- "deleteObjectLocation: objId: %s not found"%(doId,))
- else:
- self.notify.warning(
- "deleteObjectLocation: zoneId: %s not found"%(zoneId,))
- else:
- self.notify.warning(
- "deleteObjectLocation: parentId: %s not found"%(parentId,))
-
- def addDOToTables(self, do, location=None, ownerView=False):
- assert self.notify.debugStateCall(self)
- #assert not hasattr(do, "isQueryAllResponse") or not do.isQueryAllResponse
- if not ownerView:
- if location is None:
- location = (do.parentId, do.zoneId)
- doTable = self.getDoTable(ownerView)
- # make sure the object is not already present
- if do.doId in doTable:
- if ownerView:
- tableName = 'doId2ownerView'
- else:
- tableName = 'doId2do'
- self.notify.error('doId %s already in %s [%s stomping %s]' % (
- do.doId, tableName, do.__class__.__name__,
- doTable[do.doId].__class__.__name__))
- doTable[do.doId]=do
- if not ownerView:
- if self.isValidLocationTuple(location):
- self.storeObjectLocation(do.doId, location[0], location[1])
- ##assert do.doId not in self.zoneId2doIds.get(location,{})
- ##self.zoneId2doIds.setdefault(location, {})
- ##self.zoneId2doIds[location][do.doId]=do
- def isValidLocationTuple(self, location):
- return (location is not None
- and location != (0xffffffff, 0xffffffff)
- and location != (0, 0))
- def removeDOFromTables(self, do):
- assert self.notify.debugStateCall(self)
- #assert not hasattr(do, "isQueryAllResponse") or not do.isQueryAllResponse
- #assert do.doId in self.doId2do
- self.deleteObjectLocation(do.doId, do.parentId, do.zoneId)
- ## location = do.getLocation()
- ## if location is not None:
- ## if location not in self.zoneId2doIds:
- ## self.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]
- if do.doId in self.doId2do:
- del self.doId2do[do.doId]
-
- ## def changeDOZoneInTables(self, do, newParentId, newZoneId, oldParentId, oldZoneId):
- ## if 1:
- ## self.storeObjectLocation(do.doId, newParentId, newZoneId)
- ## else:
- ## #assert not hasattr(do, "isQueryAllResponse") or not do.isQueryAllResponse
- ## oldLocation = (oldParentId, oldZoneId)
- ## newLocation = (newParentId, newZoneId)
- ## # HACK: DistributedGuildMemberUD starts in -1,-1, which isnt ever put in the
- ## # zoneId2doIds table
- ## if self.isValidLocationTuple(oldLocation):
- ## 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]
- ## if self.isValidLocationTuple(newLocation):
- ## # add to new zone
- ## 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 getObjectsOfClassInZone(self, parentId, 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 in self.getDoIdList(parentId, zoneId, objClass):
- if isinstance(do, objClass):
- doDict[doId] = self.doId2do.get(do)
- return doDict
|