panda3d/direct/src/interval/IntervalManager.py
2003-06-26 20:01:25 +00:00

135 lines
4.6 KiB
Python

from PandaModules import *
from DirectNotifyGlobal import *
import EventManager
import Interval
import types
import fnmatch
class IntervalManager(CIntervalManager):
# This is a Python-C++ hybrid class. IntervalManager is a Python
# extension of the C++ class CIntervalManager; the main purpose of
# the Python extensions is to add support for Python-based
# intervals (like MetaIntervals).
def __init__(self, globalPtr = 0):
# Pass globalPtr == 1 to the constructor to trick it into
# "constructing" a Python wrapper around the global
# CIntervalManager object.
if globalPtr:
CIntervalManager.__init__(self, None)
cObj = CIntervalManager.getGlobalPtr()
self.this = cObj.this
self.userManagesMemory = 0
else:
CIntervalManager.__init__(self)
# Set up a custom event queue for handling C++ events from
# intervals.
self.eventQueue = EventQueue()
self.eventManager = EventManager.EventManager(self.eventQueue)
self.setEventQueue(self.eventQueue)
self.ivals = []
self.removedIvals = {}
def addInterval(self, interval):
index = self.addCInterval(interval, 1)
self.__storeInterval(interval, index)
def removeInterval(self, interval):
index = self.findCInterval(interval.getName())
if index >= 0:
self.removeCInterval(index)
self.ivals[index] = None
return 1
return 0
def getInterval(self, name):
index = self.findCInterval(name)
if index >= 0:
return self.ivals[index]
return None
def finishIntervalsMatching(self, pattern):
count = 0
maxIndex = self.getMaxIndex()
for index in range(maxIndex):
ival = self.getCInterval(index)
if ival and \
fnmatch.fnmatchcase(ival.getName(), pattern):
# Finish and remove this interval. Finishing it
# automatically removes it.
count += 1
if self.ivals[index]:
# Finish the python version if we have it
self.ivals[index].finish()
else:
# Otherwise, it's a C-only interval.
ival.finish()
return count
def step(self):
# This method should be called once per frame to perform all
# of the per-frame processing on the active intervals.
# Call C++ step, then do the Python stuff.
CIntervalManager.step(self)
self.__doPythonCallbacks()
def interrupt(self):
# This method should be called during an emergency cleanup
# operation, to automatically pause or finish all active
# intervals tagged with autoPause or autoFinish set true.
# Call C++ interrupt, then do the Python stuff.
CIntervalManager.interrupt(self)
self.__doPythonCallbacks()
def __doPythonCallbacks(self):
# This method does all of the required Python post-processing
# after performing some C++-level action.
# It is important to call all of the python callbacks on the
# just-removed intervals before we call any of the callbacks
# on the still-running intervals.
index = self.getNextRemoval()
while index >= 0:
# We have to clear the interval first before we call
# privPostEvent() on it, because the interval might itself
# try to add a new interval.
ival = self.ivals[index]
self.ivals[index] = None
ival.privPostEvent()
index = self.getNextRemoval()
index = self.getNextEvent()
while index >= 0:
self.ivals[index].privPostEvent()
index = self.getNextEvent()
# Finally, throw all the events on the custom event queue.
# These are the done events that may have been generated in
# C++. We use a custom event queue so we can service all of
# these immediately, rather than waiting for the global event
# queue to be serviced (which might not be till next frame).
self.eventManager.doEvents()
def __storeInterval(self, interval, index):
while index >= len(self.ivals):
self.ivals.append(None)
assert(self.ivals[index] == None)
self.ivals[index] = interval
def __repr__(self):
return self.__str__()
# The global IntervalManager object.
ivalMgr = IntervalManager(1)