More robust handling of device add/remove events

This commit is contained in:
Stefanos A 2013-12-23 00:17:13 +01:00 committed by thefiddler
parent 31ce400a7e
commit 44351a03c4

View file

@ -56,6 +56,7 @@ namespace OpenTK.Platform.SDL2
} }
readonly List<JoystickDevice> joysticks = new List<JoystickDevice>(4); readonly List<JoystickDevice> joysticks = new List<JoystickDevice>(4);
readonly Dictionary<int, int> sdl_joyid_to_joysticks = new Dictionary<int, int>();
readonly Dictionary<int, Sdl2GamePad> controllers = new Dictionary<int, Sdl2GamePad>(); readonly Dictionary<int, Sdl2GamePad> controllers = new Dictionary<int, Sdl2GamePad>();
IList<JoystickDevice> joysticks_readonly; IList<JoystickDevice> joysticks_readonly;
@ -130,14 +131,6 @@ namespace OpenTK.Platform.SDL2
{ {
case EventType.JOYDEVICEADDED: case EventType.JOYDEVICEADDED:
{ {
// Make sure we have enough space to store this instance
if (joysticks.Capacity <= id)
{
joysticks.Capacity = OpenTK.MathHelper.NextPowerOfTwo(id + 1);
for (int i = joysticks.Count; i < joysticks.Capacity; i++)
joysticks.Add(null); // Expand the joysticks list
}
IntPtr handle = SDL.JoystickOpen(id); IntPtr handle = SDL.JoystickOpen(id);
if (handle != IntPtr.Zero) if (handle != IntPtr.Zero)
{ {
@ -145,7 +138,13 @@ namespace OpenTK.Platform.SDL2
if (joystick != null) if (joystick != null)
{ {
joystick.Details.IsConnected = true; joystick.Details.IsConnected = true;
joysticks[id] = joystick; if (!sdl_joyid_to_joysticks.ContainsKey(id))
{
sdl_joyid_to_joysticks.Add(id, joysticks.Count);
joysticks.Add(null);
}
int index = sdl_joyid_to_joysticks[id];
joysticks[index] = joystick;
} }
} }
} }
@ -153,7 +152,8 @@ namespace OpenTK.Platform.SDL2
case EventType.JOYDEVICEREMOVED: case EventType.JOYDEVICEREMOVED:
{ {
JoystickDevice<Sdl2JoystickDetails> joystick = (JoystickDevice<Sdl2JoystickDetails>)joysticks[id]; int index = sdl_joyid_to_joysticks[id];
JoystickDevice<Sdl2JoystickDetails> joystick = (JoystickDevice<Sdl2JoystickDetails>)joysticks[index];
joystick.Details.IsConnected = false; joystick.Details.IsConnected = false;
} }
break; break;
@ -165,7 +165,8 @@ namespace OpenTK.Platform.SDL2
int id = ev.Which; int id = ev.Which;
if (IsJoystickValid(id)) if (IsJoystickValid(id))
{ {
JoystickDevice<Sdl2JoystickDetails> joystick = (JoystickDevice<Sdl2JoystickDetails>)joysticks[id]; int index = sdl_joyid_to_joysticks[id];
JoystickDevice<Sdl2JoystickDetails> joystick = (JoystickDevice<Sdl2JoystickDetails>)joysticks[index];
float value = ev.Value * RangeMultiplier; float value = ev.Value * RangeMultiplier;
joystick.SetAxis((JoystickAxis)ev.Axis, value); joystick.SetAxis((JoystickAxis)ev.Axis, value);
} }
@ -180,7 +181,8 @@ namespace OpenTK.Platform.SDL2
int id = ev.Which; int id = ev.Which;
if (IsJoystickValid(id)) if (IsJoystickValid(id))
{ {
JoystickDevice<Sdl2JoystickDetails> joystick = (JoystickDevice<Sdl2JoystickDetails>)joysticks[id]; int index = sdl_joyid_to_joysticks[id];
JoystickDevice<Sdl2JoystickDetails> joystick = (JoystickDevice<Sdl2JoystickDetails>)joysticks[index];
// Todo: does it make sense to support balls? // Todo: does it make sense to support balls?
} }
else else
@ -194,7 +196,8 @@ namespace OpenTK.Platform.SDL2
int id = ev.Which; int id = ev.Which;
if (IsJoystickValid(id)) if (IsJoystickValid(id))
{ {
JoystickDevice<Sdl2JoystickDetails> joystick = (JoystickDevice<Sdl2JoystickDetails>)joysticks[id]; int index = sdl_joyid_to_joysticks[id];
JoystickDevice<Sdl2JoystickDetails> joystick = (JoystickDevice<Sdl2JoystickDetails>)joysticks[index];
joystick.SetButton((JoystickButton)ev.Button, ev.State == State.Pressed); joystick.SetButton((JoystickButton)ev.Button, ev.State == State.Pressed);
} }
else else
@ -208,7 +211,8 @@ namespace OpenTK.Platform.SDL2
int id = ev.Which; int id = ev.Which;
if (IsJoystickValid(id)) if (IsJoystickValid(id))
{ {
JoystickDevice<Sdl2JoystickDetails> joystick = (JoystickDevice<Sdl2JoystickDetails>)joysticks[id]; int index = sdl_joyid_to_joysticks[id];
JoystickDevice<Sdl2JoystickDetails> joystick = (JoystickDevice<Sdl2JoystickDetails>)joysticks[index];
// Todo: map hat to an extra axis // Todo: map hat to an extra axis
} }
else else
@ -224,15 +228,15 @@ namespace OpenTK.Platform.SDL2
switch (ev.Type) switch (ev.Type)
{ {
case EventType.CONTROLLERDEVICEADDED: case EventType.CONTROLLERDEVICEADDED:
if (SDL.IsGameController(id)) IntPtr handle = SDL.GameControllerOpen(id);
if (handle != IntPtr.Zero)
{ {
IntPtr handle = SDL.GameControllerOpen(id); Sdl2GamePad pad = new Sdl2GamePad(handle);
if (handle != IntPtr.Zero) pad.State.SetConnected(true);
{ // Check whether the device has ever been connected before
Sdl2GamePad pad = new Sdl2GamePad(handle); if (!controllers.ContainsKey(id))
pad.State.SetConnected(true); controllers.Add(id, null);
controllers.Add(id, pad); controllers[id] = pad;
}
} }
break; break;