Improve joystick connection/disconnection.

Followup on 02520fb6.

Add ConnectController() and DisconnectController() protected methods in
wxSDLJoy, use them to open or close and clear the device pointer
properly.

For controller add/remap events, call DisconnectController() first
before ConnectController() to make sure the right device is associated.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
This commit is contained in:
Rafael Kitover 2019-12-05 16:55:02 +00:00
parent d395e05d97
commit 1ccc377978
No known key found for this signature in database
GPG Key ID: 08AB596679D86240
2 changed files with 26 additions and 11 deletions

View File

@ -100,7 +100,8 @@ void wxSDLJoy::Poll()
auto joy = e.cdevice.which;
if (add_all || contains(joystate, joy)) {
joystate[joy].dev = SDL_GameControllerOpen(joy);
DisconnectController(joy);
ConnectController(joy);
systemScreenMessage(wxString::Format(_("Connected game controller %d"), joy + 1));
}
@ -111,7 +112,7 @@ void wxSDLJoy::Poll()
auto joy = e.cdevice.which;
if (contains(joystate, joy)) {
joystate[joy].dev = nullptr;
DisconnectController(joy);
systemScreenMessage(wxString::Format(_("Disconnected game controller %d"), joy + 1));
}
@ -121,6 +122,22 @@ void wxSDLJoy::Poll()
}
}
void wxSDLJoy::ConnectController(uint8_t joy)
{
if (!(joystate[joy].dev = SDL_GameControllerOpen(joy)))
wxLogDebug("SDL_GameControllerOpen(%d) failed: %s", joy, SDL_GetError());
}
void wxSDLJoy::DisconnectController(uint8_t joy)
{
if (auto& dev = joystate[joy].dev) {
if (SDL_GameControllerGetAttached(dev))
SDL_GameControllerClose(dev);
dev = nullptr;
}
}
wxEvtHandler* wxSDLJoy::Attach(wxEvtHandler* handler)
{
wxEvtHandler* prev = evthandler;
@ -132,14 +149,14 @@ void wxSDLJoy::Add(int8_t joy_n)
{
if (joy_n < 0) {
for (uint8_t joy : range(0, SDL_NumJoysticks()))
joystate[joy].dev = SDL_GameControllerOpen(joy);
ConnectController(joy);
add_all = true;
return;
}
joystate[joy_n].dev = SDL_GameControllerOpen(joy_n);
ConnectController(joy_n);
}
void wxSDLJoy::Remove(int8_t joy_n)
@ -147,19 +164,15 @@ void wxSDLJoy::Remove(int8_t joy_n)
add_all = false;
if (joy_n < 0) {
for (auto joy : joystate) {
if (auto dev = std::get<1>(joy).dev)
SDL_GameControllerClose(dev);
}
for (auto joy : joystate)
DisconnectController(std::get<0>(joy));
joystate.clear();
return;
}
if (auto dev = joystate[joy_n].dev)
SDL_GameControllerClose(dev);
DisconnectController(joy_n);
joystate.erase(joy_n);
}

View File

@ -50,6 +50,8 @@ public:
protected:
// used to continue rumbling on a timer
void Notify();
void ConnectController(uint8_t joy);
void DisconnectController(uint8_t joy);
private:
std::unordered_map<uint8_t, wxSDLJoyState> joystate;
wxEvtHandler* evthandler;