summaryrefslogtreecommitdiff
path: root/src/input_common/sdl/sdl_impl.cpp
diff options
context:
space:
mode:
authorGravatar Morph2020-09-03 11:07:57 -0400
committerGravatar Morph2020-10-16 00:04:59 -0400
commit7b3f5845d28fdf245967b930452d392458fd8535 (patch)
tree7b627a0d7985ec42e90e6f4348f60c3094e31e0d /src/input_common/sdl/sdl_impl.cpp
parentMerge pull request #4790 from lioncash/input-common (diff)
downloadyuzu-7b3f5845d28fdf245967b930452d392458fd8535.tar.gz
yuzu-7b3f5845d28fdf245967b930452d392458fd8535.tar.xz
yuzu-7b3f5845d28fdf245967b930452d392458fd8535.zip
sdl_impl: Erase the SDLJoystick entry after removing a controller
Previously, disconnecting a controller still leaves a null SDLJoystick entry within the vector of SDLJoysticks mapped by GUID. When a DirectInput device of the same GUID is reconnected, it adds that device to a new port causing non-detectable input. Furthermore, opening the "Configure" menu would cause yuzu to crash since it first tries to resolve the name of a null SDLJoystick entry that was not removed. Resolve this by properly erasing the SDLJoystick entry from the vector.
Diffstat (limited to 'src/input_common/sdl/sdl_impl.cpp')
-rw-r--r--src/input_common/sdl/sdl_impl.cpp28
1 files changed, 13 insertions, 15 deletions
diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp
index 8c2cef35d..9c3035920 100644
--- a/src/input_common/sdl/sdl_impl.cpp
+++ b/src/input_common/sdl/sdl_impl.cpp
@@ -273,21 +273,19 @@ void SDLState::InitJoystick(int joystick_index) {
273void SDLState::CloseJoystick(SDL_Joystick* sdl_joystick) { 273void SDLState::CloseJoystick(SDL_Joystick* sdl_joystick) {
274 const std::string guid = GetGUID(sdl_joystick); 274 const std::string guid = GetGUID(sdl_joystick);
275 275
276 std::shared_ptr<SDLJoystick> found_joystick; 276 std::lock_guard lock{joystick_map_mutex};
277 { 277 auto& joystick_guid_list = joystick_map[guid];
278 std::lock_guard lock{joystick_map_mutex}; 278 auto joystick_it = std::find_if(
279 // This call to guid is safe since the joystick is guaranteed to be in the map 279 joystick_guid_list.begin(), joystick_guid_list.end(),
280 const auto& joystick_guid_list = joystick_map[guid]; 280 [&sdl_joystick](auto& joystick) { return joystick->GetSDLJoystick() == sdl_joystick; });
281 const auto joystick_it = std::find_if(joystick_guid_list.begin(), joystick_guid_list.end(), 281
282 [&sdl_joystick](const auto& joystick) { 282 if (joystick_it != joystick_guid_list.end()) {
283 return joystick->GetSDLJoystick() == sdl_joystick; 283 (*joystick_it)->SetSDLJoystick(nullptr, nullptr);
284 }); 284 joystick_guid_list.erase(joystick_it);
285 found_joystick = *joystick_it; 285 if (joystick_guid_list.empty()) {
286 } 286 joystick_map.erase(guid);
287 287 }
288 // Destruct SDL_Joystick outside the lock guard because SDL can internally call the 288 }
289 // event callback which locks the mutex again.
290 found_joystick->SetSDLJoystick(nullptr, nullptr);
291} 289}
292 290
293void SDLState::HandleGameControllerEvent(const SDL_Event& event) { 291void SDLState::HandleGameControllerEvent(const SDL_Event& event) {