[SDL2] Event handler in separate function
This commit is contained in:
parent
d3c618404a
commit
4e72167c5e
|
@ -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 {
|
|
||||||
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<SDLInputDriver*>(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
|
// 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.
|
// 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<SDLInputDriver*>(userdata);
|
||||||
|
driver->HandleEvent(*event);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
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_);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue