forked from panda3d/panda3d
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEventManager.py
More file actions
181 lines (155 loc) · 7.07 KB
/
EventManager.py
File metadata and controls
181 lines (155 loc) · 7.07 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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
"""Contains the EventManager class. See :mod:`.EventManagerGlobal` for the
global eventMgr instance."""
__all__ = ['EventManager']
from .MessengerGlobal import *
from direct.directnotify.DirectNotifyGlobal import *
from direct.task.TaskManagerGlobal import taskMgr
from panda3d.core import PStatCollector, EventQueue, EventHandler
from panda3d.core import ConfigVariableBool
class EventManager:
notify = None
def __init__(self, eventQueue = None):
"""
Create a C++ event queue and handler
"""
# Make a notify category for this class (unless there already is one)
if EventManager.notify is None:
EventManager.notify = directNotify.newCategory("EventManager")
self.eventQueue = eventQueue
self.eventHandler = None
self._wantPstats = ConfigVariableBool('pstats-eventmanager', False)
def doEvents(self):
"""
Process all the events on the C++ event queue
"""
# use different methods for handling events with and without pstats tracking
# for efficiency
if self._wantPstats:
processFunc = self.processEventPstats
else:
processFunc = self.processEvent
isEmptyFunc = self.eventQueue.isQueueEmpty
dequeueFunc = self.eventQueue.dequeueEvent
while not isEmptyFunc():
processFunc(dequeueFunc())
def eventLoopTask(self, task):
"""
Process all the events on the C++ event queue
"""
self.doEvents()
messenger.send("event-loop-done")
return task.cont
def parseEventParameter(self, eventParameter):
"""
Extract the actual data from the eventParameter
"""
if (eventParameter.isInt()):
return eventParameter.getIntValue()
elif (eventParameter.isDouble()):
return eventParameter.getDoubleValue()
elif (eventParameter.isString()):
return eventParameter.getStringValue()
elif (eventParameter.isWstring()):
return eventParameter.getWstringValue()
elif (eventParameter.isTypedRefCount()):
return eventParameter.getTypedRefCountValue()
elif (eventParameter.isEmpty()):
return None
else:
# Must be some user defined type, return the ptr
# which will be downcast to that type.
return eventParameter.getPtr()
def processEvent(self, event):
"""
Process a C++ event
Duplicate any changes in processEventPstats
"""
# **************************************************************
# ******** Duplicate any changes in processEventPstats *********
# **************************************************************
# Get the event name
eventName = event.name
if eventName:
paramList = []
for eventParameter in event.parameters:
eventParameterData = self.parseEventParameter(eventParameter)
paramList.append(eventParameterData)
# Do not print the new frame debug, it is too noisy!
if (EventManager.notify.getDebug() and eventName != 'NewFrame'):
EventManager.notify.debug('received C++ event named: ' + eventName +
' parameters: ' + repr(paramList))
# **************************************************************
# ******** Duplicate any changes in processEventPstats *********
# **************************************************************
# Send the event, we used to send it with the event
# name as a parameter, but now you can use extraArgs for that
messenger.send(eventName, paramList)
# Also send the event down into C++ land
handler = self.eventHandler
if handler:
handler.dispatchEvent(event)
else:
# An unnamed event from C++ is probably a bad thing
EventManager.notify.warning('unnamed event in processEvent')
def processEventPstats(self, event):
"""
Process a C++ event with pstats tracking
Duplicate any changes in processEvent
"""
# ********************************************************
# ******** Duplicate any changes in processEvent *********
# ********************************************************
# Get the event name
eventName = event.name
if eventName:
paramList = []
for eventParameter in event.parameters:
eventParameterData = self.parseEventParameter(eventParameter)
paramList.append(eventParameterData)
# Do not print the new frame debug, it is too noisy!
if (EventManager.notify.getDebug() and eventName != 'NewFrame'):
EventManager.notify.debug('received C++ event named: ' + eventName +
' parameters: ' + repr(paramList))
# Send the event, we used to send it with the event
# name as a parameter, but now you can use extraArgs for that
# ********************************************************
# ******** Duplicate any changes in processEvent *********
# ********************************************************
name = eventName
hyphen = name.find('-')
if hyphen >= 0:
name = name[0:hyphen]
pstatCollector = PStatCollector('App:Show code:eventManager:' + name)
pstatCollector.start()
if self.eventHandler:
cppPstatCollector = PStatCollector(
'App:Show code:eventManager:' + name + ':C++')
messenger.send(eventName, paramList)
# Also send the event down into C++ land
handler = self.eventHandler
if handler:
cppPstatCollector.start()
handler.dispatchEvent(event)
cppPstatCollector.stop()
pstatCollector.stop()
else:
# An unnamed event from C++ is probably a bad thing
EventManager.notify.warning('unnamed event in processEvent')
def restart(self):
if self.eventQueue is None:
self.eventQueue = EventQueue.getGlobalEventQueue()
if self.eventHandler is None:
if self.eventQueue == EventQueue.getGlobalEventQueue():
# If we are using the global event queue, then we also
# want to use the global event handler.
self.eventHandler = EventHandler.getGlobalEventHandler()
else:
# Otherwise, we need our own event handler.
self.eventHandler = EventHandler(self.eventQueue)
taskMgr.add(self.eventLoopTask, 'eventManager')
def shutdown(self):
taskMgr.remove('eventManager')
# Flush the event queue. We do this after removing the task
# since the task removal itself might also fire off an event.
if self.eventQueue is not None:
self.eventQueue.clear()