IntervalManager.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. from pandac.PandaModules import *
  2. from pandac import PandaModules
  3. from direct.directnotify.DirectNotifyGlobal import *
  4. from direct.showbase import EventManager
  5. import Interval
  6. import types
  7. import fnmatch
  8. class IntervalManager(CIntervalManager):
  9. # This is a Python-C++ hybrid class. IntervalManager is a Python
  10. # extension of the C++ class CIntervalManager; the main purpose of
  11. # the Python extensions is to add support for Python-based
  12. # intervals (like MetaIntervals).
  13. if PandaModules.__dict__.has_key("Dtool_PyNavtiveInterface"):
  14. def __init__(self, globalPtr = 0):
  15. # Pass globalPtr == 1 to the constructor to trick it into
  16. # "constructing" a Python wrapper around the global
  17. # CIntervalManager object.
  18. ##self.cObj = CIntervalManager.getGlobalPtr()
  19. ##Dtool_BarrowThisRefrence(self,self.cObj)
  20. ##self.dd = self
  21. if globalPtr:
  22. self.cObj = CIntervalManager.getGlobalPtr()
  23. Dtool_BarrowThisRefrence(self,self.cObj)
  24. self.dd = self
  25. else:
  26. CIntervalManager.__init__(self)
  27. self.eventQueue = EventQueue()
  28. self.MyEventmanager = EventManager.EventManager(self.eventQueue)
  29. self.setEventQueue(self.eventQueue)
  30. self.ivals = []
  31. self.removedIvals = {}
  32. else: ## the old interface
  33. def __init__(self, globalPtr = 0):
  34. # Pass globalPtr == 1 to the constructor to trick it into
  35. # "constructing" a Python wrapper around the global
  36. # CIntervalManager object.
  37. if globalPtr:
  38. #CIntervalManager.__init__(self, None)
  39. cObj = CIntervalManager.getGlobalPtr()
  40. self.this = cObj.this
  41. self.userManagesMemory = 0
  42. else:
  43. CIntervalManager.__init__(self)
  44. # Set up a custom event queue for handling C++ events from
  45. # intervals.
  46. self.eventQueue = EventQueue()
  47. self.MyEventmanager = EventManager.EventManager(self.eventQueue)
  48. self.setEventQueue(self.eventQueue)
  49. self.ivals = []
  50. self.removedIvals = {}
  51. def addInterval(self, interval):
  52. index = self.addCInterval(interval, 1)
  53. self.__storeInterval(interval, index)
  54. def removeInterval(self, interval):
  55. index = self.findCInterval(interval.getName())
  56. if index >= 0:
  57. self.removeCInterval(index)
  58. self.ivals[index] = None
  59. return 1
  60. return 0
  61. def getInterval(self, name):
  62. index = self.findCInterval(name)
  63. if index >= 0:
  64. return self.ivals[index]
  65. return None
  66. def finishIntervalsMatching(self, pattern):
  67. count = 0
  68. maxIndex = self.getMaxIndex()
  69. for index in range(maxIndex):
  70. ival = self.getCInterval(index)
  71. if ival and \
  72. fnmatch.fnmatchcase(ival.getName(), pattern):
  73. # Finish and remove this interval. Finishing it
  74. # automatically removes it.
  75. count += 1
  76. if self.ivals[index]:
  77. # Finish the python version if we have it
  78. self.ivals[index].finish()
  79. else:
  80. # Otherwise, it's a C-only interval.
  81. ival.finish()
  82. return count
  83. def step(self):
  84. # This method should be called once per frame to perform all
  85. # of the per-frame processing on the active intervals.
  86. # Call C++ step, then do the Python stuff.
  87. CIntervalManager.step(self)
  88. self.__doPythonCallbacks()
  89. def interrupt(self):
  90. # This method should be called during an emergency cleanup
  91. # operation, to automatically pause or finish all active
  92. # intervals tagged with autoPause or autoFinish set true.
  93. # Call C++ interrupt, then do the Python stuff.
  94. CIntervalManager.interrupt(self)
  95. self.__doPythonCallbacks()
  96. def __doPythonCallbacks(self):
  97. # This method does all of the required Python post-processing
  98. # after performing some C++-level action.
  99. # It is important to call all of the python callbacks on the
  100. # just-removed intervals before we call any of the callbacks
  101. # on the still-running intervals.
  102. index = self.getNextRemoval()
  103. while index >= 0:
  104. # We have to clear the interval first before we call
  105. # privPostEvent() on it, because the interval might itself
  106. # try to add a new interval.
  107. ival = self.ivals[index]
  108. self.ivals[index] = None
  109. ival.privPostEvent()
  110. index = self.getNextRemoval()
  111. index = self.getNextEvent()
  112. while index >= 0:
  113. self.ivals[index].privPostEvent()
  114. index = self.getNextEvent()
  115. # Finally, throw all the events on the custom event queue.
  116. # These are the done events that may have been generated in
  117. # C++. We use a custom event queue so we can service all of
  118. # these immediately, rather than waiting for the global event
  119. # queue to be serviced (which might not be till next frame).
  120. self.MyEventmanager.doEvents()
  121. def __storeInterval(self, interval, index):
  122. while index >= len(self.ivals):
  123. self.ivals.append(None)
  124. assert(self.ivals[index] == None or self.ivals[index] == interval)
  125. self.ivals[index] = interval
  126. #def __repr__(self):
  127. # return self.__str__()
  128. # The global IntervalManager object.
  129. ivalMgr = IntervalManager(1)