open_toontown_panda3d/direct/src/controls/InputState.py

109 lines
3.7 KiB
Python
Executable File

from direct.directnotify import DirectNotifyGlobal
from direct.showbase import DirectObject
class InputState(DirectObject.DirectObject):
"""
InputState is for tracking the on/off state of some events.
The initial usage is to watch some keyboard keys so that another
task can poll the key states. By the way, in general polling is
not a good idea, but it is useful in some situations. Know when
to use it :) If in doubt, don't use this class and listen for
events instead.
"""
notify = DirectNotifyGlobal.directNotify.newCategory("InputState")
def __init__(self):
self.state = {}
assert(self.debugPrint("InputState()"))
self.watching = {}
self.forcing = {}
def delete(self):
self.ignoreAll()
def watch(self, name, eventOn, eventOff, default = 0):
"""
name is any string (or actually any valid dictionary key).
eventOn is the string name of the Messenger event that will
set the state (set to 1).
eventOff is the string name of the Messenger event that will
clear the state (set to 0).
default is the initial value (this will be returned from
isSet() if a call is made before any eventOn or eventOff
events occur.
See Also: ignore()
"""
assert(self.debugPrint(
"watch(name=%s, eventOn=%s, eventOff=%s, default=%s)"%(
name, eventOn, eventOff, default)))
self.accept(eventOn, self.set, [name, 1])
self.accept(eventOff, self.set, [name, 0])
self.state[name] = default
# self.watching is a dict of the form:
# {name : [(eventOn, eventOff), (eventOn, eventOff)...]}
eventList = self.watching.get(name)
if eventList:
eventList.append((eventOn, eventOff))
else:
# Start a new list
self.watching[name] = [(eventOn, eventOff)]
def watchWithModifiers(self, name, event, default = 0):
patterns = ('%s', 'control-%s', 'shift-control-%s', 'alt-%s',
'control-alt-%s', 'shift-%s',)
for pattern in patterns:
self.watch(name, pattern % event, '%s-up' % event, default)
def force(self, name, value):
"""
Force isSet(name) to return value.
See Also: unforce()
"""
self.forcing[name] = value
def unforce(self, name):
"""
Stop forcing a value.
See Also: force()
"""
del self.forcing[name]
def ignore(self, name):
"""
The opposite of watch(name, ...)
See Also: watch()
"""
for event in self.watching[name]:
eventOn, eventOff = event
DirectObject.DirectObject.ignore(self, eventOn)
DirectObject.DirectObject.ignore(self, eventOff)
del self.watching[name]
del self.state[name]
def set(self, name, isSet):
assert(self.debugPrint("set(name=%s, isSet=%s)"%(name, isSet)))
self.state[name] = isSet
# We change the name before sending it because this may
# be the same name that messenger used to call InputState.set()
# this avoids running in circles:
messenger.send("InputState-%s"%(name,), [isSet])
def isSet(self, name):
"""
returns 0, 1
"""
#assert(self.debugPrint("isSet(name=%s)"%(name)))
r = self.forcing.get(name)
if r is not None:
return r
return self.state.get(name, 0)
def debugPrint(self, message):
"""for debugging"""
return self.notify.debug(
"%s (%s) %s"%(id(self), len(self.state), message))