Changed event dispatching to use EventTypeFilter and all the EventTypes

This commit is contained in:
Vraiment 2017-08-08 02:00:22 -07:00
parent 09268ce431
commit b470eae400
2 changed files with 220 additions and 404 deletions

View File

@ -22,386 +22,139 @@
#ifndef SDL2PP_PRIVATE_EVENTDISPATCHING_HH
#define SDL2PP_PRIVATE_EVENTDISPATCHING_HH
#include <SDL2pp/Private/EventHandler.hh>
#include <type_traits>
#include <SDL_events.h>
#include <SDL_version.h>
#include <SDL2pp/Private/EventTypeFilters.hh>
namespace SDL2pp {
namespace Private
{
/*
* This is code not to be used directly by users of SDL2pp.
*/
namespace Private {
/*
* Templated function to dynamically dispatch an event of type EventType to an event handler functor of type EventHandler.
*
* This will be only called if 'eventHandler(event)'
*/
template <typename EventHandler, typename EventType>
void DispatchEventToObject(const EventType &event, EventHandler&& eventHandler) {
eventHandler.HandleEvent(event);
}
template <typename EventHandler, typename EventType>
void DispatchEventToFunctor(const EventType &event, EventHandler&& eventHandler) {
auto DispatchEventHandlerFunctor(const EventType &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, EventType>::value>::type
{
eventHandler(event);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_Event>::value>::type
/*
* Templated function to do nothing when trying to dispatch an event of type EventType to an invalid event handler functor of type EventHandler.
*/
template <typename EventHandler, typename EventType>
auto DispatchEventHandlerFunctor(const EventType &, EventHandler&&) -> typename std::enable_if<!IsEventHandlerFunctor<EventHandler, EventType>::value>::type
{
DispatchEventToObject(event, eventHandler);
// no-op
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_Event>::value>::type
/*
* Templated function to do nothing when trying to dispatch an event of type EventType to an invalid event handler object of type EventHandler.
*/
template <typename EventHandler, typename EventType>
auto DispatchEventHandlerObject(const EventType &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, EventType>::value>::type
{
DispatchEventToFunctor(event, eventHandler);
eventHandler.HandleEvent(event);
}
#if SDL_VERSION_ATLEAST(2, 0, 5)
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_AudioDeviceEvent>::value>::type
/*
* Templated function to dynamically dispatch an event of type EventType to an event handler object of type EventHandler.
*
* This will be only called if 'eventHandler.HandleEvent(event)'
*/
template <typename EventHandler, typename EventType>
auto DispatchEventHandlerObject(const EventType &, EventHandler&&) -> typename std::enable_if<!IsEventHandlerObject<EventHandler, EventType>::value>::type
{
if (event.type == SDL_AUDIODEVICEADDED || event.type == SDL_AUDIODEVICEREMOVED)
DispatchEventToObject(event.type, eventHandler);
// no-op
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_AudioDeviceEvent>::value>::type
{
if (event.type == SDL_AUDIODEVICEADDED || event.type == SDL_AUDIODEVICEREMOVED)
DispatchEventToFunctor(event.type, eventHandler);
}
#endif
/*
* Templated class to dispatch an event to a given event handler:
*
* EventHandler is the type of the event handler
* ValidEventHandler is a boolean to detect if the event was actially valid for any of the event types
* EvenTypes is a tuple containing a list of valid event types
*
* Basically, this class would be roughly the equivalent of the following pseudocode:
*
* DispatchEvent(SDL_Event event, EventHandler eventHandler, EventTypes eventTypes) {
* auto validEventHandler = false;
*
* for (auto eventType : eventTypes) {
* validEventHandler |= IsValidEventHandler(EventHandler, eventType);
* if (ShouldHandleEvent(event)) {
* DispatchEventToFunctor(event, eventHandler);
* DispatchEventToObject(event, eventHandler);
* }
* }
*
* if (!validEventHandler) throw;
* }
*/
template <typename EventHandler, bool ValidEventHandler, typename... EventTypes>
struct EventDispatcher;
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_ControllerAxisEvent>::value>::type
{
if (event.type == SDL_CONTROLLERAXISMOTION)
DispatchEventToObject(event.caxis, eventHandler);
}
/*
* Instatiation of the class to dispatch an event to a given event handler, expansion to a given type:
*
* The head of the tuple is "peeled" and used to dispatch the event to the event handler.
* The tail then is passed to another expansion of EventDispatcher along with the calculated value of IsEventHandler
*
*/
template <typename EventHandler, bool ValidEventHandler, typename EventType, typename... EventTypes>
struct EventDispatcher<EventHandler, ValidEventHandler, std::tuple<EventType, EventTypes...>> {
static constexpr bool IsValidEventHandler = ValidEventHandler || IsEventHandler<EventHandler, EventType>::value;
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_ControllerAxisEvent>::value>::type
{
if (event.type == SDL_CONTROLLERAXISMOTION)
DispatchEventToFunctor(event.caxis, eventHandler);
}
using Filter = EventTypeFilter<EventType>;
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_ControllerButtonEvent>::value>::type
{
if (event.type == SDL_CONTROLLERBUTTONDOWN || event.type == SDL_CONTROLLERBUTTONDOWN)
DispatchEventToObject(event.cbutton, eventHandler);
}
static void DispatchEvent(const SDL_Event &event, EventHandler&& eventHandler) {
if (Filter::ShouldHandleEvent(event)) {
DispatchEventHandlerFunctor(Filter::GetEventByType(event), std::forward<EventHandler>(eventHandler));
DispatchEventHandlerObject(Filter::GetEventByType(event), std::forward<EventHandler>(eventHandler));
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_ControllerButtonEvent>::value>::type
{
if (event.type == SDL_CONTROLLERBUTTONDOWN || event.type == SDL_CONTROLLERBUTTONDOWN)
DispatchEventToFunctor(event.cbutton, eventHandler);
}
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_ControllerDeviceEvent>::value>::type
{
if (event.type == SDL_CONTROLLERDEVICEADDED || event.type == SDL_CONTROLLERDEVICEREMOVED || event.type == SDL_CONTROLLERDEVICEREMAPPED)
DispatchEventToObject(event.cdevice, eventHandler);
}
EventDispatcher<EventHandler, IsValidEventHandler, std::tuple<EventTypes...>>::DispatchEvent(event, std::forward<EventHandler>(eventHandler));
}
};
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_ControllerDeviceEvent>::value>::type
{
if (event.type == SDL_CONTROLLERDEVICEADDED || event.type == SDL_CONTROLLERDEVICEREMOVED || event.type == SDL_CONTROLLERDEVICEREMAPPED)
DispatchEventToFunctor(event.cdevice, eventHandler);
}
/*
* Instantiation of the class to dispatch an event to a given event handler, final expansion:
*
* The tuple of valid event types is empty and the value of the ValidEventHandler boolean
* is placed in the IsValidEventHandler variable, finally when an event gets dispatched
* an static_assert happens to verify if the event handler actually handled any events.
*/
template <typename EventHandler, bool ValidEventHandler>
struct EventDispatcher<EventHandler, ValidEventHandler, std::tuple<>> {
static constexpr auto IsValidEventHandler = ValidEventHandler;
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_DollarGestureEvent>::value>::type
{
if (event.type == SDL_DOLLARGESTURE || event.type == SDL_DOLLARRECORD)
DispatchEventToObject(event.dgesture, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_DollarGestureEvent>::value>::type
{
if (event.type == SDL_DOLLARGESTURE || event.type == SDL_DOLLARRECORD)
DispatchEventToFunctor(event.dgesture, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_DropEvent>::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 <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_DropEvent>::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 <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_JoyAxisEvent>::value>::type
{
if (event.type == SDL_JOYAXISMOTION)
DispatchEventToObject(event.jaxis, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_JoyAxisEvent>::value>::type
{
if (event.type == SDL_JOYAXISMOTION)
DispatchEventToFunctor(event.jaxis, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_JoyBallEvent>::value>::type
{
if (event.type == SDL_JOYBALLMOTION)
DispatchEventToObject(event.jball, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_JoyBallEvent>::value>::type
{
if (event.type == SDL_JOYBALLMOTION)
DispatchEventToFunctor(event.jball, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_JoyButtonEvent>::value>::type
{
if (event.type == SDL_JOYBUTTONDOWN || event.type == SDL_JOYBUTTONUP)
DispatchEventToObject(event.jbutton, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_JoyButtonEvent>::value>::type
{
if (event.type == SDL_JOYBUTTONDOWN || event.type == SDL_JOYBUTTONUP)
DispatchEventToFunctor(event.jbutton, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_JoyDeviceEvent>::value>::type
{
if (event.type == SDL_JOYDEVICEADDED || event.type == SDL_JOYDEVICEREMOVED)
DispatchEventToObject(event.jdevice, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_JoyDeviceEvent>::value>::type
{
if (event.type == SDL_JOYDEVICEADDED || event.type == SDL_JOYDEVICEREMOVED)
DispatchEventToFunctor(event.jdevice, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_JoyHatEvent>::value>::type
{
if (event.type == SDL_JOYHATMOTION)
DispatchEventToObject(event.jhat, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_JoyHatEvent>::value>::type
{
if (event.type == SDL_JOYHATMOTION)
DispatchEventToFunctor(event.jhat, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_KeyboardEvent>::value>::type
{
if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP)
DispatchEventToObject(event.key, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_KeyboardEvent>::value>::type
{
if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP)
DispatchEventToFunctor(event.key, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_MouseButtonEvent>::value>::type
{
if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP)
DispatchEventToObject(event.button, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_MouseButtonEvent>::value>::type
{
if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP)
DispatchEventToFunctor(event.button, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_MouseMotionEvent>::value>::type
{
if (event.type == SDL_MOUSEMOTION)
DispatchEventToObject(event.motion, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_MouseMotionEvent>::value>::type
{
if (event.type == SDL_MOUSEMOTION)
DispatchEventToFunctor(event.motion, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_MouseWheelEvent>::value>::type
{
if (event.type == SDL_MOUSEWHEEL)
DispatchEventToObject(event.wheel, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_MouseWheelEvent>::value>::type
{
if (event.type == SDL_MOUSEWHEEL)
DispatchEventToFunctor(event.wheel, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_MultiGestureEvent>::value>::type
{
if (event.type == SDL_MULTIGESTURE)
DispatchEventToObject(event.mgesture, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_MultiGestureEvent>::value>::type
{
if (event.type == SDL_MULTIGESTURE)
DispatchEventToFunctor(event.mgesture, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_QuitEvent>::value>::type
{
if (event.type == SDL_QUIT)
DispatchEventToObject(event.quit, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_QuitEvent>::value>::type
{
if (event.type == SDL_QUIT)
DispatchEventToFunctor(event.quit, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_SysWMEvent>::value>::type
{
if (event.type == SDL_SYSWMEVENT)
DispatchEventToObject(event.syswm, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_SysWMEvent>::value>::type
{
if (event.type == SDL_SYSWMEVENT)
DispatchEventToFunctor(event.syswm, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_TextEditingEvent>::value>::type
{
if (event.type == SDL_TEXTEDITING)
DispatchEventToObject(event.edit, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_TextEditingEvent>::value>::type
{
if (event.type == SDL_TEXTEDITING)
DispatchEventToFunctor(event.edit, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_TextInputEvent>::value>::type
{
if (event.type == SDL_TEXTINPUT)
DispatchEventToObject(event.text, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_TextInputEvent>::value>::type
{
if (event.type == SDL_TEXTINPUT)
DispatchEventToFunctor(event.text, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_TouchFingerEvent>::value>::type
{
if (event.type == SDL_FINGERMOTION || event.type == SDL_FINGERDOWN || event.type == SDL_FINGERUP)
DispatchEventToObject(event.tfinger, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_TouchFingerEvent>::value>::type
{
if (event.type == SDL_FINGERMOTION || event.type == SDL_FINGERDOWN || event.type == SDL_FINGERUP)
DispatchEventToFunctor(event.tfinger, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_UserEvent>::value>::type
{
if (event.type == SDL_USEREVENT)
DispatchEventToObject(event.user, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_UserEvent>::value>::type
{
if (event.type == SDL_USEREVENT)
DispatchEventToFunctor(event.user, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandler, SDL_WindowEvent>::value>::type
{
if (event.type == SDL_WINDOWEVENT)
DispatchEventToObject(event.window, eventHandler);
}
template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &event, EventHandler&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandler, SDL_WindowEvent>::value>::type
{
if (event.type == SDL_WINDOWEVENT)
DispatchEventToFunctor(event.window, eventHandler);
}
// TODO: Find an easy way to make IsEventHandler<EventHandler, ANY_EVENT>
/*template <typename EventHandler>
auto DispatchSpecificEvent(const SDL_Event &, EventHandler&&) -> typename std::enable_if<!IsEventHandler<EventHandler, SDL_Event>::value>::type
{
static_assert(IsEventHandler<EventHandler, SDL_Event>::value, "Event handler is not a valid functor or object");
}*/
static void DispatchEvent(const SDL_Event &, EventHandler&&) {
static_assert(IsValidEventHandler, "One of the given event handlers is not a valid one");
}
};
/*
* Templated class expand a list of event handlers so they can be dispatched.
*/
template <typename... EventHandlers>
void DispatchEvent(const SDL_Event &, EventHandlers&&...);
/*
* Instantiation of the class to expand a list of event handlers so they can be dispatched.
*
* This "peels" the first event handler from the arguments, dispatchs it and then expands the tail of the list.
*/
template <typename EventHandler, typename... EventHandlers>
void DispatchEvent(const SDL_Event &event, EventHandler&& eventHandler, EventHandlers&&... eventHandlers) {
DispatchSpecificEvent(event, eventHandler);
EventDispatcher<EventHandler, false, ValidEventTypes>::DispatchEvent(event, std::forward<EventHandler>(eventHandler));
DispatchEvent(event, eventHandlers...);
}
/*
* Instantiation of the class to expand a list of event handlers, when the list is empty.
*/
template <>
void DispatchEvent(const SDL_Event &) {
// no-op

View File

@ -6,64 +6,127 @@
using namespace SDL2pp::Private;
static auto globalResult = Sint32{0};
namespace TestFreeFunctions {
static auto globalResult = Sint32{0};
inline void handler(SDL_Event event)
{
globalResult = event.user.code;
inline void handler(SDL_Event event) {
globalResult = event.user.code;
}
}
BEGIN_TEST(int, char*[])
// These test require a major rework, commenting everything in the mean time
SDL_Event event;
event.type = SDL_QUIT;
event.user.code = 31;
SDL_Event event;
event.type = SDL_USEREVENT;
event.user.code = 31;
// Test dispatching with no event handler
DispatchEvent(event);
DispatchEvent(event);
auto result = Sint32{0};
DispatchEvent(event, [&result](SDL_Event event) {
result = event.user.code;
});
EXPECT_EQUAL(event.user.code, result);
DispatchEvent(event, handler);
EXPECT_EQUAL(event.user.code, globalResult);
struct EventHandlerFunctor {
Sint32 result;
void operator()(SDL_Event event) {
result = event.user.code;
// Test dispatching with lambda as event handler
{
auto result = Sint32{0};
DispatchEvent(event, [&result](SDL_Event event) {
result = event.user.code;
});
EXPECT_EQUAL(event.user.code, result);
}
};
auto eventHandlerFunctor = EventHandlerFunctor{};
DispatchEvent(event, eventHandlerFunctor);
EXPECT_EQUAL(event.user.code, eventHandlerFunctor.result);
struct EventHandlerObject {
Sint32 result;
void HandleEvent(SDL_Event event) {
result = event.user.code;
// Test dispatching with function as event handler
{
DispatchEvent(event, TestFreeFunctions::handler);
EXPECT_EQUAL(event.user.code, TestFreeFunctions::globalResult);
}
};
auto eventHandlerObject = EventHandlerObject{};
DispatchEvent(event, eventHandlerObject);
EXPECT_EQUAL(event.user.code, eventHandlerObject.result);
// Test dispatching with a functor as event handler
{
struct EventHandlerFunctor {
Sint32 result;
struct SpecificEventHandler {
Sint32 result;
void operator()(SDL_Event event) {
result = event.user.code;
}
};
void HandleEvent(SDL_UserEvent event) {
result = event.code;
auto eventHandlerFunctor = EventHandlerFunctor{};
DispatchEvent(event, eventHandlerFunctor);
EXPECT_EQUAL(event.user.code, eventHandlerFunctor.result);
}
};
auto specificEventHandler = SpecificEventHandler{};
DispatchEvent(event, specificEventHandler);
EXPECT_EQUAL(event.user.code, specificEventHandler.result);
// Test dispatching with an object as event handler
{
struct EventHandlerObject {
Sint32 result;
void HandleEvent(SDL_Event event) {
result = event.user.code;
}
};
auto eventHandlerObject = EventHandlerObject{};
DispatchEvent(event, eventHandlerObject);
EXPECT_EQUAL(event.user.code, eventHandlerObject.result);
}
// Test several event handlers
{
struct EventHandlerFunctor {
bool executed = false;
void operator()(SDL_QuitEvent) {
executed = true;
}
};
auto eventHandlerFunctor1 = EventHandlerFunctor{};
auto eventHandlerFunctor2 = EventHandlerFunctor{};
struct EventHandlerObject {
bool executed = false;
void HandleEvent(SDL_QuitEvent) {
executed = true;
}
};
auto eventHandlerObject = EventHandlerObject{};
auto lambdaExecuted = false;
auto lambda = [&lambdaExecuted](SDL_QuitEvent) { lambdaExecuted = true; };
DispatchEvent(event, eventHandlerFunctor1, eventHandlerFunctor2, eventHandlerObject, lambda);
EXPECT_TRUE(eventHandlerFunctor1.executed);
EXPECT_TRUE(eventHandlerFunctor2.executed);
EXPECT_TRUE(eventHandlerObject.executed);
EXPECT_TRUE(lambdaExecuted);
}
// Test event handler with several event types
{
struct EventHandler {
bool quitEventExecuted = false;
bool keyboardEventExecuted = false;
void HandleEvent(SDL_QuitEvent) {
quitEventExecuted = true;
}
void HandleEvent(SDL_KeyboardEvent) {
keyboardEventExecuted = true;
}
};
auto eventHandler = EventHandler{};
DispatchEvent(event, eventHandler);
EXPECT_TRUE(eventHandler.quitEventExecuted);
EXPECT_TRUE(!eventHandler.keyboardEventExecuted);
eventHandler.quitEventExecuted = false;
event.type = SDL_KEYUP;
DispatchEvent(event, eventHandler);
EXPECT_TRUE(!eventHandler.quitEventExecuted);
EXPECT_TRUE(eventHandler.keyboardEventExecuted);
}
END_TEST()