From 4e72167c5e7c0f51c8e844b049728e3d1609a231 Mon Sep 17 00:00:00 2001 From: Joel Linn Date: Tue, 1 Dec 2020 01:33:21 +0100 Subject: [PATCH] [SDL2] Event handler in separate function --- src/xenia/hid/sdl/sdl_input_driver.cc | 100 ++++++++++++++------------ src/xenia/hid/sdl/sdl_input_driver.h | 1 + 2 files changed, 55 insertions(+), 46 deletions(-) diff --git a/src/xenia/hid/sdl/sdl_input_driver.cc b/src/xenia/hid/sdl/sdl_input_driver.cc index ac5f18f9f..27a00c80d 100644 --- a/src/xenia/hid/sdl/sdl_input_driver.cc +++ b/src/xenia/hid/sdl/sdl_input_driver.cc @@ -76,54 +76,29 @@ X_STATUS SDLInputDriver::Setup() { } sdl_events_initialized_ = true; - SDL_EventFilter event_filter{[](void* userdata, SDL_Event* event) -> int { - if (!userdata || !event) { - assert_always(); - return 0; - } - // This callback will likely run on the thread that posts the event, which - // may be a dedicated thread SDL has created for the joystick subsystem. - - // Event queue should never be (this) full - assert(SDL_PeepEvents(nullptr, 0, SDL_PEEKEVENT, SDL_FIRSTEVENT, - SDL_LASTEVENT) < 0xFFFF); - - const auto type = event->type; - if (type < SDL_JOYAXISMOTION || type > SDL_CONTROLLERDEVICEREMAPPED) { - return 0; - } - - // If another part of xenia uses another SDL subsystem that generates - // events, this may seem like a bad idea. They will however not subscribe - // to controller events so we get away with that. - const auto driver = static_cast(userdata); - // The queue could grow up to 3.5MB since it is never polled. - if (++driver->sdl_events_unflushed_ > 64) { - SDL_FlushEvents(SDL_JOYAXISMOTION, SDL_CONTROLLERDEVICEREMAPPED); - driver->sdl_events_unflushed_ = 0; - } - switch (type) { - case SDL_CONTROLLERDEVICEADDED: - driver->OnControllerDeviceAdded(*event); - break; - case SDL_CONTROLLERDEVICEREMOVED: - driver->OnControllerDeviceRemoved(*event); - break; - case SDL_CONTROLLERAXISMOTION: - driver->OnControllerDeviceAxisMotion(*event); - break; - case SDL_CONTROLLERBUTTONDOWN: - case SDL_CONTROLLERBUTTONUP: - driver->OnControllerDeviceButtonChanged(*event); - break; - default: - break; - } - return 0; - }}; // With an event watch we will always get notified, even if the event queue // is full, which can happen if another subsystem does not clear its events. - SDL_AddEventWatch(event_filter, this); + SDL_AddEventWatch( + [](void* userdata, SDL_Event* event) -> int { + if (!userdata || !event) { + assert_always(); + return 0; + } + + const auto type = event->type; + if (type < SDL_JOYAXISMOTION || type >= SDL_FINGERDOWN) { + return 0; + } + + // If another part of xenia uses another SDL subsystem that generates + // events, this may seem like a bad idea. They will however not + // subscribe to controller events so we get away with that. + const auto driver = static_cast(userdata); + driver->HandleEvent(*event); + + return 0; + }, + this); if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) < 0) { return; @@ -403,6 +378,39 @@ X_RESULT SDLInputDriver::GetKeystroke(uint32_t users, uint32_t flags, return X_ERROR_EMPTY; } +void SDLInputDriver::HandleEvent(const SDL_Event& event) { + // This callback will likely run on the thread that posts the event, which + // may be a dedicated thread SDL has created for the joystick subsystem. + + // Event queue should never be (this) full + assert(SDL_PeepEvents(nullptr, 0, SDL_PEEKEVENT, SDL_FIRSTEVENT, + SDL_LASTEVENT) < 0xFFFF); + + // The queue could grow up to 3.5MB since it is never polled. + if (++sdl_events_unflushed_ > 64) { + SDL_FlushEvents(SDL_JOYAXISMOTION, SDL_FINGERDOWN - 1); + sdl_events_unflushed_ = 0; + } + switch (event.type) { + case SDL_CONTROLLERDEVICEADDED: + OnControllerDeviceAdded(event); + break; + case SDL_CONTROLLERDEVICEREMOVED: + OnControllerDeviceRemoved(event); + break; + case SDL_CONTROLLERAXISMOTION: + OnControllerDeviceAxisMotion(event); + break; + case SDL_CONTROLLERBUTTONDOWN: + case SDL_CONTROLLERBUTTONUP: + OnControllerDeviceButtonChanged(event); + break; + default: + break; + } + return; +} + void SDLInputDriver::OnControllerDeviceAdded(const SDL_Event& event) { std::unique_lock guard(controllers_mutex_); diff --git a/src/xenia/hid/sdl/sdl_input_driver.h b/src/xenia/hid/sdl/sdl_input_driver.h index 4ccc76afc..367206cdb 100644 --- a/src/xenia/hid/sdl/sdl_input_driver.h +++ b/src/xenia/hid/sdl/sdl_input_driver.h @@ -66,6 +66,7 @@ class SDLInputDriver : public InputDriver { }; protected: + void HandleEvent(const SDL_Event& event); void OnControllerDeviceAdded(const SDL_Event& event); void OnControllerDeviceRemoved(const SDL_Event& event); void OnControllerDeviceAxisMotion(const SDL_Event& event);