[SDL2] Event handler in separate function

This commit is contained in:
Joel Linn 2020-12-01 01:33:21 +01:00 committed by Rick Gibbed
parent d3c618404a
commit 4e72167c5e
2 changed files with 55 additions and 46 deletions

View File

@ -76,54 +76,29 @@ X_STATUS SDLInputDriver::Setup() {
} }
sdl_events_initialized_ = true; sdl_events_initialized_ = true;
SDL_EventFilter event_filter{[](void* userdata, SDL_Event* event) -> int { // 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(
[](void* userdata, SDL_Event* event) -> int {
if (!userdata || !event) { if (!userdata || !event) {
assert_always(); assert_always();
return 0; 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; const auto type = event->type;
if (type < SDL_JOYAXISMOTION || type > SDL_CONTROLLERDEVICEREMAPPED) { if (type < SDL_JOYAXISMOTION || type >= SDL_FINGERDOWN) {
return 0; return 0;
} }
// If another part of xenia uses another SDL subsystem that generates // If another part of xenia uses another SDL subsystem that generates
// events, this may seem like a bad idea. They will however not subscribe // events, this may seem like a bad idea. They will however not
// to controller events so we get away with that. // subscribe to controller events so we get away with that.
const auto driver = static_cast<SDLInputDriver*>(userdata); const auto driver = static_cast<SDLInputDriver*>(userdata);
// The queue could grow up to 3.5MB since it is never polled. driver->HandleEvent(*event);
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; return 0;
}}; },
// With an event watch we will always get notified, even if the event queue this);
// is full, which can happen if another subsystem does not clear its events.
SDL_AddEventWatch(event_filter, this);
if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) < 0) { if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) < 0) {
return; return;
@ -403,6 +378,39 @@ X_RESULT SDLInputDriver::GetKeystroke(uint32_t users, uint32_t flags,
return X_ERROR_EMPTY; 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) { void SDLInputDriver::OnControllerDeviceAdded(const SDL_Event& event) {
std::unique_lock<std::mutex> guard(controllers_mutex_); std::unique_lock<std::mutex> guard(controllers_mutex_);

View File

@ -66,6 +66,7 @@ class SDLInputDriver : public InputDriver {
}; };
protected: protected:
void HandleEvent(const SDL_Event& event);
void OnControllerDeviceAdded(const SDL_Event& event); void OnControllerDeviceAdded(const SDL_Event& event);
void OnControllerDeviceRemoved(const SDL_Event& event); void OnControllerDeviceRemoved(const SDL_Event& event);
void OnControllerDeviceAxisMotion(const SDL_Event& event); void OnControllerDeviceAxisMotion(const SDL_Event& event);