Centralize SDL input subsystem ownership for hotplug recovery
This commit is contained in:
parent
e94f0c5990
commit
d174341b6d
7 changed files with 315 additions and 117 deletions
191
app/streaming/input/sdlinputsubsystems.cpp
Normal file
191
app/streaming/input/sdlinputsubsystems.cpp
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
#include "streaming/input/sdlinputsubsystems.h"
|
||||
|
||||
#include "settings/mappingmanager.h"
|
||||
|
||||
namespace {
|
||||
|
||||
int s_JoystickRefs = 0;
|
||||
int s_GameControllerRefs = 0;
|
||||
#if !SDL_VERSION_ATLEAST(2, 0, 9)
|
||||
int s_HapticRefs = 0;
|
||||
#endif
|
||||
|
||||
bool retainSubsystem(Uint32 subsystem, int& refs, const char* subsystemName, const char* ownerTag)
|
||||
{
|
||||
if (refs == 0 && SDL_InitSubSystem(subsystem) != 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Failed to initialize %s subsystem for %s: %s",
|
||||
subsystemName,
|
||||
ownerTag,
|
||||
SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
refs++;
|
||||
return true;
|
||||
}
|
||||
|
||||
void releaseSubsystem(Uint32 subsystem, int& refs, const char* subsystemName, const char* ownerTag)
|
||||
{
|
||||
if (refs <= 0) {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Ignoring unbalanced release of %s subsystem for %s",
|
||||
subsystemName,
|
||||
ownerTag);
|
||||
refs = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
refs--;
|
||||
if (refs == 0) {
|
||||
SDL_QuitSubSystem(subsystem);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace SdlInputSubsystems {
|
||||
|
||||
bool acquire(const char* ownerTag, const LeaseOptions& options)
|
||||
{
|
||||
bool acquiredJoystick = false;
|
||||
#if !SDL_VERSION_ATLEAST(2, 0, 9)
|
||||
bool acquiredGameController = false;
|
||||
bool acquiredHaptic = false;
|
||||
#endif
|
||||
|
||||
if (options.joystick) {
|
||||
if (!retainSubsystem(SDL_INIT_JOYSTICK, s_JoystickRefs, "joystick", ownerTag)) {
|
||||
return false;
|
||||
}
|
||||
acquiredJoystick = true;
|
||||
}
|
||||
|
||||
if (options.gameController) {
|
||||
if (!retainSubsystem(SDL_INIT_GAMECONTROLLER, s_GameControllerRefs, "gamecontroller", ownerTag)) {
|
||||
if (acquiredJoystick) {
|
||||
releaseSubsystem(SDL_INIT_JOYSTICK, s_JoystickRefs, "joystick", ownerTag);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#if !SDL_VERSION_ATLEAST(2, 0, 9)
|
||||
acquiredGameController = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !SDL_VERSION_ATLEAST(2, 0, 9)
|
||||
if (options.haptic) {
|
||||
if (!retainSubsystem(SDL_INIT_HAPTIC, s_HapticRefs, "haptic", ownerTag)) {
|
||||
if (acquiredGameController) {
|
||||
releaseSubsystem(SDL_INIT_GAMECONTROLLER, s_GameControllerRefs, "gamecontroller", ownerTag);
|
||||
}
|
||||
if (acquiredJoystick) {
|
||||
releaseSubsystem(SDL_INIT_JOYSTICK, s_JoystickRefs, "joystick", ownerTag);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
acquiredHaptic = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (options.applyMappings) {
|
||||
MappingManager mappingManager;
|
||||
mappingManager.applyMappings();
|
||||
}
|
||||
|
||||
if (options.flushControllerDeviceEvents) {
|
||||
SDL_FlushEvent(SDL_CONTROLLERDEVICEADDED);
|
||||
SDL_FlushEvent(SDL_CONTROLLERDEVICEREMOVED);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void release(const char* ownerTag, const LeaseOptions& options)
|
||||
{
|
||||
#if !SDL_VERSION_ATLEAST(2, 0, 9)
|
||||
if (options.haptic) {
|
||||
releaseSubsystem(SDL_INIT_HAPTIC, s_HapticRefs, "haptic", ownerTag);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (options.gameController) {
|
||||
releaseSubsystem(SDL_INIT_GAMECONTROLLER, s_GameControllerRefs, "gamecontroller", ownerTag);
|
||||
}
|
||||
|
||||
if (options.joystick) {
|
||||
releaseSubsystem(SDL_INIT_JOYSTICK, s_JoystickRefs, "joystick", ownerTag);
|
||||
}
|
||||
}
|
||||
|
||||
bool hasExclusiveGamepadOwnership()
|
||||
{
|
||||
if (s_JoystickRefs != 1 || s_GameControllerRefs != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !SDL_VERSION_ATLEAST(2, 0, 9)
|
||||
if (s_HapticRefs != 1) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool reenumerateGamepadSubsystems(const char* ownerTag)
|
||||
{
|
||||
if (!hasExclusiveGamepadOwnership()) {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Skipping subsystem re-enumeration for %s due to shared ownership (joystick=%d gamecontroller=%d)",
|
||||
ownerTag,
|
||||
s_JoystickRefs,
|
||||
s_GameControllerRefs);
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !SDL_VERSION_ATLEAST(2, 0, 9)
|
||||
SDL_QuitSubSystem(SDL_INIT_HAPTIC);
|
||||
#endif
|
||||
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
|
||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||
|
||||
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Failed to reinitialize joystick subsystem for %s: %s",
|
||||
ownerTag,
|
||||
SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) != 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Failed to reinitialize gamecontroller subsystem for %s: %s",
|
||||
ownerTag,
|
||||
SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !SDL_VERSION_ATLEAST(2, 0, 9)
|
||||
if (SDL_InitSubSystem(SDL_INIT_HAPTIC) != 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Failed to reinitialize haptic subsystem for %s: %s",
|
||||
ownerTag,
|
||||
SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
MappingManager mappingManager;
|
||||
mappingManager.applyMappings();
|
||||
|
||||
SDL_JoystickUpdate();
|
||||
SDL_GameControllerUpdate();
|
||||
|
||||
SDL_FlushEvents(SDL_JOYDEVICEADDED, SDL_JOYDEVICEREMOVED);
|
||||
SDL_FlushEvents(SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEREMAPPED);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue