CRCache.py 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. """CRCache module: contains the CRCache class"""
  2. from direct.directnotify import DirectNotifyGlobal
  3. import DistributedObject
  4. class CRCache:
  5. notify = DirectNotifyGlobal.directNotify.newCategory("CRCache")
  6. def __init__(self, maxCacheItems=10):
  7. self.maxCacheItems = maxCacheItems
  8. self.dict = {}
  9. self.fifo = []
  10. def isEmpty(self):
  11. return len(self.fifo) == 0
  12. def flush(self):
  13. """
  14. Delete each item in the cache then clear all references to them
  15. """
  16. assert self.checkCache()
  17. CRCache.notify.debug("Flushing the cache")
  18. for distObj in self.dict.values():
  19. distObj.deleteOrDelay()
  20. # Null out all references to the objects so they will get gcd
  21. self.dict = {}
  22. self.fifo = []
  23. def cache(self, distObj):
  24. # Only distributed objects are allowed in the cache
  25. assert isinstance(distObj, DistributedObject.DistributedObject)
  26. assert self.checkCache()
  27. # Get the doId
  28. doId = distObj.getDoId()
  29. # Error check
  30. if self.dict.has_key(doId):
  31. CRCache.notify.warning("Double cache attempted for distObj "
  32. + str(doId))
  33. else:
  34. # Call disable on the distObj
  35. distObj.disableAndAnnounce()
  36. # Put the distObj in the fifo and the dict
  37. self.fifo.append(distObj)
  38. self.dict[doId] = distObj
  39. if len(self.fifo) > self.maxCacheItems:
  40. # if the cache is full, pop the oldest item
  41. oldestDistObj = self.fifo.pop(0)
  42. # and remove it from the dictionary
  43. del(self.dict[oldestDistObj.getDoId()])
  44. # and delete it
  45. oldestDistObj.deleteOrDelay()
  46. # Make sure that the fifo and the dictionary are sane
  47. assert len(self.dict) == len(self.fifo)
  48. def retrieve(self, doId):
  49. assert self.checkCache()
  50. if self.dict.has_key(doId):
  51. # Find the object
  52. distObj = self.dict[doId]
  53. # Remove it from the dictionary
  54. del(self.dict[doId])
  55. # Remove it from the fifo
  56. self.fifo.remove(distObj)
  57. # return the distObj
  58. return distObj
  59. else:
  60. # If you can't find it, return None
  61. return None
  62. def contains(self, doId):
  63. return self.dict.has_key(doId)
  64. def delete(self, doId):
  65. assert self.checkCache()
  66. assert self.dict.has_key(doId)
  67. # Look it up
  68. distObj = self.dict[doId]
  69. # Remove it from the dict and fifo
  70. del(self.dict[doId])
  71. self.fifo.remove(distObj)
  72. # and delete it
  73. distObj.deleteOrDelay()
  74. def checkCache(self):
  75. # For debugging; this verifies that the cache is sensible and
  76. # returns true if so.
  77. from pandac.PandaModules import NodePath
  78. for obj in self.dict.values():
  79. if isinstance(obj, NodePath):
  80. assert not obj.isEmpty() and obj.getTopNode() != render.node()
  81. return 1