diff --git a/SDL2pp/Private/EventDispatching.hh b/SDL2pp/Private/EventDispatching.hh index 7299bca..63b01b6 100644 --- a/SDL2pp/Private/EventDispatching.hh +++ b/SDL2pp/Private/EventDispatching.hh @@ -27,30 +27,371 @@ #include #include - -#include -using namespace std; +#include namespace SDL2pp { namespace Private { + template + void DispatchEventToObject(const EventType &event, EventHandler&& eventHandler) { + eventHandler.HandleEvent(event); + } + + template + void DispatchEventToFunctor(const EventType &event, EventHandler&& eventHandler) { + eventHandler(event); + } + template auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type { - eventHandler.HandleEvent(event); + DispatchEventToObject(event, eventHandler); } template auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type { - eventHandler(event); + DispatchEventToFunctor(event, eventHandler); + } + +#if SDL_VERSION_ATLEAST(2, 0, 5) + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_AUDIODEVICEADDED || event.type == SDL_AUDIODEVICEREMOVED) + DispatchEventToObject(event.type, eventHandler); } template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_AUDIODEVICEADDED || event.type == SDL_AUDIODEVICEREMOVED) + DispatchEventToFunctor(event.type, eventHandler); + } +#endif + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_CONTROLLERAXISMOTION) + DispatchEventToObject(event.caxis, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_CONTROLLERAXISMOTION) + DispatchEventToFunctor(event.caxis, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_CONTROLLERBUTTONDOWN || event.type == SDL_CONTROLLERBUTTONDOWN) + DispatchEventToObject(event.cbutton, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_CONTROLLERBUTTONDOWN || event.type == SDL_CONTROLLERBUTTONDOWN) + DispatchEventToFunctor(event.cbutton, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_CONTROLLERDEVICEADDED || event.type == SDL_CONTROLLERDEVICEREMOVED || event.type == SDL_CONTROLLERDEVICEREMAPPED) + DispatchEventToObject(event.cdevice, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_CONTROLLERDEVICEADDED || event.type == SDL_CONTROLLERDEVICEREMOVED || event.type == SDL_CONTROLLERDEVICEREMAPPED) + DispatchEventToFunctor(event.cdevice, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_DOLLARGESTURE || event.type == SDL_DOLLARRECORD) + DispatchEventToObject(event.dgesture, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_DOLLARGESTURE || event.type == SDL_DOLLARRECORD) + DispatchEventToFunctor(event.dgesture, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_DROPFILE || event.type == SDL_DROPTEXT +#if SDL_VERSION_ATLEAST(2, 0, 5) + || event.type == SDL_DROPBEGIN || event.type == SDL_DROPCOMPLETE +#endif + ) + DispatchEventToObject(event.drop, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_DROPFILE || event.type == SDL_DROPTEXT +#if SDL_VERSION_ATLEAST(2, 0, 5) + || event.type == SDL_DROPBEGIN || event.type == SDL_DROPCOMPLETE +#endif + ) + DispatchEventToObject(event.drop, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_JOYAXISMOTION) + DispatchEventToObject(event.jaxis, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_JOYAXISMOTION) + DispatchEventToFunctor(event.jaxis, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_JOYBALLMOTION) + DispatchEventToObject(event.jball, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_JOYBALLMOTION) + DispatchEventToFunctor(event.jball, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_JOYBUTTONDOWN || event.type == SDL_JOYBUTTONUP) + DispatchEventToObject(event.jbutton, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_JOYBUTTONDOWN || event.type == SDL_JOYBUTTONUP) + DispatchEventToFunctor(event.jbutton, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_JOYDEVICEADDED || event.type == SDL_JOYDEVICEREMOVED) + DispatchEventToObject(event.jdevice, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_JOYDEVICEADDED || event.type == SDL_JOYDEVICEREMOVED) + DispatchEventToFunctor(event.jdevice, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_JOYHATMOTION) + DispatchEventToObject(event.jhat, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_JOYHATMOTION) + DispatchEventToFunctor(event.jhat, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) + DispatchEventToObject(event.key, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) + DispatchEventToFunctor(event.key, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP) + DispatchEventToObject(event.button, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP) + DispatchEventToFunctor(event.button, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_MOUSEMOTION) + DispatchEventToObject(event.motion, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_MOUSEMOTION) + DispatchEventToFunctor(event.motion, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_MOUSEWHEEL) + DispatchEventToObject(event.wheel, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_MOUSEWHEEL) + DispatchEventToFunctor(event.wheel, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_MULTIGESTURE) + DispatchEventToObject(event.mgesture, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_MULTIGESTURE) + DispatchEventToFunctor(event.mgesture, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_QUIT) + DispatchEventToObject(event.quit, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_QUIT) + DispatchEventToFunctor(event.quit, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_SYSWMEVENT) + DispatchEventToObject(event.syswm, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_SYSWMEVENT) + DispatchEventToFunctor(event.syswm, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_TEXTEDITING) + DispatchEventToObject(event.edit, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_TEXTEDITING) + DispatchEventToFunctor(event.edit, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_TEXTINPUT) + DispatchEventToObject(event.text, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_TEXTINPUT) + DispatchEventToFunctor(event.text, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_FINGERMOTION || event.type == SDL_FINGERDOWN || event.type == SDL_FINGERUP) + DispatchEventToObject(event.tfinger, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_FINGERMOTION || event.type == SDL_FINGERDOWN || event.type == SDL_FINGERUP) + DispatchEventToFunctor(event.tfinger, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_USEREVENT) + DispatchEventToObject(event.user, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_USEREVENT) + DispatchEventToFunctor(event.user, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_WINDOWEVENT) + DispatchEventToObject(event.window, eventHandler); + } + + template + auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if::value>::type + { + if (event.type == SDL_WINDOWEVENT) + DispatchEventToFunctor(event.window, eventHandler); + } + + // TODO: Find an easy way to make IsEventHandler + /*template auto DispatchSpecificEvent(const SDL_Event &, EventHandler&&) -> typename std::enable_if::value>::type { static_assert(IsEventHandler::value, "Event handler is not a valid functor or object"); - } + }*/ template void DispatchEvent(const SDL_Event &, EventHandlers&&...); diff --git a/tests/test_eventdispatching.cc b/tests/test_eventdispatching.cc index e7fca38..183505f 100644 --- a/tests/test_eventdispatching.cc +++ b/tests/test_eventdispatching.cc @@ -54,4 +54,16 @@ auto eventHandlerObject = EventHandlerObject{}; DispatchEvent(event, eventHandlerObject); EXPECT_EQUAL(event.user.code, eventHandlerObject.result); +struct SpecificEventHandler { + Sint32 result; + + void HandleEvent(SDL_UserEvent event) { + result = event.code; + } +}; + +auto specificEventHandler = SpecificEventHandler{}; +DispatchEvent(event, specificEventHandler); +EXPECT_EQUAL(event.user.code, specificEventHandler.result); + END_TEST()