Merge pull request #13157 from jordan-woyak/sdl-hotplug-fix

ControllerInterface/SDL: Fix device removal event processing.
This commit is contained in:
JMC47 2024-11-01 18:11:17 -04:00 committed by GitHub
commit 000e8fd83d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -263,18 +263,16 @@ private:
}; };
public: public:
GameController(SDL_GameController* const gamecontroller, SDL_Joystick* const joystick, GameController(SDL_GameController* const gamecontroller, SDL_Joystick* const joystick);
const int sdl_index);
~GameController(); ~GameController();
std::string GetName() const override; std::string GetName() const override;
std::string GetSource() const override; std::string GetSource() const override;
int GetSDLIndex() const; int GetSDLInstanceID() const;
private: private:
SDL_GameController* const m_gamecontroller; SDL_GameController* const m_gamecontroller;
std::string m_name; std::string m_name;
int m_sdl_index;
SDL_Joystick* const m_joystick; SDL_Joystick* const m_joystick;
SDL_Haptic* m_haptic = nullptr; SDL_Haptic* m_haptic = nullptr;
}; };
@ -318,7 +316,7 @@ void InputBackend::OpenAndAddDevice(int index)
// SDL tries parsing these as Joysticks // SDL tries parsing these as Joysticks
return; return;
} }
auto gamecontroller = std::make_shared<GameController>(gc, js, index); auto gamecontroller = std::make_shared<GameController>(gc, js);
if (!gamecontroller->Inputs().empty() || !gamecontroller->Outputs().empty()) if (!gamecontroller->Inputs().empty() || !gamecontroller->Outputs().empty())
GetControllerInterface().AddDevice(std::move(gamecontroller)); GetControllerInterface().AddDevice(std::move(gamecontroller));
} }
@ -326,25 +324,20 @@ void InputBackend::OpenAndAddDevice(int index)
bool InputBackend::HandleEventAndContinue(const SDL_Event& e) bool InputBackend::HandleEventAndContinue(const SDL_Event& e)
{ {
if (e.type == SDL_CONTROLLERDEVICEADDED || e.type == SDL_JOYDEVICEADDED) if (e.type == SDL_JOYDEVICEADDED)
{ {
// Avoid handling the event twice on a GameController // NOTE: SDL_JOYDEVICEADDED's `jdevice.which` is a device index in SDL2.
if (e.type == SDL_JOYDEVICEADDED && SDL_IsGameController(e.jdevice.which)) // It will change to an "instance ID" in SDL3.
{ // OpenAndAddDevice impl and calls will need refactoring when changing to SDL3.
return true; static_assert(!SDL_VERSION_ATLEAST(3, 0, 0), "Refactoring is needed for SDL3.");
}
OpenAndAddDevice(e.jdevice.which); OpenAndAddDevice(e.jdevice.which);
} }
else if (e.type == SDL_CONTROLLERDEVICEREMOVED || e.type == SDL_JOYDEVICEREMOVED) else if (e.type == SDL_JOYDEVICEREMOVED)
{ {
// Avoid handling the event twice on a GameController // NOTE: SDL_JOYDEVICEREMOVED's `jdevice.which` is an "instance ID".
if (e.type == SDL_JOYDEVICEREMOVED && SDL_IsGameController(e.jdevice.which))
{
return true;
}
GetControllerInterface().RemoveDevice([&e](const auto* device) { GetControllerInterface().RemoveDevice([&e](const auto* device) {
return device->GetSource() == "SDL" && return device->GetSource() == "SDL" &&
static_cast<const GameController*>(device)->GetSDLIndex() == e.jdevice.which; static_cast<const GameController*>(device)->GetSDLInstanceID() == e.jdevice.which;
}); });
} }
else if (e.type == m_populate_event_type) else if (e.type == m_populate_event_type)
@ -585,8 +578,8 @@ static constexpr SDLMotionAxisList SDL_AXES_GYRO = {{
// clang-format on // clang-format on
GameController::GameController(SDL_GameController* const gamecontroller, GameController::GameController(SDL_GameController* const gamecontroller,
SDL_Joystick* const joystick, const int sdl_index) SDL_Joystick* const joystick)
: m_gamecontroller(gamecontroller), m_sdl_index(sdl_index), m_joystick(joystick) : m_gamecontroller(gamecontroller), m_joystick(joystick)
{ {
const char* name; const char* name;
if (gamecontroller) if (gamecontroller)
@ -809,9 +802,9 @@ std::string GameController::GetSource() const
return "SDL"; return "SDL";
} }
int GameController::GetSDLIndex() const int GameController::GetSDLInstanceID() const
{ {
return m_sdl_index; return SDL_JoystickInstanceID(m_joystick);
} }
std::string GameController::Button::GetName() const std::string GameController::Button::GetName() const