historical/toontown-classic.git/panda/direct/interval/IntervalManager.py
2024-01-16 11:20:27 -06:00

141 lines
5.1 KiB
Python

"""Defines the IntervalManager class as well as the global instance of
this class, ivalMgr."""
__all__ = ['IntervalManager', 'ivalMgr']
from panda3d.core import *
from panda3d.direct import *
from direct.directnotify.DirectNotifyGlobal import *
from direct.showbase import EventManager
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:
self.cObj = CIntervalManager.getGlobalPtr()
Dtool_BorrowThisReference(self, self.cObj)
self.dd = self
else:
CIntervalManager.__init__(self)
self.eventQueue = EventQueue()
self.MyEventmanager = 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)
if index < len(self.ivals):
self.ivals[index] = None
return 1
return 0
def getInterval(self, name):
index = self.findCInterval(name)
if index >= 0:
if index < len(self.ivals) and self.ivals[index]:
return self.ivals[index]
# It must be a C-only interval.
return self.getCInterval(index)
return None
def getIntervalsMatching(self, pattern):
ivals = []
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 index < len(self.ivals) and self.ivals[index]:
# Get the python version if we have it
ivals.append(self.ivals[index])
else:
# Otherwise, it's a C-only interval.
ivals.append(ival)
return ivals
def finishIntervalsMatching(self, pattern):
ivals = self.getIntervalsMatching(pattern)
for ival in ivals:
ival.finish()
return len(ivals)
def pauseIntervalsMatching(self, pattern):
ivals = self.getIntervalsMatching(pattern)
for ival in ivals:
ival.pause()
return len(ivals)
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.MyEventmanager.doEvents()
def __storeInterval(self, interval, index):
while index >= len(self.ivals):
self.ivals.append(None)
assert self.ivals[index] == None or self.ivals[index] == interval
self.ivals[index] = interval
#: The global IntervalManager object.
ivalMgr = IntervalManager(1)