Browse Source

*** empty log message ***

Jesse Schell 25 years ago
parent
commit
ef0c3fd0fd

+ 70 - 0
direct/src/distributed/CRCache.py

@@ -0,0 +1,70 @@
+"""CRCache module: contains the CRCache class"""
+
+import DirectNotifyGlobal
+import DistributedObject
+
+class CRCache:
+    notify = DirectNotifyGlobal.directNotify.newCategory("CRCache")
+
+    def __init__(self, maxCacheItems=50):
+        self.maxCacheItems = maxCacheItems
+        self.dict = {}
+        self.fifo = []
+        return None
+
+    def cache(self, distObj):
+        # Only distributed objects are allowed in the cache
+        assert(isinstance(distObj, DistributedObject.DistributedObject))
+        # Get the doId
+        doId = distObj.getDoId()
+        # Error check
+        if self.dict.has_key(doId):
+            CRCache.notify.warning("Double cache attempted for distObj "
+                                   + str(doId))
+        else:
+            # Call disable on the distObj
+            distObj.disable()
+            
+            # Put the distObj in the fifo and the dict
+            self.fifo.append(distObj)
+            self.dict[doId] = distObj
+            
+            if len(self.fifo) > self.maxCacheItems:
+                # if the cache is full, pop the oldest item
+                oldestDistObj = self.fifo.pop(0)
+                # and remove it from the dictionary
+                del(self.dict[oldestDistObj.getDoId()])
+                # and delete it
+                oldestDistObj.delete()
+                
+        # Make sure that the fifo and the dictionary are sane
+        assert(len(self.dict) == len(self.fifo))
+        return None
+
+    def retrieve(self, doId):
+        if self.dict.has_key(doId):
+            # Find the object
+            distObj = self.dict[doId]
+            # Remove it from the dictionary
+            del(self.dict[doId])
+            # Remove it from the fifo
+            self.fifo.remove(distObj)
+            # return the distObj
+            return distObj
+        else:
+            # If you can't find it, return None
+            return None
+
+    def contains(self, doId):
+        return self.dict.has_key(doId)
+    
+    def delete(self, doId):
+        assert(self.dict.has_key(doId))
+        # Look it up
+        distObj = self.dict[doId]
+        # Remove it from the dict and fifo
+        del(self.dict[doId])
+        self.fifo.remove(distObj)
+        # and delete it
+        oldestDistObj.delete()
+        

+ 55 - 5
direct/src/distributed/ClientRepository.py

@@ -6,6 +6,7 @@ from MsgTypes import *
 import Task
 import DirectNotifyGlobal
 import ClientDistClass
+import CRCache
 # The repository must import all known types of Distributed Objects
 import DistributedObject
 import DistributedToon
@@ -21,6 +22,7 @@ class ClientRepository(DirectObject.DirectObject):
         self.doId2do={}
         self.doId2cdc={}
         self.parseDcFile(dcFileName)
+        self.cache=CRCache.CRCache()
         return None
 
     def parseDcFile(self, dcFileName):
@@ -61,7 +63,7 @@ class ClientRepository(DirectObject.DirectObject):
     def readerPollOnce(self):
         availGetVal = self.qcr.dataAvailable()
         if availGetVal:
-            print "Client: Incoming message!"
+            #print "Client: Incoming message!"
             datagram = NetDatagram()
             readRetVal = self.qcr.getData(datagram)
             if readRetVal:
@@ -98,12 +100,24 @@ class ClientRepository(DirectObject.DirectObject):
         # if it is there. The right thing to do would be to update
         # all the required fields, but that will come later, too.
 
+        # Is it in our dictionary? 
         if self.doId2do.has_key(doId):
-            ClientRepository.notify.warning("doId: " +
-                                            str(doId) +
-                                            " was generated again")
+            # If so, just update it.
             distObj = self.doId2do[doId]
             distObj.updateRequiredFields(cdc, di)
+
+        # Is it in the cache? If so, pull it out, put it in the dictionaries,
+        # and update it.
+        elif self.cache.contains(doId):
+            # If so, pull it out of the cache...
+            distObj = self.cache.retrieve(doId)
+            # put it in both dictionaries...
+            self.doId2do[doId] = distObj
+            self.doId2cdc[doId] = cdc
+            # and update it.
+            distObj.updateRequiredFields(cdc, di)
+
+        # If it is not in the dictionary or the cache, then...
         else:
             # Construct a new one
             distObj = constructor(self)
@@ -117,10 +131,46 @@ class ClientRepository(DirectObject.DirectObject):
             
         return distObj
 
+    def handleDisable(self, di):
+        # Get the DO Id
+        doId = di.getArg(STUint32)
+        # Make sure the object exists
+        if self.doId2do.has_key(doId):
+            # Look up the object
+            distObj = self.doId2do[doId]
+            # remove the object from both dictionaries
+            del(self.doId2do[doId])
+            del(self.doId2cdc[doId])
+            assert(len(self.doId2do) == len(self.doId2cdc))
+            # cache the object
+            self.cache.cache(distObj)
+        else:
+            ClientRepository.notify.warning("Disable failed. DistObj " +
+                                            str(doId) +
+                                            " is not in dictionary")
+        return None
+
+    def handleDelete(self, di):
+        # Get the DO Id
+        doId = di.getArg(STUint32)
+        # If it is in the dictionaries, remove it.
+        if self.doId2do.has_key(doId):
+            del(self.doId2do[doId])
+            del(self.doId2cdc[doId])
+            assert(len(self.doId2do) == len(self.doId2cdc))
+        # If it is in the cache, remove it.
+        elif self.cache.contains(doId):
+            self.cache.delete(doId)
+        # Otherwise, ignore it
+        else:
+            ClientRepository.notify.warning(
+                "Asked to delete non-existent DistObj " + str(doId))
+        return None
+
     def handleUpdateField(self, di):
         # Get the DO Id
         doId = di.getArg(STUint32)
-        print("Updating " + str(doId))
+        #print("Updating " + str(doId))
         # Find the DO
         assert(self.doId2do.has_key(doId))
         do = self.doId2do[doId]

+ 4 - 2
direct/src/distributed/DistributedNode.py

@@ -1,5 +1,6 @@
 """DistributedNode module: contains the DistributedNode class"""
 
+from ShowBaseGlobal import *
 import NodePath
 import DistributedObject
 
@@ -14,8 +15,9 @@ class DistributedNode(DistributedObject.DistributedObject, NodePath.NodePath):
             DistributedObject.DistributedObject.__init__(self, cr)
         return None
 
-    def generateInit(self, di):
-        DistributedObject.DistributedObject.generateInit(self, di)
+    def disable(self):
+        self.reparent(hidden)
+        DistributedObject.DistributedObject.disable(self)
 
     def d_setPos(self, x, y, z):
         self.sendUpdate("setPos", [x, y, z])

+ 13 - 1
direct/src/distributed/DistributedObject.py

@@ -1,7 +1,7 @@
 """DistributedObject module: contains the DistributedObject class"""
 
 from PandaObject import *
-from ToonBaseGlobal import *
+#from ToonBaseGlobal import *
 
 class DistributedObject(PandaObject):
     """Distributed Object class:"""
@@ -12,6 +12,18 @@ class DistributedObject(PandaObject):
             self.DistributedObject_initialized = 1
             self.cr = cr
         return None
+
+    def disable(self):
+        """disable(self)
+        Inheritors should redefine this to take appropriate action on disable
+        """
+        pass
+
+    def delete(self):
+        """delete(self)
+        Inheritors should redefine this to take appropriate action on delete
+        """
+        pass
     
     def getDoId(self):
         """getDoId(self)