mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -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
|
## This is the global input device manager, which keeps track of
|
||||||
## connected input devices.
|
## connected input devices.
|
||||||
self.devices = InputDeviceManager.getGlobalPtr()
|
self.devices = InputDeviceManager.getGlobalPtr()
|
||||||
# add existing devices to the data graph
|
self.__inputDeviceNodes = {}
|
||||||
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.createStats()
|
self.createStats()
|
||||||
|
|
||||||
@ -1681,76 +1676,56 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
return self.mouseWatcherNode.getModifierButtons().isDown(
|
return self.mouseWatcherNode.getModifierButtons().isDown(
|
||||||
KeyboardButton.meta())
|
KeyboardButton.meta())
|
||||||
|
|
||||||
def connectDevice(self, device):
|
def attachInputDevice(self, device, prefix=None):
|
||||||
"""
|
"""
|
||||||
This function will get called each time a new device got
|
This function attaches an input device to the data graph, which will
|
||||||
connected and will add that new device to the data graph.
|
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
|
If you call this, you should consider calling detachInputDevice when
|
||||||
are currently as follow
|
you are done with the device or when it is disconnected.
|
||||||
|
|
||||||
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
|
|
||||||
"""
|
"""
|
||||||
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 = []
|
# Protect against the same device being attached multiple times.
|
||||||
for np in self.dataRoot.findAllMatches("**/{}".format(prefix)):
|
assert device not in self.__inputDeviceNodes
|
||||||
bt = np.node()
|
|
||||||
currentPrefixes.append(bt.getPrefix())
|
|
||||||
|
|
||||||
id = 0
|
idn = self.dataRoot.attachNewNode(InputDeviceNode(device, device.name))
|
||||||
# Find the next free ID for the newly connected device
|
|
||||||
while "{}{}-".format(prefix, id) in currentPrefixes:
|
# Setup the button thrower to generate events for the device.
|
||||||
id+=1
|
bt = idn.attachNewNode(ButtonThrower(device.name))
|
||||||
# Setup the button thrower for that device and register it's event prefix
|
if prefix is not None:
|
||||||
bt = idn.attachNewNode(ButtonThrower(prefix))
|
bt.node().setPrefix(prefix + '-')
|
||||||
assert self.notify.debug("Registered event prefix {}{}-".format(prefix, id))
|
|
||||||
bt.node().setPrefix("{}{}-".format(prefix, id))
|
assert self.notify.debug("Attached input device {0} with prefix {1}".format(device, prefix))
|
||||||
# append the new button thrower to the list of device button throwers
|
self.__inputDeviceNodes[device] = idn
|
||||||
self.deviceButtonThrowers.append(bt)
|
self.deviceButtonThrowers.append(bt)
|
||||||
|
|
||||||
def disconnectDevice(self, device):
|
def detachInputDevice(self, device):
|
||||||
"""
|
"""
|
||||||
This function will get called each time a new device got
|
This should be called after attaching an input device using
|
||||||
connected. It is then used to clean up the given device from the
|
attachInputDevice and the device is disconnected or you no longer wish
|
||||||
data graph.
|
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()))
|
if device not in self.__inputDeviceNodes:
|
||||||
for bt in list(self.deviceButtonThrowers):
|
assert device in self.__inputDeviceNodes
|
||||||
if bt.getName() == idn.getName():
|
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)
|
self.deviceButtonThrowers.remove(bt)
|
||||||
break
|
break
|
||||||
|
|
||||||
idn.removeNode()
|
idn.removeNode()
|
||||||
|
del self.__inputDeviceNodes[device]
|
||||||
|
|
||||||
def addAngularIntegrator(self):
|
def addAngularIntegrator(self):
|
||||||
if not self.physicsMgrAngular:
|
if not self.physicsMgrAngular:
|
||||||
@ -1944,10 +1919,6 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
# Check if there were newly connected devices.
|
# Check if there were newly connected devices.
|
||||||
self.devices.update()
|
self.devices.update()
|
||||||
|
|
||||||
# Poll all connected devices.
|
|
||||||
for device in self.devices.devices:
|
|
||||||
device.poll()
|
|
||||||
|
|
||||||
# traverse the data graph. This reads all the control
|
# traverse the data graph. This reads all the control
|
||||||
# inputs (from the mouse and keyboard, for instance) and also
|
# inputs (from the mouse and keyboard, for instance) and also
|
||||||
# directly acts upon them (for instance, to move the avatar).
|
# directly acts upon them (for instance, to move the avatar).
|
||||||
@ -3163,6 +3134,8 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
setup_mouse = setupMouse
|
setup_mouse = setupMouse
|
||||||
setup_mouse_cb = setupMouseCB
|
setup_mouse_cb = setupMouseCB
|
||||||
enable_software_mouse_pointer = enableSoftwareMousePointer
|
enable_software_mouse_pointer = enableSoftwareMousePointer
|
||||||
|
detach_input_device = detachInputDevice
|
||||||
|
attach_input_device = attachInputDevice
|
||||||
add_angular_integrator = addAngularIntegrator
|
add_angular_integrator = addAngularIntegrator
|
||||||
enable_particles = enableParticles
|
enable_particles = enableParticles
|
||||||
disable_particles = disableParticles
|
disable_particles = disableParticles
|
||||||
|
Loading…
x
Reference in New Issue
Block a user