zeth / inputs

Cross-platform Python support for keyboards, mice and gamepads
BSD 3-Clause "New" or "Revised" License
273 stars 88 forks source link

Rescanning OS for peripherals crashs when connecting xbox controller. #2

Open jf-mgd opened 8 years ago

jf-mgd commented 8 years ago

Using the following test code to try to enable "after launch" joystick connection:

# -*- coding: windows-1252 -*-

import inputs
from time import sleep
from traceback import print_exc

try:
  while 1:

    # Wait for a joystick to be connected
    print "Please connect a joystick..."
    while 1:
      try:
        inputs.devices = inputs.DeviceManager() # Rescan OS for joystick.
        inputs.get_gamepad()
        break

      except inputs.UnpluggedError:
        sleep(1.0 / 30.0)

    # Print connected device name
    print(inputs.devices.gamepads[0])

    # While joystick is connected
    try:
      while 1:
        try:
          events = inputs.get_gamepad()
          for event in events:
            print(event.ev_type, event.code, event.state)

        except inputs.UnknownEventType:
          pass

    except inputs.UnpluggedError:
      print("Joystick unplugged!")

except:
  print_exc()

I have the following crash when I connect a new xbox controller:

  File "D:\projets\tests\lib\site-packages\inputs.py", line 2713, in get_gamepad
    return gamepad.read()
  File "D:\projets\tests\lib\site-packages\inputs.py", line 2101, in read
    return next(iter(self))
  File "D:\projets\tests\lib\site-packages\inputs.py", line 2192, in __iter__
    self.__check_state()
  File "D:\projets\tests\lib\site-packages\inputs.py", line 2205, in __check_state
    self.__handle_changed_state(state)
  File "D:\projets\tests\lib\site-packages\inputs.py", line 2270, in __handle_changed_state
    events.extend(self.__get_axis_events(state, timeval))
  File "D:\projets\tests\lib\site-packages\inputs.py", line 2304, in __get_axis_events
    events = self.__emulate_axis(axis_changes, timeval)
  File "D:\projets\tests\lib\site-packages\inputs.py", line 2316, in __emulate_axis
    timeval=timeval)
  File "D:\projets\tests\lib\site-packages\inputs.py", line 2229, in create_event_object
    event_type)
UnknownEventType: ("We don't know what kind of event a %s is.", 'Absolute')

And indeed, inputs.DeviceManager.codes['type_codes'] is empty on consecutives calls to inputs.DeviceManager. constructors (it only contains values the first time constructor is called).

zeth commented 8 years ago

Sorry for the delay in replying. Thanks so much for this work. I will test and commit it as soon as I can.

joseafga commented 6 years ago

I had the same problem. @jf-mgd commit work fine. To not change the module code I did the following:

import inputs

inputs.EVENT_MAP = list(inputs.EVENT_MAP)
inputs.EVENT_MAP[1] = ('type_codes', list((value, key) for key, value in inputs.EVENT_TYPES))
inputs.EVENT_MAP = tuple(inputs.EVENT_MAP)
ChrisDAT20 commented 2 years ago

I got the same issue.

The connected devices are read using inputs.DeviceManager() in a loop and presented as list to the user on a UI. This way it is assured that all newly connected devices are picked up and disconnected devices are removed from that list as well.

When the user selects a device, i added a verification if the device is still avalable, just to be sure. But when calling inputs.DeviceManager() again and verify if the selected device is still amongst the list of connected devices, which is, the events from that device seem to be screwed up.