mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
showbase: make input device binding explicit, not automatic
This commit is contained in:
parent
8edc019307
commit
76365f3ed1
@ -307,12 +307,7 @@ class ShowBase(DirectObject.DirectObject):
|
||||
## This is the global input device manager, which keeps track of
|
||||
## connected input devices.
|
||||
self.devices = InputDeviceManager.getGlobalPtr()
|
||||
# add existing devices to the data graph
|
||||
for device in self.devices.devices:
|
||||
self.connectDevice(device)
|
||||
# Checks for device connection and disconnection
|
||||
self.accept('connect-device', self.connectDevice)
|
||||
self.accept('disconnect-device', self.disconnectDevice)
|
||||
self.__inputDeviceNodes = {}
|
||||
|
||||
self.createStats()
|
||||
|
||||
@ -1681,76 +1676,56 @@ class ShowBase(DirectObject.DirectObject):
|
||||
return self.mouseWatcherNode.getModifierButtons().isDown(
|
||||
KeyboardButton.meta())
|
||||
|
||||
def connectDevice(self, device):
|
||||
def attachInputDevice(self, device, prefix=None):
|
||||
"""
|
||||
This function will get called each time a new device got
|
||||
connected and will add that new device to the data graph.
|
||||
This function attaches an input device to the data graph, which will
|
||||
cause the device to be polled and generate events. If a prefix is
|
||||
given and not None, it is used to prefix events generated by this
|
||||
device, separated by a hyphen.
|
||||
|
||||
Each device class will get a specific prefix for thrown events. Those
|
||||
are currently as follow
|
||||
|
||||
gamepad
|
||||
flight_stick
|
||||
steering_wheel
|
||||
dance_pad
|
||||
mouse
|
||||
keyboard
|
||||
unclassified_device
|
||||
|
||||
In addition, the index of that device will appended to the prefix,
|
||||
so for example if you hit the A button of the first connected gamepad
|
||||
you will get an event like "gamepad0-action_a" the second gamepad will
|
||||
then be catchable via "gamepad1-button_event" and so on.
|
||||
Note, each device class will have a separate 0 based index, this way
|
||||
you can have a gamepad0 as well as a steering_wheel0 and flight_stick0.
|
||||
|
||||
All newly created button throwers will be stored in
|
||||
the deviceButtonThrowers lsit
|
||||
If you call this, you should consider calling detachInputDevice when
|
||||
you are done with the device or when it is disconnected.
|
||||
"""
|
||||
idn = self.dataRoot.attachNewNode(InputDeviceNode(device, device.getName()))
|
||||
prefix = "unclassified_device"
|
||||
if device.getDeviceClass() == InputDevice.DC_gamepad:
|
||||
prefix = "gamepad"
|
||||
elif device.getDeviceClass() == InputDevice.DC_flight_stick:
|
||||
prefix = "flight_stick"
|
||||
elif device.getDeviceClass() == InputDevice.DC_steering_wheel:
|
||||
prefix = "steering_wheel"
|
||||
elif device.getDeviceClass() == InputDevice.DC_dance_pad:
|
||||
prefix = "dance_pad"
|
||||
elif device.getDeviceClass() == InputDevice.DC_mouse:
|
||||
prefix = "mouse"
|
||||
elif device.getDeviceClass() == InputDevice.DC_keyboard:
|
||||
prefix = "keyboard"
|
||||
|
||||
currentPrefixes = []
|
||||
for np in self.dataRoot.findAllMatches("**/{}".format(prefix)):
|
||||
bt = np.node()
|
||||
currentPrefixes.append(bt.getPrefix())
|
||||
# Protect against the same device being attached multiple times.
|
||||
assert device not in self.__inputDeviceNodes
|
||||
|
||||
id = 0
|
||||
# Find the next free ID for the newly connected device
|
||||
while "{}{}-".format(prefix, id) in currentPrefixes:
|
||||
id+=1
|
||||
# Setup the button thrower for that device and register it's event prefix
|
||||
bt = idn.attachNewNode(ButtonThrower(prefix))
|
||||
assert self.notify.debug("Registered event prefix {}{}-".format(prefix, id))
|
||||
bt.node().setPrefix("{}{}-".format(prefix, id))
|
||||
# append the new button thrower to the list of device button throwers
|
||||
idn = self.dataRoot.attachNewNode(InputDeviceNode(device, device.name))
|
||||
|
||||
# Setup the button thrower to generate events for the device.
|
||||
bt = idn.attachNewNode(ButtonThrower(device.name))
|
||||
if prefix is not None:
|
||||
bt.node().setPrefix(prefix + '-')
|
||||
|
||||
assert self.notify.debug("Attached input device {0} with prefix {1}".format(device, prefix))
|
||||
self.__inputDeviceNodes[device] = idn
|
||||
self.deviceButtonThrowers.append(bt)
|
||||
|
||||
def disconnectDevice(self, device):
|
||||
def detachInputDevice(self, device):
|
||||
"""
|
||||
This function will get called each time a new device got
|
||||
connected. It is then used to clean up the given device from the
|
||||
data graph.
|
||||
This should be called after attaching an input device using
|
||||
attachInputDevice and the device is disconnected or you no longer wish
|
||||
to keep polling this device for events.
|
||||
|
||||
You do not strictly need to call this if you expect the device to be
|
||||
reconnected (but be careful that you don't reattach it).
|
||||
"""
|
||||
self.notify.debug("Disconnect device {}".format(device.getName()))
|
||||
idn = self.dataRoot.find("**/{}".format(device.getName()))
|
||||
for bt in list(self.deviceButtonThrowers):
|
||||
if bt.getName() == idn.getName():
|
||||
|
||||
if device not in self.__inputDeviceNodes:
|
||||
assert device in self.__inputDeviceNodes
|
||||
return
|
||||
|
||||
assert self.notify.debug("Detached device {0}".format(device.name))
|
||||
|
||||
# Remove the ButtonThrower from the deviceButtonThrowers list.
|
||||
idn = self.__inputDeviceNodes[device]
|
||||
for bt in self.deviceButtonThrowers:
|
||||
if idn.isAncestorOf(bt):
|
||||
self.deviceButtonThrowers.remove(bt)
|
||||
break
|
||||
|
||||
idn.removeNode()
|
||||
del self.__inputDeviceNodes[device]
|
||||
|
||||
def addAngularIntegrator(self):
|
||||
if not self.physicsMgrAngular:
|
||||
@ -1944,10 +1919,6 @@ class ShowBase(DirectObject.DirectObject):
|
||||
# Check if there were newly connected devices.
|
||||
self.devices.update()
|
||||
|
||||
# Poll all connected devices.
|
||||
for device in self.devices.devices:
|
||||
device.poll()
|
||||
|
||||
# traverse the data graph. This reads all the control
|
||||
# inputs (from the mouse and keyboard, for instance) and also
|
||||
# directly acts upon them (for instance, to move the avatar).
|
||||
@ -3163,6 +3134,8 @@ class ShowBase(DirectObject.DirectObject):
|
||||
setup_mouse = setupMouse
|
||||
setup_mouse_cb = setupMouseCB
|
||||
enable_software_mouse_pointer = enableSoftwareMousePointer
|
||||
detach_input_device = detachInputDevice
|
||||
attach_input_device = attachInputDevice
|
||||
add_angular_integrator = addAngularIntegrator
|
||||
enable_particles = enableParticles
|
||||
disable_particles = disableParticles
|
||||
|
Loading…
x
Reference in New Issue
Block a user