mirror of
https://github.com/libSDL2pp/libSDL2pp.git
synced 2025-08-04 11:25:58 -04:00
Merge 154eed861dd8e20dbdc741670368b5838e9728b1 into b00d3b9eb98be4fa2eca7ae9d88f96d28796e4f0
This commit is contained in:
commit
39f3b27b9f
@ -106,6 +106,7 @@ set(LIBRARY_HEADERS
|
|||||||
SDL2pp/AudioSpec.hh
|
SDL2pp/AudioSpec.hh
|
||||||
SDL2pp/Color.hh
|
SDL2pp/Color.hh
|
||||||
SDL2pp/ContainerRWops.hh
|
SDL2pp/ContainerRWops.hh
|
||||||
|
SDL2pp/EventPolling.hh
|
||||||
SDL2pp/Exception.hh
|
SDL2pp/Exception.hh
|
||||||
SDL2pp/Optional.hh
|
SDL2pp/Optional.hh
|
||||||
SDL2pp/Point.hh
|
SDL2pp/Point.hh
|
||||||
@ -119,6 +120,10 @@ set(LIBRARY_HEADERS
|
|||||||
SDL2pp/Texture.hh
|
SDL2pp/Texture.hh
|
||||||
SDL2pp/Wav.hh
|
SDL2pp/Wav.hh
|
||||||
SDL2pp/Window.hh
|
SDL2pp/Window.hh
|
||||||
|
SDL2pp/Private/EventDispatching.hh
|
||||||
|
SDL2pp/Private/EventHandler.hh
|
||||||
|
SDL2pp/Private/EventTypeFilters.hh
|
||||||
|
SDL2pp/Private/Utility.hh
|
||||||
)
|
)
|
||||||
|
|
||||||
# optional sources
|
# optional sources
|
||||||
|
@ -21,7 +21,8 @@ INPUT = "@CMAKE_CURRENT_SOURCE_DIR@/SDL2pp" \
|
|||||||
RECURSIVE = YES
|
RECURSIVE = YES
|
||||||
|
|
||||||
# Exclude foreign files
|
# Exclude foreign files
|
||||||
EXCLUDE = "@CMAKE_CURRENT_SOURCE_DIR@/SDL2pp/external"
|
EXCLUDE = "@CMAKE_CURRENT_SOURCE_DIR@/SDL2pp/external" \
|
||||||
|
"@CMAKE_CURRENT_SOURCE_DIR@/SDL2pp/Private"
|
||||||
|
|
||||||
# Examples (doesn't work atm)
|
# Examples (doesn't work atm)
|
||||||
EXAMPLE_PATH = "@CMAKE_CURRENT_SOURCE_DIR@/examples"
|
EXAMPLE_PATH = "@CMAKE_CURRENT_SOURCE_DIR@/examples"
|
||||||
|
102
SDL2pp/EventPolling.hh
Normal file
102
SDL2pp/EventPolling.hh
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
libSDL2pp - C++11 bindings/wrapper for SDL2
|
||||||
|
Copyright (C) 2017 Vraiment <jemc44@gmail.com>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SDL2PP_EVENTPOLLING_HH
|
||||||
|
#define SDL2PP_EVENTPOLLING_HH
|
||||||
|
|
||||||
|
#include <SDL2pp/Private/EventDispatching.hh>
|
||||||
|
|
||||||
|
namespace SDL2pp {
|
||||||
|
namespace Event {
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Polls and handles a single event
|
||||||
|
///
|
||||||
|
/// This function tries to poll a single event from the event
|
||||||
|
/// queue using SDL_PollEvent(). If an event was polled the
|
||||||
|
/// event handler is called using the retrieved SDL_Event as an
|
||||||
|
/// argument then this function returns true. If no event was
|
||||||
|
/// retrieved the event handler is not called and this function
|
||||||
|
/// returns false.
|
||||||
|
///
|
||||||
|
/// This function accepts the following as event handlers:
|
||||||
|
/// - Functors (lambdas, free functions, callable objects)
|
||||||
|
/// - Objects (Objects that have a HandleEvent(EventType) function)
|
||||||
|
///
|
||||||
|
/// \ingroup events
|
||||||
|
///
|
||||||
|
/// \headerfile SDL2pp/EventPolling.hh
|
||||||
|
///
|
||||||
|
/// \param[in] eventHandlers A list of event handlers that will handle the event
|
||||||
|
///
|
||||||
|
/// \returns True if an event was polled, false otherwise
|
||||||
|
///
|
||||||
|
/// \see https://wiki.libsdl.org/SDL_PollEvent
|
||||||
|
/// \see https://wiki.libsdl.org/CategoryEvents#Structures
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
template <typename... EventHandlers>
|
||||||
|
bool PollEvent(EventHandlers&&... eventHandlers) {
|
||||||
|
SDL_Event event;
|
||||||
|
if (!SDL_PollEvent(&event)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Private::DispatchEvent(event, eventHandlers...);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Polls and handles all the events from the event queue
|
||||||
|
///
|
||||||
|
/// This function calls SDL_PollEvent() until the event queue is empty.
|
||||||
|
/// Then for each event that was polled the event handler is called
|
||||||
|
/// using the polled event as an argument. This function returns the
|
||||||
|
/// amount of events that were polled.
|
||||||
|
///
|
||||||
|
/// This function accepts the following as event handlers:
|
||||||
|
/// - Functors (lambdas, free functions, callable objects)
|
||||||
|
/// - Objects (Objects that have a HandleEvent(EventType) function)
|
||||||
|
///
|
||||||
|
/// \ingroup events
|
||||||
|
///
|
||||||
|
/// \headerfile SDL2pp/EventPolling.hh
|
||||||
|
///
|
||||||
|
/// \param[in] eventHandlers A list of event handlers that will handle the polled event
|
||||||
|
///
|
||||||
|
/// \returns The amount of polled events (can be zero)
|
||||||
|
///
|
||||||
|
/// \see https://wiki.libsdl.org/SDL_PollEvent
|
||||||
|
/// \see https://wiki.libsdl.org/CategoryEvents#Structures
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
template <typename... EventHandlers>
|
||||||
|
int PollAllEvents(EventHandlers&&... eventHandlers) {
|
||||||
|
int result;
|
||||||
|
|
||||||
|
for (result = 0; PollEvent(eventHandlers...); result++);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
166
SDL2pp/Private/EventDispatching.hh
Normal file
166
SDL2pp/Private/EventDispatching.hh
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
/*
|
||||||
|
libSDL2pp - C++11 bindings/wrapper for SDL2
|
||||||
|
Copyright (C) 2017 Vraiment <jemc44@gmail.com>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SDL2PP_PRIVATE_EVENTDISPATCHING_HH
|
||||||
|
#define SDL2PP_PRIVATE_EVENTDISPATCHING_HH
|
||||||
|
|
||||||
|
#include <SDL2pp/Private/EventTypeFilters.hh>
|
||||||
|
|
||||||
|
namespace SDL2pp {
|
||||||
|
/*
|
||||||
|
* 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 EventHandlerType.
|
||||||
|
*
|
||||||
|
* This will be only called if 'eventHandler(event)' can be called
|
||||||
|
*/
|
||||||
|
template <typename EventHandlerType, typename EventType>
|
||||||
|
auto DispatchEventHandlerFunctor(const EventType &event, EventHandlerType&& eventHandler) -> typename std::enable_if<IsEventHandlerFunctor<EventHandlerType, EventType>::value>::type
|
||||||
|
{
|
||||||
|
eventHandler(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Templated function to do nothing when trying to dispatch an event of type EventType to an invalid event handler functor of type EventHandlerType.
|
||||||
|
*/
|
||||||
|
template <typename EventHandlerType, typename EventType>
|
||||||
|
auto DispatchEventHandlerFunctor(const EventType &, EventHandlerType&&) -> typename std::enable_if<!IsEventHandlerFunctor<EventHandlerType, EventType>::value>::type
|
||||||
|
{
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Templated function to dynamically dispatch an event of type EventType to an event handler object of type EventHandlerType.
|
||||||
|
*
|
||||||
|
* This will be only called if 'eventHandler.HandleEvent(event)' can be called
|
||||||
|
*/
|
||||||
|
template <typename EventHandlerType, typename EventType>
|
||||||
|
auto DispatchEventHandlerObject(const EventType &event, EventHandlerType&& eventHandler) -> typename std::enable_if<IsEventHandlerObject<EventHandlerType, EventType>::value>::type
|
||||||
|
{
|
||||||
|
eventHandler.HandleEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Templated function to do nothing when trying to dispatch an event of type EventType to an invalid event handler object of type EventHandlerType.
|
||||||
|
*/
|
||||||
|
template <typename EventHandlerType, typename EventType>
|
||||||
|
auto DispatchEventHandlerObject(const EventType &, EventHandlerType&&) -> typename std::enable_if<!IsEventHandlerObject<EventHandlerType, EventType>::value>::type
|
||||||
|
{
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Templated class to dispatch an event to a given event handler:
|
||||||
|
*
|
||||||
|
* ValidEventHandler is a boolean to detect if the event was actially valid for any of the event types
|
||||||
|
* EventHandlerType is the type of the event handler
|
||||||
|
* 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, EventHandlerType 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 <bool ValidEventHandler, typename EventHandlerType, typename... EventTypes>
|
||||||
|
struct EventDispatcher;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 <bool ValidEventHandler, typename EventHandlerType, typename EventType, typename... EventTypes>
|
||||||
|
struct EventDispatcher<ValidEventHandler, EventHandlerType, std::tuple<EventType, EventTypes...>> {
|
||||||
|
static constexpr bool IsValidEventHandler = ValidEventHandler || IsEventHandler<EventHandlerType, EventType>::value;
|
||||||
|
|
||||||
|
using Filter = EventTypeFilter<EventType>;
|
||||||
|
|
||||||
|
static void DispatchEvent(const SDL_Event &event, EventHandlerType&& eventHandler) {
|
||||||
|
if (Filter::ShouldHandleEvent(event)) {
|
||||||
|
DispatchEventHandlerFunctor(Filter::GetEventByType(event), std::forward<EventHandlerType>(eventHandler));
|
||||||
|
DispatchEventHandlerObject(Filter::GetEventByType(event), std::forward<EventHandlerType>(eventHandler));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
EventDispatcher<IsValidEventHandler, EventHandlerType, std::tuple<EventTypes...>>::DispatchEvent(event, std::forward<EventHandlerType>(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 <bool ValidEventHandler, typename EventHandlerType>
|
||||||
|
struct EventDispatcher<ValidEventHandler, EventHandlerType, std::tuple<>> {
|
||||||
|
static constexpr auto IsValidEventHandler = ValidEventHandler;
|
||||||
|
|
||||||
|
static void DispatchEvent(const SDL_Event &, EventHandlerType&&) {
|
||||||
|
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... EventHandlerTypes>
|
||||||
|
void DispatchEvent(const SDL_Event &, EventHandlerTypes&&...);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 EventHandlerType, typename... EventHandlerTypes>
|
||||||
|
void DispatchEvent(const SDL_Event &event, EventHandlerType&& eventHandler, EventHandlerTypes&&... eventHandlers) {
|
||||||
|
EventDispatcher<false, EventHandlerType, ValidEventTypes>::DispatchEvent(event, std::forward<EventHandlerType>(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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
153
SDL2pp/Private/EventHandler.hh
Normal file
153
SDL2pp/Private/EventHandler.hh
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
libSDL2pp - C++11 bindings/wrapper for SDL2
|
||||||
|
Copyright (C) 2017 Vraiment <jemc44@gmail.com>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SDL2PP_PRIVATE_EVENTHANDLER_HH
|
||||||
|
#define SDL2PP_PRIVATE_EVENTHANDLER_HH
|
||||||
|
|
||||||
|
#include <SDL2pp/Private/Utility.hh>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <tuple>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include <SDL_events.h>
|
||||||
|
#include <SDL_version.h>
|
||||||
|
|
||||||
|
namespace SDL2pp {
|
||||||
|
/*
|
||||||
|
* This is code not to be used directly by users of SDL2pp.
|
||||||
|
*/
|
||||||
|
namespace Private {
|
||||||
|
/*
|
||||||
|
* Tuple containing all the valid events that can be handled.
|
||||||
|
*/
|
||||||
|
using ValidEventTypes = std::tuple<
|
||||||
|
SDL_Event,
|
||||||
|
#if SDL_VERSION_ATLEAST(2, 0, 5)
|
||||||
|
SDL_AudioDeviceEvent,
|
||||||
|
#endif
|
||||||
|
SDL_ControllerAxisEvent,
|
||||||
|
SDL_ControllerButtonEvent,
|
||||||
|
SDL_ControllerDeviceEvent,
|
||||||
|
SDL_DollarGestureEvent,
|
||||||
|
SDL_DropEvent,
|
||||||
|
SDL_JoyAxisEvent,
|
||||||
|
SDL_JoyBallEvent,
|
||||||
|
SDL_JoyButtonEvent,
|
||||||
|
SDL_JoyDeviceEvent,
|
||||||
|
SDL_JoyHatEvent,
|
||||||
|
SDL_KeyboardEvent,
|
||||||
|
SDL_MouseButtonEvent,
|
||||||
|
SDL_MouseMotionEvent,
|
||||||
|
SDL_MouseWheelEvent,
|
||||||
|
SDL_MultiGestureEvent,
|
||||||
|
SDL_QuitEvent,
|
||||||
|
SDL_SysWMEvent,
|
||||||
|
SDL_TextEditingEvent,
|
||||||
|
SDL_TextInputEvent,
|
||||||
|
SDL_TouchFingerEvent,
|
||||||
|
SDL_UserEvent,
|
||||||
|
SDL_WindowEvent
|
||||||
|
>;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Templated class to identify a class that is not an event handler functor.
|
||||||
|
*/
|
||||||
|
template <typename, typename, typename = void>
|
||||||
|
struct IsEventHandlerFunctor : std::false_type { };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Templated class to identify a class that is an event handler functor, the
|
||||||
|
* way this is done is by verifying if the functor is assignable to the
|
||||||
|
* expected signature.
|
||||||
|
*/
|
||||||
|
template <typename EventHandlerType, typename EventType>
|
||||||
|
struct IsEventHandlerFunctor<
|
||||||
|
EventHandlerType,
|
||||||
|
EventType,
|
||||||
|
typename std::enable_if<
|
||||||
|
std::is_convertible<EventHandlerType, std::function<void(EventType)>>::value
|
||||||
|
>::type
|
||||||
|
> : std::true_type { };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Templated class to identify a class that is not an event handler object.
|
||||||
|
*/
|
||||||
|
template <typename, typename, typename = void>
|
||||||
|
struct IsEventHandlerObject : std::false_type { };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Templated class to identify a class that is an event handler object, the
|
||||||
|
* way this is done is by verifying that an instance of EventHandlerType has
|
||||||
|
* the "HandleEvent" member function which received a "EventType" and
|
||||||
|
* returns void.
|
||||||
|
*/
|
||||||
|
template <typename EventHandlerType, typename EventType>
|
||||||
|
struct IsEventHandlerObject<
|
||||||
|
EventHandlerType,
|
||||||
|
EventType,
|
||||||
|
typename std::enable_if<
|
||||||
|
std::is_same<
|
||||||
|
decltype(std::declval<EventHandlerType>().HandleEvent(std::declval<EventType>())),
|
||||||
|
void
|
||||||
|
>::value
|
||||||
|
>::type
|
||||||
|
> : std::true_type { };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Templated class to identify a class that is not an event handler.
|
||||||
|
*/
|
||||||
|
template <typename, typename, typename = void>
|
||||||
|
struct IsEventHandler : std::false_type { };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Templated class to identify a type that is an event handler, the type
|
||||||
|
* EventHandlerType is considered to be an event handler if is either an
|
||||||
|
* event handler object or an event handler functor for the given event
|
||||||
|
* type. Also the event type must be a valid SDL event type.
|
||||||
|
*
|
||||||
|
* In other words, any of the following code can be executed:
|
||||||
|
* {
|
||||||
|
* EventType event;
|
||||||
|
* EventHandlerType eventHandler;
|
||||||
|
* eventHandler(event);
|
||||||
|
* // or
|
||||||
|
* eventHandler.HandleEvent(event);
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
template <typename EventHandlerType, typename EventType>
|
||||||
|
struct IsEventHandler<
|
||||||
|
EventHandlerType,
|
||||||
|
EventType,
|
||||||
|
typename std::enable_if<
|
||||||
|
And<
|
||||||
|
Or<
|
||||||
|
IsEventHandlerObject<EventHandlerType, EventType>,
|
||||||
|
IsEventHandlerFunctor<EventHandlerType, EventType>
|
||||||
|
>,
|
||||||
|
TupleHasType<EventType, ValidEventTypes>
|
||||||
|
>::value
|
||||||
|
>::type
|
||||||
|
> : std::true_type { };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
107
SDL2pp/Private/EventTypeFilters.hh
Normal file
107
SDL2pp/Private/EventTypeFilters.hh
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
libSDL2pp - C++11 bindings/wrapper for SDL2
|
||||||
|
Copyright (C) 2017 Vraiment <jemc44@gmail.com>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SDL2PP_PRIVATE_EVENTHANDLERBYTYPE_HH
|
||||||
|
#define SDL2PP_PRIVATE_EVENTHANDLERBYTYPE_HH
|
||||||
|
|
||||||
|
#include <SDL2pp/Private/EventHandler.hh>
|
||||||
|
|
||||||
|
#include <SDL_version.h>
|
||||||
|
|
||||||
|
namespace SDL2pp {
|
||||||
|
/*
|
||||||
|
* This is code not to be used directly by users of SDL2pp.
|
||||||
|
*/
|
||||||
|
namespace Private {
|
||||||
|
/*
|
||||||
|
* Templated struct that is used to:
|
||||||
|
* - Verify an event is of the given type
|
||||||
|
* - Get the specific event for that given type
|
||||||
|
*/
|
||||||
|
template <typename EventType>
|
||||||
|
struct EventTypeFilter {
|
||||||
|
// Should return true if the given event is of the type EventType
|
||||||
|
static bool ShouldHandleEvent(const SDL_Event &);
|
||||||
|
|
||||||
|
// Should return the member of SDL_Event that is of the given EventType
|
||||||
|
static const EventType &GetEventByType(const SDL_Event &event);
|
||||||
|
};
|
||||||
|
|
||||||
|
// SDL_Event is defined without a macro because the arguments are not used
|
||||||
|
// this shutdowns "unnused variables" warnings on some compilers
|
||||||
|
template <>
|
||||||
|
struct EventTypeFilter<SDL_Event> {
|
||||||
|
static bool ShouldHandleEvent(const SDL_Event &) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const SDL_Event &GetEventByType(const SDL_Event &event) {
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// I use a macro here to make things less verbose
|
||||||
|
#define SDL2PP_DEFINE_EVENT_MAPPING(eventType, condition, eventObject) template<>\
|
||||||
|
struct EventTypeFilter<eventType> {\
|
||||||
|
static bool ShouldHandleEvent(const SDL_Event &event) {\
|
||||||
|
return condition;\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
static const eventType &GetEventByType(const SDL_Event &event) {\
|
||||||
|
return eventObject;\
|
||||||
|
}\
|
||||||
|
}
|
||||||
|
|
||||||
|
#if SDL_VERSION_ATLEAST(2, 0, 4)
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_AudioDeviceEvent, event.type == SDL_AUDIODEVICEADDED || event.type == SDL_AUDIODEVICEREMOVED, event.adevice);
|
||||||
|
#endif
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_ControllerAxisEvent, event.type == SDL_CONTROLLERAXISMOTION, event.caxis);
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_ControllerButtonEvent, event.type == SDL_CONTROLLERBUTTONDOWN || event.type == SDL_CONTROLLERBUTTONUP, event.cbutton);
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_ControllerDeviceEvent, event.type == SDL_CONTROLLERDEVICEADDED || event.type == SDL_CONTROLLERDEVICEREMOVED || event.type == SDL_CONTROLLERDEVICEREMAPPED, event.cdevice);
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_DollarGestureEvent, event.type == SDL_DOLLARGESTURE || event.type == SDL_DOLLARRECORD, event.dgesture);
|
||||||
|
#if SDL_VERSION_ATLEAST(2, 0, 5)
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_DropEvent, event.type == SDL_DROPFILE || event.type == SDL_DROPTEXT || event.type == SDL_DROPBEGIN || event.type == SDL_DROPCOMPLETE, event.drop);
|
||||||
|
#else
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_DropEvent, event.type == SDL_DROPFILE, event.drop);
|
||||||
|
#endif
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_JoyAxisEvent, event.type == SDL_JOYAXISMOTION, event.jaxis);
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_JoyBallEvent, event.type == SDL_JOYBALLMOTION, event.jball);
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_JoyButtonEvent, event.type == SDL_JOYBUTTONDOWN || event.type == SDL_JOYBUTTONUP, event.jbutton);
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_JoyDeviceEvent, event.type == SDL_JOYDEVICEADDED || event.type == SDL_JOYDEVICEREMOVED, event.jdevice);
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_JoyHatEvent, event.type == SDL_JOYHATMOTION, event.jhat);
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_KeyboardEvent, event.type == SDL_KEYDOWN || event.type == SDL_KEYUP, event.key);
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_MouseButtonEvent, event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP, event.button);
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_MouseMotionEvent, event.type == SDL_MOUSEMOTION, event.motion);
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_MouseWheelEvent, event.type == SDL_MOUSEWHEEL, event.wheel);
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_MultiGestureEvent, event.type == SDL_MULTIGESTURE, event.mgesture);
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_QuitEvent, event.type == SDL_QUIT, event.quit);
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_SysWMEvent, event.type == SDL_SYSWMEVENT, event.syswm);
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_TextEditingEvent, event.type == SDL_TEXTEDITING, event.edit);
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_TextInputEvent, event.type == SDL_TEXTINPUT, event.text);
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_TouchFingerEvent, event.type == SDL_FINGERMOTION || event.type == SDL_FINGERDOWN || event.type == SDL_FINGERUP, event.tfinger);
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_UserEvent, SDL_USEREVENT <= event.type && event.type <= SDL_LASTEVENT, event.user);
|
||||||
|
SDL2PP_DEFINE_EVENT_MAPPING(SDL_WindowEvent, event.type == SDL_WINDOWEVENT, event.window);
|
||||||
|
|
||||||
|
#undef SDL2PP_DEFINE_EVENT_MAPPING
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
118
SDL2pp/Private/Utility.hh
Normal file
118
SDL2pp/Private/Utility.hh
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
libSDL2pp - C++11 bindings/wrapper for SDL2
|
||||||
|
Copyright (C) 2017 Vraiment <jemc44@gmail.com>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SDL2PP_PRIVATE_UTILITY_HH
|
||||||
|
#define SDL2PP_PRIVATE_UTILITY_HH
|
||||||
|
|
||||||
|
#if __cplusplus > 201703L
|
||||||
|
// No need to include utility, until C++17 there
|
||||||
|
// is no definition for std::disjuntion before
|
||||||
|
#include <utility>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace SDL2pp {
|
||||||
|
/*
|
||||||
|
* This is code not to be used directly by users of SDL2pp.
|
||||||
|
*/
|
||||||
|
namespace Private {
|
||||||
|
/*
|
||||||
|
* Templated class to perform an "OR" operation on any amount of types.
|
||||||
|
*
|
||||||
|
* Usage is as follows:
|
||||||
|
* template <typename T,
|
||||||
|
* typename = typename Or<HasFeatureOne<T>, HasFeatureTwo<T>>
|
||||||
|
* void UseFeatureOneOrFeatureTwo(T t) {
|
||||||
|
* // The code will be only compiled if either
|
||||||
|
* // HasFeatureOne<T> or HasFeatureTwo<T> are type_true
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
#if __cplusplus >= 201703L
|
||||||
|
// Use the standard definitions if they are available
|
||||||
|
template <typename T, typename... Tx>
|
||||||
|
using Or = typename std::disjunction<T, Tx...>::type;
|
||||||
|
#else
|
||||||
|
template <typename...>
|
||||||
|
struct OrOperation : std::false_type { };
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct OrOperation<T> : T { };
|
||||||
|
|
||||||
|
template <typename T, typename... Tx>
|
||||||
|
struct OrOperation<T, Tx...> : std::conditional<bool(T::value), T, OrOperation<Tx...>> { };
|
||||||
|
|
||||||
|
template <typename T, typename... Tx>
|
||||||
|
using Or = typename OrOperation<T, Tx...>::type;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Templated class to perform an "AND" operation on any amount of types.
|
||||||
|
*
|
||||||
|
* Usage is as follows:
|
||||||
|
* template <typename T,
|
||||||
|
* typename = typename And<HasFeatureOne<T>, HasFeatureTwo<T>>
|
||||||
|
* void UseFeatureOneAndFeatureTwo(T t) {
|
||||||
|
* // The code will be only compiled if both
|
||||||
|
* // HasFeatureOne<T> and HasFeatureTwo<T> are type_true
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
#if __cplusplus >= 201703L
|
||||||
|
// Use the standard definitions if they are available
|
||||||
|
template <typename T, typename... Tx>
|
||||||
|
using And = typename std::conjunction<T, Tx...>::type;
|
||||||
|
#else
|
||||||
|
template <typename...>
|
||||||
|
struct AndOperation : std::true_type { };
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct AndOperation<T> : T { };
|
||||||
|
|
||||||
|
template <typename T, typename... Tx>
|
||||||
|
struct AndOperation<T, Tx...> : std::conditional<bool(T::value), AndOperation<Tx...>, T> { };
|
||||||
|
|
||||||
|
template <typename T, typename... Tx>
|
||||||
|
using And = typename AndOperation<T, Tx...>::type;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Templated class to an specific type in a tuple, returns std::true_type if the
|
||||||
|
* tuple contains T, std::false_type otherwise.
|
||||||
|
*/
|
||||||
|
template <typename T, typename Tuple>
|
||||||
|
struct TupleHasTypeOperation;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct TupleHasTypeOperation<T, std::tuple<>> : std::false_type { };
|
||||||
|
|
||||||
|
template <typename T, typename U, typename... Tx>
|
||||||
|
struct TupleHasTypeOperation<T, std::tuple<U, Tx...>> : TupleHasTypeOperation<T, std::tuple<Tx...>> { };
|
||||||
|
|
||||||
|
template <typename T, typename... Tx>
|
||||||
|
struct TupleHasTypeOperation<T, std::tuple<T, Tx...>> : std::true_type { };
|
||||||
|
|
||||||
|
template <typename T, typename... Tx>
|
||||||
|
using TupleHasType = typename TupleHasTypeOperation<T, Tx...>::type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -97,6 +97,14 @@
|
|||||||
#include <SDL2pp/ContainerRWops.hh>
|
#include <SDL2pp/ContainerRWops.hh>
|
||||||
#include <SDL2pp/StreamRWops.hh>
|
#include <SDL2pp/StreamRWops.hh>
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
/// \defgroup events Event handling
|
||||||
|
///
|
||||||
|
/// \brief Functions and classes to easily manage SDL events
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
#include <SDL2pp/EventPolling.hh>
|
||||||
|
|
||||||
#ifdef SDL2PP_WITH_TTF
|
#ifdef SDL2PP_WITH_TTF
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \defgroup ttf SDL_ttf
|
/// \defgroup ttf SDL_ttf
|
||||||
|
@ -3,10 +3,14 @@ set(CLI_TESTS
|
|||||||
test_color
|
test_color
|
||||||
test_color_constexpr
|
test_color_constexpr
|
||||||
test_error
|
test_error
|
||||||
|
test_eventdispatching
|
||||||
|
test_eventhandler
|
||||||
|
test_eventpolling
|
||||||
test_optional
|
test_optional
|
||||||
test_pointrect
|
test_pointrect
|
||||||
test_pointrect_constexpr
|
test_pointrect_constexpr
|
||||||
test_rwops
|
test_rwops
|
||||||
|
test_utility
|
||||||
test_wav
|
test_wav
|
||||||
)
|
)
|
||||||
|
|
||||||
|
156
tests/test_eventdispatching.cc
Normal file
156
tests/test_eventdispatching.cc
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
#include <SDL_main.h>
|
||||||
|
|
||||||
|
#include <SDL2pp/Private/EventDispatching.hh>
|
||||||
|
|
||||||
|
#include "testing.h"
|
||||||
|
|
||||||
|
using namespace SDL2pp::Private;
|
||||||
|
|
||||||
|
namespace TestFreeFunctions {
|
||||||
|
static auto globalResult = Sint32{0};
|
||||||
|
|
||||||
|
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.common.timestamp = 98;
|
||||||
|
event.type = SDL_QUIT;
|
||||||
|
event.user.code = 31;
|
||||||
|
|
||||||
|
// Test dispatching with no event handler
|
||||||
|
DispatchEvent(event);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test dispatching with function as event handler
|
||||||
|
{
|
||||||
|
DispatchEvent(event, TestFreeFunctions::handler);
|
||||||
|
EXPECT_EQUAL(event.user.code, TestFreeFunctions::globalResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test dispatching with a functor as event handler
|
||||||
|
{
|
||||||
|
struct EventHandlerFunctor {
|
||||||
|
Sint32 result;
|
||||||
|
|
||||||
|
void operator()(SDL_Event event) {
|
||||||
|
result = event.user.code;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto eventHandlerFunctor = EventHandlerFunctor();
|
||||||
|
DispatchEvent(event, eventHandlerFunctor);
|
||||||
|
EXPECT_EQUAL(event.user.code, eventHandlerFunctor.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;
|
||||||
|
|
||||||
|
SDL_Event keyboardEvent;
|
||||||
|
keyboardEvent.type = SDL_KEYUP;
|
||||||
|
|
||||||
|
DispatchEvent(keyboardEvent, eventHandler);
|
||||||
|
|
||||||
|
EXPECT_TRUE(!eventHandler.quitEventExecuted);
|
||||||
|
EXPECT_TRUE(eventHandler.keyboardEventExecuted);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test call event handler that's both a functor and object
|
||||||
|
{
|
||||||
|
struct EventHandler {
|
||||||
|
bool quitEventFunctorExecuted = false;
|
||||||
|
bool quitEventObjectExecuted = false;
|
||||||
|
|
||||||
|
void operator()(SDL_QuitEvent) {
|
||||||
|
quitEventFunctorExecuted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleEvent(SDL_QuitEvent) {
|
||||||
|
quitEventObjectExecuted = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto eventHandler = EventHandler();
|
||||||
|
DispatchEvent(event, eventHandler);
|
||||||
|
|
||||||
|
EXPECT_TRUE(eventHandler.quitEventFunctorExecuted);
|
||||||
|
EXPECT_TRUE(eventHandler.quitEventObjectExecuted);
|
||||||
|
}
|
||||||
|
END_TEST()
|
71
tests/test_eventhandler.cc
Normal file
71
tests/test_eventhandler.cc
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#include <SDL_main.h>
|
||||||
|
|
||||||
|
#include <SDL2pp/Private/EventHandler.hh>
|
||||||
|
|
||||||
|
using namespace SDL2pp::Private;
|
||||||
|
|
||||||
|
void EventHandlerFunction(SDL_Event);
|
||||||
|
|
||||||
|
struct EventHandlerFunctor {
|
||||||
|
void operator()(SDL_Event);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EventHandler {
|
||||||
|
void HandleEvent(SDL_Event);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct InvalidEventHandler {
|
||||||
|
void handleEvent(SDL_Event);
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int, char*[]) {
|
||||||
|
auto lambda = [](SDL_Event) { };
|
||||||
|
|
||||||
|
// Test IsEventHandlerFunctor
|
||||||
|
static_assert(
|
||||||
|
IsEventHandlerFunctor<decltype(EventHandlerFunction), SDL_Event>::value,
|
||||||
|
"IsEventHandlerFunctor<> should accept functions like void(SDL_Event)"
|
||||||
|
);
|
||||||
|
static_assert(
|
||||||
|
IsEventHandlerFunctor<decltype(lambda), SDL_Event>::value,
|
||||||
|
"IsEventHandlerFunctor<> should accept functions like void(SDL_Event)"
|
||||||
|
);
|
||||||
|
static_assert(
|
||||||
|
IsEventHandlerFunctor<EventHandlerFunctor, SDL_Event>::value,
|
||||||
|
"IsEventHandlerFunctor<> shouldn accept a class with operator(SDL_Event)"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test IsEventHandlerObject
|
||||||
|
static_assert(
|
||||||
|
IsEventHandlerObject<EventHandler, SDL_Event>::value,
|
||||||
|
"IsEventHandlerObject<> should accept a class with HandleEvent(SDL_Event)"
|
||||||
|
);
|
||||||
|
static_assert(
|
||||||
|
!IsEventHandlerObject<InvalidEventHandler, SDL_Event>::value,
|
||||||
|
"IsEventHandlerObject<> shouldn't accept a class without a valid signature"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test IsEventHandler
|
||||||
|
static_assert(
|
||||||
|
IsEventHandler<decltype(EventHandlerFunction), SDL_Event>::value,
|
||||||
|
"IsEventHandler<> should accept functions like void(SDL_Event)"
|
||||||
|
);
|
||||||
|
static_assert(
|
||||||
|
IsEventHandler<decltype(lambda), SDL_Event>::value,
|
||||||
|
"IsEventHandler<> should accept functions like void(SDL_Event)"
|
||||||
|
);
|
||||||
|
static_assert(
|
||||||
|
IsEventHandler<EventHandlerFunctor, SDL_Event>::value,
|
||||||
|
"IsEventHandler<> should accept a class with operator(SDL_Event)"
|
||||||
|
);
|
||||||
|
static_assert(
|
||||||
|
IsEventHandler<EventHandler, SDL_Event>::value,
|
||||||
|
"IsEventHandler<> should accept a class with HandleEvent(SDL_Event)"
|
||||||
|
);
|
||||||
|
static_assert(
|
||||||
|
!IsEventHandler<InvalidEventHandler, SDL_Event>::value,
|
||||||
|
"IsEventHandler<> shouldn't accept a class without a valid signature"
|
||||||
|
);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
76
tests/test_eventpolling.cc
Normal file
76
tests/test_eventpolling.cc
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#include <SDL2pp/SDL.hh>
|
||||||
|
#include <SDL2pp/EventPolling.hh>
|
||||||
|
|
||||||
|
#include "testing.h"
|
||||||
|
|
||||||
|
using namespace SDL2pp;
|
||||||
|
using namespace SDL2pp::Event;
|
||||||
|
|
||||||
|
BEGIN_TEST(int, char*[])
|
||||||
|
SDL sdl{SDL_INIT_EVENTS};
|
||||||
|
|
||||||
|
// Empty event poll
|
||||||
|
SDL_Event event;
|
||||||
|
while (SDL_PollEvent(&event)) { }
|
||||||
|
|
||||||
|
// Poll a single event
|
||||||
|
{
|
||||||
|
event.type = SDL_KEYUP;
|
||||||
|
SDL_PushEvent(&event);
|
||||||
|
|
||||||
|
EXPECT_TRUE(PollEvent());
|
||||||
|
EXPECT_TRUE(!PollEvent()); // Verify no additional events
|
||||||
|
}
|
||||||
|
|
||||||
|
// Poll multiple events single event
|
||||||
|
{
|
||||||
|
event.type = SDL_KEYUP;
|
||||||
|
constexpr auto amountOfEvents = 5;
|
||||||
|
for (auto n = 0; n < amountOfEvents; n++)
|
||||||
|
SDL_PushEvent(&event);
|
||||||
|
|
||||||
|
EXPECT_EQUAL(PollAllEvents(), amountOfEvents);
|
||||||
|
EXPECT_TRUE(!PollEvent()); // Verify no additional events
|
||||||
|
}
|
||||||
|
|
||||||
|
// Poll with an event handler
|
||||||
|
{
|
||||||
|
struct EventHandler {
|
||||||
|
int eventsHandled = 0;
|
||||||
|
int keyboardEventsHandled = 0;
|
||||||
|
bool quitEventHandled = false;
|
||||||
|
|
||||||
|
void HandleEvent(SDL_Event) {
|
||||||
|
eventsHandled++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleEvent(SDL_KeyboardEvent) {
|
||||||
|
keyboardEventsHandled++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleEvent(SDL_QuitEvent) {
|
||||||
|
quitEventHandled = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
event.type = SDL_KEYUP;
|
||||||
|
SDL_PushEvent(&event);
|
||||||
|
|
||||||
|
event.type = SDL_KEYDOWN;
|
||||||
|
SDL_PushEvent(&event);
|
||||||
|
|
||||||
|
event.type = SDL_QUIT;
|
||||||
|
SDL_PushEvent(&event);
|
||||||
|
|
||||||
|
auto eventHandler = EventHandler();
|
||||||
|
|
||||||
|
EXPECT_EQUAL(PollAllEvents(eventHandler), 3);
|
||||||
|
EXPECT_TRUE(!PollEvent()); // Verify no additional events
|
||||||
|
|
||||||
|
EXPECT_EQUAL(eventHandler.eventsHandled, 3);
|
||||||
|
EXPECT_EQUAL(eventHandler.keyboardEventsHandled, 2);
|
||||||
|
EXPECT_EQUAL(eventHandler.quitEventHandled, true);
|
||||||
|
}
|
||||||
|
END_TEST()
|
28
tests/test_utility.cc
Normal file
28
tests/test_utility.cc
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#include <SDL_main.h>
|
||||||
|
|
||||||
|
#include <SDL2pp/Private/Utility.hh>
|
||||||
|
|
||||||
|
using namespace SDL2pp::Private;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main(int, char*[]) {
|
||||||
|
static_assert(Or<true_type, true_type>::value, "OR(true, true) should be true");
|
||||||
|
static_assert(Or<true_type, false_type>::value, "OR(true, false) should be true");
|
||||||
|
static_assert(Or<false_type, true_type>::value, "OR(false, true) should be true");
|
||||||
|
static_assert(!Or<false_type, false_type>::value, "OR(false, false) should be false");
|
||||||
|
|
||||||
|
static_assert(And<true_type, true_type>::value, "AND(true, true) should be true");
|
||||||
|
static_assert(!And<true_type, false_type>::value, "AND(true, false) should be false");
|
||||||
|
static_assert(!And<false_type, true_type>::value, "AND(false, true) should be false");
|
||||||
|
static_assert(!And<false_type, false_type>::value, "AND(false, false) should be false");
|
||||||
|
|
||||||
|
struct A { };
|
||||||
|
struct B { };
|
||||||
|
struct C { };
|
||||||
|
|
||||||
|
static_assert(TupleHasType<A, tuple<A, B>>::value, "");
|
||||||
|
static_assert(TupleHasType<B, tuple<A, B>>::value, "");
|
||||||
|
static_assert(!TupleHasType<C, tuple<A, B>>::value, "");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user