More fixes for event handlers meta programming logic

This commit is contained in:
Vraiment 2017-08-05 22:16:14 -07:00
parent ab48a57a40
commit 04f7c2a365
3 changed files with 28 additions and 41 deletions

View File

@ -30,13 +30,6 @@ namespace SDL2pp {
* This is code not to be used directly by users of SDL2pp. * This is code not to be used directly by users of SDL2pp.
*/ */
namespace Private { namespace Private {
/*
* Helper alias to help identify a functor object with the correct signature
* to be used as an event handler.
*/
template <typename EventType>
using EventHandlerFunctorSignature = std::function<void(const EventType &)>;
/* /*
* Templated class to identify a class that is not an event handler functor. * Templated class to identify a class that is not an event handler functor.
*/ */
@ -53,7 +46,7 @@ namespace Private {
EventHandlerType, EventHandlerType,
EventType, EventType,
typename std::enable_if< typename std::enable_if<
std::is_convertible<EventHandlerType, EventHandlerFunctorSignature<EventType>>::value std::is_convertible<EventHandlerType, std::function<void(EventType)>>::value
>::type >::type
> : std::true_type { }; > : std::true_type { };
} }

View File

@ -29,15 +29,6 @@ namespace SDL2pp {
* This is code not to be used directly by users of SDL2pp. * This is code not to be used directly by users of SDL2pp.
*/ */
namespace Private { namespace Private {
/*
* Templated class to detect if a given type can handle a given event.
*/
template <typename EventHandlerType, typename EventType>
struct HasEventHandlerMethod : std::is_same<
decltype(std::declval<EventHandlerType>().HandleEvent(std::declval<const EventType &>())),
void
> { };
/* /*
* Templated class to identify a class that is not an event handler object. * Templated class to identify a class that is not an event handler object.
*/ */
@ -47,15 +38,18 @@ namespace Private {
/* /*
* Templated class to identify a class that is an event handler object, the * 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 * way this is done is by verifying that an instance of EventHandlerType has
* the "HandleEvent" member function which received a "const EventType &" * the "HandleEvent" member function which received a "EventType" and
* and returns void. * returns void.
*/ */
template <typename EventHandlerType, typename EventType> template <typename EventHandlerType, typename EventType>
struct IsEventHandlerObject< struct IsEventHandlerObject<
EventHandlerType, EventHandlerType,
EventType, EventType,
typename std::enable_if< typename std::enable_if<
HasEventHandlerMethod<EventHandlerType, EventType>::value std::is_same<
decltype(std::declval<EventHandlerType>().HandleEvent(std::declval<EventType>())),
void
>::value
>::type >::type
> : std::true_type { }; > : std::true_type { };
} }

View File

@ -4,66 +4,66 @@
using namespace SDL2pp::Private; using namespace SDL2pp::Private;
void EventHandlerFunction(const SDL_Event &); void EventHandlerFunction(SDL_Event);
struct EventHandlerOperator { struct EventHandlerFunctor {
void operator()(SDL_Event); void operator()(SDL_Event);
}; };
struct EventHandler { struct EventHandler {
void HandleEvent(const SDL_Event &);
};
struct InvalidEventHandler {
void HandleEvent(SDL_Event); void HandleEvent(SDL_Event);
}; };
struct InvalidEventHandler {
void handleEvent(SDL_Event);
};
int main(int, char*[]) { int main(int, char*[]) {
auto lambda = [](const SDL_Event &) { }; auto lambda = [](SDL_Event) { };
// Test IsEventHandlerFunctor // Test IsEventHandlerFunctor
static_assert( static_assert(
IsEventHandlerFunctor<decltype(EventHandlerFunction), SDL_Event>::value, IsEventHandlerFunctor<decltype(EventHandlerFunction), SDL_Event>::value,
"IsEventHandlerFunctor<> should accept functions like void(const SDL_Event &)" "IsEventHandlerFunctor<> should accept functions like void(SDL_Event)"
); );
static_assert( static_assert(
IsEventHandlerFunctor<decltype(lambda), SDL_Event>::value, IsEventHandlerFunctor<decltype(lambda), SDL_Event>::value,
"IsEventHandlerFunctor<> should accept functions like void(const SDL_Event &)" "IsEventHandlerFunctor<> should accept functions like void(SDL_Event)"
); );
static_assert( static_assert(
!IsEventHandlerFunctor<EventHandlerOperator, SDL_Event>::value, IsEventHandlerFunctor<EventHandlerFunctor, SDL_Event>::value,
"IsEventHandlerFunctor<> shouldn't accept a class with operator(const SDL_Event &)" "IsEventHandlerFunctor<> shouldn accept a class with operator(SDL_Event)"
); );
// Test IsEventHandlerObject // Test IsEventHandlerObject
static_assert( static_assert(
IsEventHandlerObject<EventHandler, SDL_Event>::value, IsEventHandlerObject<EventHandler, SDL_Event>::value,
"IsEventHandlerObject<> should accept a class with HandleEvent(const SDL_Event &)" "IsEventHandlerObject<> should accept a class with HandleEvent(SDL_Event)"
); );
static_assert( static_assert(
!IsEventHandlerObject<InvalidEventHandler, SDL_Event>::value, !IsEventHandlerObject<InvalidEventHandler, SDL_Event>::value,
"IsEventHandlerObject<> shouldn't accept a class with a different HandleEvent() signature" "IsEventHandlerObject<> shouldn't accept a class without a valid signature"
); );
// Test IsEventHandler // Test IsEventHandler
static_assert( static_assert(
IsEventHandler<decltype(EventHandlerFunction), SDL_Event>::value, IsEventHandler<decltype(EventHandlerFunction), SDL_Event>::value,
"IsEventHandler<> should accept functions like void(const SDL_Event &)" "IsEventHandler<> should accept functions like void(SDL_Event)"
); );
static_assert( static_assert(
IsEventHandler<decltype(lambda), SDL_Event>::value, IsEventHandler<decltype(lambda), SDL_Event>::value,
"IsEventHandler<> should accept functions like void(const SDL_Event &)" "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( static_assert(
IsEventHandler<EventHandler, SDL_Event>::value, IsEventHandler<EventHandler, SDL_Event>::value,
"IsEventHandler<> should accept a class with HandleEvent(const SDL_Event &)" "IsEventHandler<> should accept a class with HandleEvent(SDL_Event)"
);
static_assert(
!IsEventHandler<EventHandlerOperator, SDL_Event>::value,
"IsEventHandler<> shouldn't accept a class with operator(const SDL_Event &)"
); );
static_assert( static_assert(
!IsEventHandler<InvalidEventHandler, SDL_Event>::value, !IsEventHandler<InvalidEventHandler, SDL_Event>::value,
"IsEventHandler<> shouldn't accept a class with a different HandleEvent() signature" "IsEventHandler<> shouldn't accept a class without a valid signature"
); );
} }