forked from panda3d/panda3d
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIntervalManager.py
More file actions
141 lines (120 loc) · 5.11 KB
/
IntervalManager.py
File metadata and controls
141 lines (120 loc) · 5.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
"""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)