From 1c7d9e3d75d288663caef5abef1f5a308f306be0 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Sun, 18 Aug 2019 15:21:29 +0200 Subject: [PATCH] signals meet references (close #289) --- TODO | 1 + docs/md/entity.md | 9 ++--- docs/md/signal.md | 32 +++++++-------- src/entt/entity/observer.hpp | 64 ++++++++++++++--------------- src/entt/entity/registry.hpp | 12 +++--- src/entt/signal/delegate.hpp | 33 +++++++-------- src/entt/signal/dispatcher.hpp | 6 +-- src/entt/signal/sigh.hpp | 26 ++++++------ test/entt/entity/registry.cpp | 38 ++++++++--------- test/entt/signal/delegate.cpp | 72 ++++++++++++++++----------------- test/entt/signal/dispatcher.cpp | 4 +- test/entt/signal/sigh.cpp | 51 ++++++++++------------- test/lib/lib.cpp | 4 +- 13 files changed, 173 insertions(+), 179 deletions(-) diff --git a/TODO b/TODO index d220b8bd0..68e76ec26 100644 --- a/TODO +++ b/TODO @@ -18,6 +18,7 @@ * built-in support for dual (or N-) buffering * allow to "merge" registries easily * allow for custom stomp functions +* deprecate/replace snapshot * remove prototype TODO diff --git a/docs/md/entity.md b/docs/md/entity.md index 46ad3f0da..94976d256 100644 --- a/docs/md/entity.md +++ b/docs/md/entity.md @@ -348,13 +348,13 @@ notified on the creation of a component, use the `on_construct` member function: registry.on_construct().connect<&my_free_function>(); // connects a member function -registry.on_construct().connect<&my_class::member>(&instance); +registry.on_construct().connect<&my_class::member>(instance); // disconnects a free function registry.on_construct().disconnect<&my_free_function>(); // disconnects a member function -registry.on_construct().disconnect<&my_class::member>(&instance); +registry.on_construct().disconnect<&my_class::member>(instance); ``` To be notified when components are destroyed, use the `on_destroy` member @@ -656,9 +656,8 @@ brief, yet incomplete list of some of them: entity.
Put aside the fact that having the prototypes separated from the simulation is useful in many cases, they make also the codebase easier to maintain, since - updating a template is much less error prone than jumping in the code to - update all the snippets copied and pasted around to initialize entities and - components. + updating a template is less error prone than jumping in the code to update all + the snippets copied and pasted around to initialize entities and components. * Literally _move_ entities from one registry to another (that is a copy followed by a destroy), which can be useful for solving problems such as the diff --git a/docs/md/signal.md b/docs/md/signal.md index de5a1df87..9e251474e 100644 --- a/docs/md/signal.md +++ b/docs/md/signal.md @@ -71,27 +71,27 @@ delegate.connect<&f>(); // bind a member function to the delegate my_struct instance; -delegate.connect<&my_struct::f>(&instance); +delegate.connect<&my_struct::f>(instance); ``` The delegate class accepts also data members, if needed. In this case, the function type of the delegate is such that the parameter list is empty and the value of the data member is at least convertible to the return type. -Free functions having type equivalent to `void(T *, args...)` are accepted as -well. In this case, `T *` is considered a payload and the function will receive +Free functions having type equivalent to `void(T &, args...)` are accepted as +well. In this case, `T &` is considered a payload and the function will receive it back every time it's invoked. In other terms, this works just fine with the above definition: ```cpp -void g(const char *c, int i) { /* ... */ } +void g(const char &c, int i) { /* ... */ } const char c = 'c'; -delegate.connect<&g>(&c); +delegate.connect<&g>(c); delegate(42); ``` -The function `g` will be invoked with a pointer to `c` and `42`. However, the +The function `g` will be invoked with a reference to `c` and `42`. However, the function type of the delegate is still `void(int)`. This is also the signature of its function call operator. @@ -144,8 +144,8 @@ fine. # Signals -Signal handlers work with naked pointers, function pointers and pointers to -members. Listeners can be any kind of objects and users are in charge of +Signal handlers work with references to classes, function pointers and pointers +to members. Listeners can be any kind of objects and users are in charge of connecting and disconnecting them from a signal to avoid crashes due to different lifetimes. On the other side, performance shouldn't be affected that much by the presence of such a signal handler.
@@ -190,7 +190,7 @@ entt::sink sink{signal}; listener instance; sink.connect<&foo>(); -sink.connect<&listener::bar>(&instance); +sink.connect<&listener::bar>(instance); // ... @@ -198,10 +198,10 @@ sink.connect<&listener::bar>(&instance); sink.disconnect<&foo>(); // disconnect a member function of an instance -sink.disconnect<&listener::bar>(&instance); +sink.disconnect<&listener::bar>(instance); // disconnect all the member functions of an instance, if any -sink.disconnect(&instance); +sink.disconnect(instance); // discards all the listeners at once sink.disconnect(); @@ -280,7 +280,7 @@ This class shares part of its API with the one of the signal handler, but it doesn't require that all the types of events are specified when declared: ```cpp -// define a general purpose dispatcher that works with naked pointers +// define a general purpose dispatcher entt::dispatcher dispatcher{}; ``` @@ -303,16 +303,16 @@ struct listener { // ... listener listener; -dispatcher.sink().connect<&listener::receive>(&listener); -dispatcher.sink().connect<&listener::method>(&listener); +dispatcher.sink().connect<&listener::receive>(listener); +dispatcher.sink().connect<&listener::method>(listener); ``` The `disconnect` member function follows the same pattern and can be used to remove one listener at a time or all of them at once: ```cpp -dispatcher.sink().disconnect<&listener::receive>(&listener); -dispatcher.sink().disconnect(&listener); +dispatcher.sink().disconnect<&listener::receive>(listener); +dispatcher.sink().disconnect(listener); ``` The `trigger` member function serves the purpose of sending an immediate event diff --git a/src/entt/entity/observer.hpp b/src/entt/entity/observer.hpp index ce066a0fa..13f6f48b6 100644 --- a/src/entt/entity/observer.hpp +++ b/src/entt/entity/observer.hpp @@ -173,72 +173,72 @@ class basic_observer { template struct matcher_handler, type_list>, AnyOf>> { template - static void maybe_valid_if(basic_observer *obs, const basic_registry ®, const Entity entt) { + static void maybe_valid_if(basic_observer &obs, const basic_registry ®, const Entity entt) { if(reg.template has(entt) && !(reg.template has(entt) || ...)) { - auto *comp = obs->view.try_get(entt); - (comp ? *comp : obs->view.construct(entt)) |= (1 << Index); + auto *comp = obs.view.try_get(entt); + (comp ? *comp : obs.view.construct(entt)) |= (1 << Index); } } template - static void discard_if(basic_observer *obs, const basic_registry &, const Entity entt) { - if(auto *value = obs->view.try_get(entt); value && !(*value &= (~(1 << Index)))) { - obs->view.destroy(entt); + static void discard_if(basic_observer &obs, const basic_registry &, const Entity entt) { + if(auto *value = obs.view.try_get(entt); value && !(*value &= (~(1 << Index)))) { + obs.view.destroy(entt); } } template static void connect(basic_observer &obs, basic_registry ®) { - (reg.template on_destroy().template connect<&discard_if>(&obs), ...); - (reg.template on_construct().template connect<&discard_if>(&obs), ...); - reg.template on_replace().template connect<&maybe_valid_if>(&obs); - reg.template on_destroy().template connect<&discard_if>(&obs); + (reg.template on_destroy().template connect<&discard_if>(obs), ...); + (reg.template on_construct().template connect<&discard_if>(obs), ...); + reg.template on_replace().template connect<&maybe_valid_if>(obs); + reg.template on_destroy().template connect<&discard_if>(obs); } static void disconnect(basic_observer &obs, basic_registry ®) { - (reg.template on_destroy().disconnect(&obs), ...); - (reg.template on_construct().disconnect(&obs), ...); - reg.template on_replace().disconnect(&obs); - reg.template on_destroy().disconnect(&obs); + (reg.template on_destroy().disconnect(obs), ...); + (reg.template on_construct().disconnect(obs), ...); + reg.template on_replace().disconnect(obs); + reg.template on_destroy().disconnect(obs); } }; template struct matcher_handler, type_list>, type_list, type_list>> { template - static void maybe_valid_if(basic_observer *obs, const basic_registry ®, const Entity entt) { + static void maybe_valid_if(basic_observer &obs, const basic_registry ®, const Entity entt) { if(reg.template has(entt) && !(reg.template has(entt) || ...) && reg.template has(entt) && !(reg.template has(entt) || ...)) { - auto *comp = obs->view.try_get(entt); - (comp ? *comp : obs->view.construct(entt)) |= (1 << Index); + auto *comp = obs.view.try_get(entt); + (comp ? *comp : obs.view.construct(entt)) |= (1 << Index); } } template - static void discard_if(basic_observer *obs, const basic_registry &, const Entity entt) { - if(auto *value = obs->view.try_get(entt); value && !(*value &= (~(1 << Index)))) { - obs->view.destroy(entt); + static void discard_if(basic_observer &obs, const basic_registry &, const Entity entt) { + if(auto *value = obs.view.try_get(entt); value && !(*value &= (~(1 << Index)))) { + obs.view.destroy(entt); } } template static void connect(basic_observer &obs, basic_registry ®) { - (reg.template on_destroy().template connect<&discard_if>(&obs), ...); - (reg.template on_construct().template connect<&discard_if>(&obs), ...); - (reg.template on_construct().template connect<&maybe_valid_if>(&obs), ...); - (reg.template on_destroy().template connect<&maybe_valid_if>(&obs), ...); - (reg.template on_destroy().template connect<&discard_if>(&obs), ...); - (reg.template on_construct().template connect<&discard_if>(&obs), ...); + (reg.template on_destroy().template connect<&discard_if>(obs), ...); + (reg.template on_construct().template connect<&discard_if>(obs), ...); + (reg.template on_construct().template connect<&maybe_valid_if>(obs), ...); + (reg.template on_destroy().template connect<&maybe_valid_if>(obs), ...); + (reg.template on_destroy().template connect<&discard_if>(obs), ...); + (reg.template on_construct().template connect<&discard_if>(obs), ...); } static void disconnect(basic_observer &obs, basic_registry ®) { - (reg.template on_destroy().disconnect(&obs), ...); - (reg.template on_construct().disconnect(&obs), ...); - (reg.template on_construct().disconnect(&obs), ...); - (reg.template on_destroy().disconnect(&obs), ...); - (reg.template on_destroy().disconnect(&obs), ...); - (reg.template on_construct().disconnect(&obs), ...); + (reg.template on_destroy().disconnect(obs), ...); + (reg.template on_construct().disconnect(obs), ...); + (reg.template on_construct().disconnect(obs), ...); + (reg.template on_destroy().disconnect(obs), ...); + (reg.template on_destroy().disconnect(obs), ...); + (reg.template on_construct().disconnect(obs), ...); } }; diff --git a/src/entt/entity/registry.hpp b/src/entt/entity/registry.hpp index 622a16b0f..790ad7978 100644 --- a/src/entt/entity/registry.hpp +++ b/src/entt/entity/registry.hpp @@ -1347,14 +1347,14 @@ public: ENTT_ASSERT((!std::get *>(curr->cpools)->group && ...)); ((std::get *>(curr->cpools)->group = curr), ...); - (std::get *>(curr->cpools)->on_construct().template connect<&handler_type::template maybe_valid_if>(curr), ...); - (std::get *>(curr->cpools)->on_destroy().template connect<&handler_type::discard_if>(curr), ...); + (std::get *>(curr->cpools)->on_construct().template connect<&handler_type::template maybe_valid_if>(*curr), ...); + (std::get *>(curr->cpools)->on_destroy().template connect<&handler_type::discard_if>(*curr), ...); - (std::get *>(curr->cpools)->on_construct().template connect<&handler_type::template maybe_valid_if>(curr), ...); - (std::get *>(curr->cpools)->on_destroy().template connect<&handler_type::discard_if>(curr), ...); + (std::get *>(curr->cpools)->on_construct().template connect<&handler_type::template maybe_valid_if>(*curr), ...); + (std::get *>(curr->cpools)->on_destroy().template connect<&handler_type::discard_if>(*curr), ...); - (std::get *>(curr->cpools)->on_destroy().template connect<&handler_type::template maybe_valid_if>(curr), ...); - (std::get *>(curr->cpools)->on_construct().template connect<&handler_type::discard_if>(curr), ...); + (std::get *>(curr->cpools)->on_destroy().template connect<&handler_type::template maybe_valid_if>(*curr), ...); + (std::get *>(curr->cpools)->on_construct().template connect<&handler_type::discard_if>(*curr), ...); const auto *cpool = std::min({ static_cast *>(std::get *>(curr->cpools))..., diff --git a/src/entt/signal/delegate.hpp b/src/entt/signal/delegate.hpp index 2af110142..b91c1979d 100644 --- a/src/entt/signal/delegate.hpp +++ b/src/entt/signal/delegate.hpp @@ -27,20 +27,20 @@ template auto to_function_pointer(Ret(*)(Args...)) -> Ret(*)(Args...); -template>> -auto to_function_pointer(Ret(*)(Type *, Args...), Payload *) -> Ret(*)(Args...); +template>> +auto to_function_pointer(Ret(*)(Type &, Args...), Payload &) -> Ret(*)(Args...); template -auto to_function_pointer(Ret(Class:: *)(Args...), const Class *) -> Ret(*)(Args...); +auto to_function_pointer(Ret(Class:: *)(Args...), const Class &) -> Ret(*)(Args...); template -auto to_function_pointer(Ret(Class:: *)(Args...) const, const Class *) -> Ret(*)(Args...); +auto to_function_pointer(Ret(Class:: *)(Args...) const, const Class &) -> Ret(*)(Args...); template -auto to_function_pointer(Type Class:: *, const Class *) -> Type(*)(); +auto to_function_pointer(Type Class:: *, const Class &) -> Type(*)(); template @@ -115,9 +115,9 @@ class delegate { } template - void connect(Type *value_or_instance, std::index_sequence) ENTT_NOEXCEPT { - static_assert(std::is_invocable_r_v>...>); - data = value_or_instance; + void connect(Type &value_or_instance, std::index_sequence) ENTT_NOEXCEPT { + static_assert(std::is_invocable_r_v>...>); + data = &value_or_instance; fn = [](const void *payload, std::tuple args) -> Ret { Type *curr = nullptr; @@ -129,7 +129,7 @@ class delegate { } // Ret(...) makes void(...) eat the return values to avoid errors - return Ret(std::invoke(Candidate, curr, std::forward>>(std::get(args))...)); + return Ret(std::invoke(Candidate, *curr, std::forward>>(std::get(args))...)); }; } @@ -158,10 +158,10 @@ public: * or a free function with payload. * @tparam Candidate Member or free function to connect to the delegate. * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid pointer that fits the purpose. + * @param value_or_instance A valid reference that fits the purpose. */ template - delegate(connect_arg_t, Type *value_or_instance) ENTT_NOEXCEPT + delegate(connect_arg_t, Type &value_or_instance) ENTT_NOEXCEPT : delegate{} { connect(value_or_instance); @@ -190,11 +190,11 @@ public: * * @tparam Candidate Member or free function to connect to the delegate. * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid pointer that fits the purpose. + * @param value_or_instance A valid reference that fits the purpose. */ template - void connect(Type *value_or_instance) ENTT_NOEXCEPT { - constexpr auto extent = internal::function_extent_v(), std::declval()))>; + void connect(Type &value_or_instance) ENTT_NOEXCEPT { + constexpr auto extent = internal::function_extent_v(), value_or_instance))>; connect(value_or_instance, std::make_index_sequence{}); } @@ -292,12 +292,13 @@ delegate(connect_arg_t) ENTT_NOEXCEPT * It allows to deduce the function type of the delegate directly from a member * or a free function with payload provided to the constructor. * + * @param value_or_instance A valid reference that fits the purpose. * @tparam Candidate Member or free function to connect to the delegate. * @tparam Type Type of class or type of payload. */ template -delegate(connect_arg_t, Type *) ENTT_NOEXCEPT --> delegate()))>>; +delegate(connect_arg_t, Type &value_or_instance) ENTT_NOEXCEPT +-> delegate>; } diff --git a/src/entt/signal/dispatcher.hpp b/src/entt/signal/dispatcher.hpp index 738fd6dc6..540f94b7f 100644 --- a/src/entt/signal/dispatcher.hpp +++ b/src/entt/signal/dispatcher.hpp @@ -24,9 +24,9 @@ namespace entt { * type `Event`, listeners are such that they can be invoked with an argument of * type `const Event &`, no matter what the return type is. * - * The type of the instances is `Class *` (a naked pointer). It means that users - * must guarantee that the lifetimes of the instances overcome the one of the - * dispatcher itself to avoid crashes. + * The types of the instances are `Class &`. Users must guarantee that the + * lifetimes of the objects overcome the one of the dispatcher itself to avoid + * crashes. */ class dispatcher { using event_family = family; diff --git a/src/entt/signal/sigh.hpp b/src/entt/signal/sigh.hpp index fd1951af5..98a276aa6 100644 --- a/src/entt/signal/sigh.hpp +++ b/src/entt/signal/sigh.hpp @@ -42,9 +42,9 @@ class sigh; /** * @brief Unmanaged signal handler. * - * It works directly with naked pointers to classes and pointers to member - * functions as well as pointers to free functions. Users of this class are in - * charge of disconnecting instances before deleting them. + * It works directly with references to classes and pointers to member functions + * as well as pointers to free functions. Users of this class are in charge of + * disconnecting instances before deleting them. * * This class serves mainly two purposes: * @@ -305,7 +305,7 @@ class sink { using signal_type = sigh; template - static void release(Type *value_or_instance, void *signal) { + static void release(Type &value_or_instance, void *signal) { sink{*static_cast(signal)}.disconnect(value_or_instance); } @@ -363,11 +363,11 @@ public: * * @tparam Candidate Member or free function to connect to the signal. * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid pointer that fits the purpose. + * @param value_or_instance A valid reference that fits the purpose. * @return A properly initialized connection object. */ template - connection connect(Type *value_or_instance) { + connection connect(Type &value_or_instance) { disconnect(value_or_instance); delegate conn{}; conn.template connect<&sink::release>(value_or_instance); @@ -392,10 +392,10 @@ public: * a signal. * @tparam Candidate Member or free function to disconnect from the signal. * @tparam Type Type of class or type of payload. - * @param value_or_instance A valid pointer that fits the purpose. + * @param value_or_instance A valid reference that fits the purpose. */ template - void disconnect(Type *value_or_instance) { + void disconnect(Type &value_or_instance) { auto &calls = signal->calls; delegate delegate{}; delegate.template connect(value_or_instance); @@ -405,12 +405,14 @@ public: /** * @brief Disconnects member functions or free functions based on an * instance or specific payload. - * @param value_or_instance A valid pointer that fits the purpose. + * @tparam Type Type of class or type of payload. + * @param value_or_instance A valid reference that fits the purpose. */ - void disconnect(const void *value_or_instance) { + template + void disconnect(const Type &value_or_instance) { auto &calls = signal->calls; - calls.erase(std::remove_if(calls.begin(), calls.end(), [value_or_instance](const auto &delegate) { - return value_or_instance == delegate.instance(); + calls.erase(std::remove_if(calls.begin(), calls.end(), [&value_or_instance](const auto &delegate) { + return delegate.instance() == &value_or_instance; }), calls.end()); } diff --git a/test/entt/entity/registry.cpp b/test/entt/entity/registry.cpp index e94a88962..6238f9391 100644 --- a/test/entt/entity/registry.cpp +++ b/test/entt/entity/registry.cpp @@ -925,10 +925,10 @@ TEST(Registry, Signals) { entt::registry registry; listener listener; - registry.on_construct().connect<&listener::incr>(&listener); - registry.on_destroy().connect<&listener::decr>(&listener); - registry.on_construct().connect<&listener::incr>(&listener); - registry.on_destroy().connect<&listener::decr>(&listener); + registry.on_construct().connect<&listener::incr>(listener); + registry.on_destroy().connect<&listener::decr>(listener); + registry.on_construct().connect<&listener::incr>(listener); + registry.on_destroy().connect<&listener::decr>(listener); auto e0 = registry.create(); auto e1 = registry.create(); @@ -951,8 +951,8 @@ TEST(Registry, Signals) { ASSERT_EQ(listener.counter, 2); ASSERT_EQ(listener.last, e0); - registry.on_destroy().disconnect<&listener::decr>(&listener); - registry.on_destroy().disconnect<&listener::decr>(&listener); + registry.on_destroy().disconnect<&listener::decr>(listener); + registry.on_destroy().disconnect<&listener::decr>(listener); registry.remove(e1); registry.remove(e1); @@ -960,8 +960,8 @@ TEST(Registry, Signals) { ASSERT_EQ(listener.counter, 2); ASSERT_EQ(listener.last, e0); - registry.on_construct().disconnect<&listener::incr>(&listener); - registry.on_construct().disconnect<&listener::incr>(&listener); + registry.on_construct().disconnect<&listener::incr>(listener); + registry.on_construct().disconnect<&listener::incr>(listener); registry.assign(e1); registry.assign(e1); @@ -969,8 +969,8 @@ TEST(Registry, Signals) { ASSERT_EQ(listener.counter, 2); ASSERT_EQ(listener.last, e0); - registry.on_construct().connect<&listener::incr>(&listener); - registry.on_destroy().connect<&listener::decr>(&listener); + registry.on_construct().connect<&listener::incr>(listener); + registry.on_destroy().connect<&listener::decr>(listener); registry.assign(e0); registry.reset(e1); @@ -978,8 +978,8 @@ TEST(Registry, Signals) { ASSERT_EQ(listener.counter, 2); ASSERT_EQ(listener.last, e1); - registry.on_construct().connect<&listener::incr>(&listener); - registry.on_destroy().connect<&listener::decr>(&listener); + registry.on_construct().connect<&listener::incr>(listener); + registry.on_destroy().connect<&listener::decr>(listener); registry.reset(e1); registry.assign(e0); @@ -1011,8 +1011,8 @@ TEST(Registry, Signals) { ASSERT_EQ(listener.counter, 2); ASSERT_EQ(listener.last, e0); - registry.on_destroy().disconnect<&listener::decr>(&listener); - registry.on_destroy().disconnect<&listener::decr>(&listener); + registry.on_destroy().disconnect<&listener::decr>(listener); + registry.on_destroy().disconnect<&listener::decr>(listener); registry.assign_or_replace(e0); registry.assign_or_replace(e0); @@ -1020,8 +1020,8 @@ TEST(Registry, Signals) { ASSERT_EQ(listener.counter, 2); ASSERT_EQ(listener.last, e0); - registry.on_replace().connect<&listener::incr>(&listener); - registry.on_replace().connect<&listener::incr>(&listener); + registry.on_replace().connect<&listener::incr>(listener); + registry.on_replace().connect<&listener::incr>(listener); registry.assign_or_replace(e0); registry.assign_or_replace(e0); @@ -1179,13 +1179,13 @@ TEST(Registry, CreateManyEntitiesWithComponentsAtOnceWithListener) { entt::entity entities[3]; listener listener; - registry.on_construct().connect<&listener::incr>(&listener); + registry.on_construct().connect<&listener::incr>(listener); registry.create(std::begin(entities), std::end(entities)); ASSERT_EQ(listener.counter, 3); - registry.on_construct().disconnect<&listener::incr>(&listener); - registry.on_construct().connect<&listener::incr>(&listener); + registry.on_construct().disconnect<&listener::incr>(listener); + registry.on_construct().connect<&listener::incr>(listener); registry.create(std::begin(entities), std::end(entities)); ASSERT_EQ(listener.counter, 6); diff --git a/test/entt/signal/delegate.cpp b/test/entt/signal/delegate.cpp index 3b63f3915..f86811caf 100644 --- a/test/entt/signal/delegate.cpp +++ b/test/entt/signal/delegate.cpp @@ -6,8 +6,8 @@ int delegate_function(const int &i) { return i*i; } -int curried_function(const int *i, int j) { - return *i+j; +int curried_function(const int &i, int j) { + return i+j; } int non_const_reference(int &i) { @@ -51,7 +51,7 @@ TEST(Delegate, Functionalities) { ASSERT_EQ(ff_del, mf_del); ff_del.connect<&delegate_function>(); - mf_del.connect<&delegate_functor::operator()>(&functor); + mf_del.connect<&delegate_functor::operator()>(functor); ASSERT_TRUE(ff_del); ASSERT_TRUE(mf_del); @@ -82,7 +82,7 @@ TEST(Delegate, DataMembers) { entt::delegate delegate; delegate_functor functor; - delegate.connect<&delegate_functor::data_member>(&functor); + delegate.connect<&delegate_functor::data_member>(functor); ASSERT_EQ(delegate(), 42); } @@ -113,37 +113,37 @@ TEST(Delegate, Comparison) { ASSERT_TRUE(lhs == rhs); ASSERT_EQ(lhs, rhs); - lhs.connect<&curried_function>(&value); + lhs.connect<&curried_function>(value); - ASSERT_EQ(lhs, (entt::delegate{entt::connect_arg<&curried_function>, &value})); + ASSERT_EQ(lhs, (entt::delegate{entt::connect_arg<&curried_function>, value})); ASSERT_TRUE(lhs != rhs); ASSERT_FALSE(lhs == rhs); ASSERT_NE(lhs, rhs); - rhs.connect<&curried_function>(&value); + rhs.connect<&curried_function>(value); - ASSERT_EQ(rhs, (entt::delegate{entt::connect_arg<&curried_function>, &value})); + ASSERT_EQ(rhs, (entt::delegate{entt::connect_arg<&curried_function>, value})); ASSERT_FALSE(lhs != rhs); ASSERT_TRUE(lhs == rhs); ASSERT_EQ(lhs, rhs); - lhs.connect<&delegate_functor::operator()>(&functor); + lhs.connect<&delegate_functor::operator()>(functor); - ASSERT_EQ(lhs, (entt::delegate{entt::connect_arg<&delegate_functor::operator()>, &functor})); + ASSERT_EQ(lhs, (entt::delegate{entt::connect_arg<&delegate_functor::operator()>, functor})); ASSERT_TRUE(lhs != rhs); ASSERT_FALSE(lhs == rhs); ASSERT_NE(lhs, rhs); - rhs.connect<&delegate_functor::operator()>(&functor); + rhs.connect<&delegate_functor::operator()>(functor); - ASSERT_EQ(rhs, (entt::delegate{entt::connect_arg<&delegate_functor::operator()>, &functor})); + ASSERT_EQ(rhs, (entt::delegate{entt::connect_arg<&delegate_functor::operator()>, functor})); ASSERT_FALSE(lhs != rhs); ASSERT_TRUE(lhs == rhs); ASSERT_EQ(lhs, rhs); - lhs.connect<&delegate_functor::operator()>(&other); + lhs.connect<&delegate_functor::operator()>(other); - ASSERT_EQ(lhs, (entt::delegate{entt::connect_arg<&delegate_functor::operator()>, &other})); + ASSERT_EQ(lhs, (entt::delegate{entt::connect_arg<&delegate_functor::operator()>, other})); ASSERT_NE(lhs.instance(), rhs.instance()); ASSERT_TRUE(lhs != rhs); ASSERT_FALSE(lhs == rhs); @@ -168,16 +168,16 @@ TEST(Delegate, ConstNonConstNoExcept) { entt::delegate delegate; const_nonconst_noexcept functor; - delegate.connect<&const_nonconst_noexcept::f>(&functor); + delegate.connect<&const_nonconst_noexcept::f>(functor); delegate(); - delegate.connect<&const_nonconst_noexcept::g>(&functor); + delegate.connect<&const_nonconst_noexcept::g>(functor); delegate(); - delegate.connect<&const_nonconst_noexcept::h>(&functor); + delegate.connect<&const_nonconst_noexcept::h>(functor); delegate(); - delegate.connect<&const_nonconst_noexcept::i>(&functor); + delegate.connect<&const_nonconst_noexcept::i>(functor); delegate(); ASSERT_EQ(functor.cnt, 4); @@ -188,17 +188,17 @@ TEST(Delegate, DeductionGuide) { int value = 0; entt::delegate func{entt::connect_arg<&delegate_function>}; - entt::delegate curried_func{entt::connect_arg<&curried_function>, &value}; - entt::delegate curried_func_const{entt::connect_arg<&curried_function>, &std::as_const(value)}; - entt::delegate member_func_f{entt::connect_arg<&const_nonconst_noexcept::f>, &functor}; - entt::delegate member_func_g{entt::connect_arg<&const_nonconst_noexcept::g>, &functor}; - entt::delegate member_func_h{entt::connect_arg<&const_nonconst_noexcept::h>, &functor}; - entt::delegate member_func_h_const{entt::connect_arg<&const_nonconst_noexcept::h>, &std::as_const(functor)}; - entt::delegate member_func_i{entt::connect_arg<&const_nonconst_noexcept::i>, &functor}; - entt::delegate member_func_i_const{entt::connect_arg<&const_nonconst_noexcept::i>, &std::as_const(functor)}; - entt::delegate data_member_u{entt::connect_arg<&const_nonconst_noexcept::u>, &functor}; - entt::delegate data_member_v{entt::connect_arg<&const_nonconst_noexcept::v>, &functor}; - entt::delegate data_member_v_const{entt::connect_arg<&const_nonconst_noexcept::v>, &std::as_const(functor)}; + entt::delegate curried_func{entt::connect_arg<&curried_function>, value}; + entt::delegate curried_func_const{entt::connect_arg<&curried_function>, std::as_const(value)}; + entt::delegate member_func_f{entt::connect_arg<&const_nonconst_noexcept::f>, functor}; + entt::delegate member_func_g{entt::connect_arg<&const_nonconst_noexcept::g>, functor}; + entt::delegate member_func_h{entt::connect_arg<&const_nonconst_noexcept::h>, functor}; + entt::delegate member_func_h_const{entt::connect_arg<&const_nonconst_noexcept::h>, std::as_const(functor)}; + entt::delegate member_func_i{entt::connect_arg<&const_nonconst_noexcept::i>, functor}; + entt::delegate member_func_i_const{entt::connect_arg<&const_nonconst_noexcept::i>, std::as_const(functor)}; + entt::delegate data_member_u{entt::connect_arg<&const_nonconst_noexcept::u>, functor}; + entt::delegate data_member_v{entt::connect_arg<&const_nonconst_noexcept::v>, functor}; + entt::delegate data_member_v_const{entt::connect_arg<&const_nonconst_noexcept::v>, std::as_const(functor)}; static_assert(std::is_same_v); static_assert(std::is_same_v); @@ -233,7 +233,7 @@ TEST(Delegate, ConstInstance) { ASSERT_FALSE(delegate); - delegate.connect<&delegate_functor::identity>(&functor); + delegate.connect<&delegate_functor::identity>(functor); ASSERT_TRUE(delegate); ASSERT_EQ(delegate(3), 3); @@ -266,7 +266,7 @@ TEST(Delegate, CurriedFunction) { entt::delegate delegate; const auto value = 3; - delegate.connect<&curried_function>(&value); + delegate.connect<&curried_function>(value); ASSERT_TRUE(delegate); ASSERT_EQ(delegate(1), 4); @@ -278,8 +278,8 @@ TEST(Delegate, Constructors) { entt::delegate empty{}; entt::delegate func{entt::connect_arg<&delegate_function>}; - entt::delegate curr{entt::connect_arg<&curried_function>, &value}; - entt::delegate member{entt::connect_arg<&delegate_functor::operator()>, &functor}; + entt::delegate curr{entt::connect_arg<&curried_function>, value}; + entt::delegate member{entt::connect_arg<&delegate_functor::operator()>, functor}; ASSERT_FALSE(empty); @@ -297,8 +297,8 @@ TEST(Delegate, VoidVsNonVoidReturnType) { delegate_functor functor; entt::delegate func{entt::connect_arg<&delegate_function>}; - entt::delegate member{entt::connect_arg<&delegate_functor::operator()>, &functor}; - entt::delegate cmember{entt::connect_arg<&delegate_functor::identity>, &std::as_const(functor)}; + entt::delegate member{entt::connect_arg<&delegate_functor::operator()>, functor}; + entt::delegate cmember{entt::connect_arg<&delegate_functor::identity>, std::as_const(functor)}; ASSERT_TRUE(func); ASSERT_TRUE(member); @@ -315,7 +315,7 @@ TEST(Delegate, TheLessTheBetter) { ASSERT_EQ(delegate(3, 'c'), 9); // int delegate_functor::operator()(int); - delegate.connect<&delegate_functor::operator()>(&functor); + delegate.connect<&delegate_functor::operator()>(functor); ASSERT_EQ(delegate(3, 'c'), 6); } diff --git a/test/entt/signal/dispatcher.cpp b/test/entt/signal/dispatcher.cpp index 74efbf1f5..af193adf4 100644 --- a/test/entt/signal/dispatcher.cpp +++ b/test/entt/signal/dispatcher.cpp @@ -23,7 +23,7 @@ TEST(Dispatcher, Functionalities) { dispatcher.enqueue(); dispatcher.update(); - dispatcher.sink().connect<&receiver::receive>(&receiver); + dispatcher.sink().connect<&receiver::receive>(receiver); dispatcher.trigger(); dispatcher.enqueue(); @@ -43,7 +43,7 @@ TEST(Dispatcher, Functionalities) { an_event event{}; - dispatcher.sink().disconnect<&receiver::receive>(&receiver); + dispatcher.sink().disconnect<&receiver::receive>(receiver); dispatcher.trigger(); dispatcher.enqueue(event); dispatcher.update(); diff --git a/test/entt/signal/sigh.cpp b/test/entt/signal/sigh.cpp index c6b7e3b99..f9d927ecc 100644 --- a/test/entt/signal/sigh.cpp +++ b/test/entt/signal/sigh.cpp @@ -96,43 +96,34 @@ TEST(SigH, Functions) { ASSERT_TRUE(sigh.empty()); ASSERT_EQ(static_cast::size_type>(0), sigh.size()); ASSERT_EQ(v, 0); - - sink.connect<&sigh_listener::f>(); - - ASSERT_FALSE(sigh.empty()); - ASSERT_EQ(static_cast::size_type>(1), sigh.size()); - - sink.disconnect(nullptr); - - ASSERT_TRUE(sigh.empty()); - ASSERT_EQ(static_cast::size_type>(0), sigh.size());} +} TEST(SigH, Members) { sigh_listener l1, l2; entt::sigh sigh; entt::sink sink{sigh}; - sink.connect<&sigh_listener::g>(&l1); + sink.connect<&sigh_listener::g>(l1); sigh.publish(42); ASSERT_TRUE(l1.k); ASSERT_FALSE(sigh.empty()); ASSERT_EQ(static_cast::size_type>(1), sigh.size()); - sink.disconnect<&sigh_listener::g>(&l1); + sink.disconnect<&sigh_listener::g>(l1); sigh.publish(42); ASSERT_TRUE(l1.k); ASSERT_TRUE(sigh.empty()); ASSERT_EQ(static_cast::size_type>(0), sigh.size()); - sink.connect<&sigh_listener::g>(&l1); - sink.connect<&sigh_listener::h>(&l2); + sink.connect<&sigh_listener::g>(l1); + sink.connect<&sigh_listener::h>(l2); ASSERT_FALSE(sigh.empty()); ASSERT_EQ(static_cast::size_type>(2), sigh.size()); - sink.disconnect(&l1); + sink.disconnect(l1); ASSERT_FALSE(sigh.empty()); ASSERT_EQ(static_cast::size_type>(1), sigh.size()); @@ -144,8 +135,8 @@ TEST(SigH, Collector) { entt::sink sink{sigh}; int cnt = 0; - sink.connect<&sigh_listener::g>(&listener); - sink.connect<&sigh_listener::h>(&listener); + sink.connect<&sigh_listener::g>(listener); + sink.connect<&sigh_listener::h>(listener); listener.k = true; sigh.collect([&listener, &cnt](bool value) { @@ -174,8 +165,8 @@ TEST(SigH, CollectorVoid) { entt::sink sink{sigh}; int cnt = 0; - sink.connect<&sigh_listener::g>(&listener); - sink.connect<&sigh_listener::h>(&listener); + sink.connect<&sigh_listener::g>(listener); + sink.connect<&sigh_listener::h>(listener); sigh.collect([&cnt]() { ++cnt; }, 42); ASSERT_FALSE(sigh.empty()); @@ -219,7 +210,7 @@ TEST(SigH, ScopedConnection) { { ASSERT_FALSE(listener.k); - entt::scoped_connection conn = sink.connect<&sigh_listener::g>(&listener); + entt::scoped_connection conn = sink.connect<&sigh_listener::g>(listener); sigh.publish(42); ASSERT_FALSE(sigh.empty()); @@ -244,7 +235,7 @@ TEST(SigH, ScopedConnectionConstructorsAndOperators) { ASSERT_FALSE(conn); entt::scoped_connection inner{}; - inner = sink.connect<&sigh_listener::g>(&listener); + inner = sink.connect<&sigh_listener::g>(listener); sigh.publish(42); ASSERT_FALSE(sigh.empty()); @@ -256,7 +247,7 @@ TEST(SigH, ScopedConnectionConstructorsAndOperators) { ASSERT_TRUE(sigh.empty()); ASSERT_FALSE(inner); - auto basic = sink.connect<&sigh_listener::g>(&listener); + auto basic = sink.connect<&sigh_listener::g>(listener); inner = std::as_const(basic); sigh.publish(42); @@ -285,19 +276,19 @@ TEST(SigH, ConstNonConstNoExcept) { const_nonconst_noexcept functor; const const_nonconst_noexcept cfunctor; - sink.connect<&const_nonconst_noexcept::f>(&functor); - sink.connect<&const_nonconst_noexcept::g>(&functor); - sink.connect<&const_nonconst_noexcept::h>(&cfunctor); - sink.connect<&const_nonconst_noexcept::i>(&cfunctor); + sink.connect<&const_nonconst_noexcept::f>(functor); + sink.connect<&const_nonconst_noexcept::g>(functor); + sink.connect<&const_nonconst_noexcept::h>(cfunctor); + sink.connect<&const_nonconst_noexcept::i>(cfunctor); sigh.publish(); ASSERT_EQ(functor.cnt, 2); ASSERT_EQ(cfunctor.cnt, 2); - sink.disconnect<&const_nonconst_noexcept::f>(&functor); - sink.disconnect<&const_nonconst_noexcept::g>(&functor); - sink.disconnect<&const_nonconst_noexcept::h>(&cfunctor); - sink.disconnect<&const_nonconst_noexcept::i>(&cfunctor); + sink.disconnect<&const_nonconst_noexcept::f>(functor); + sink.disconnect<&const_nonconst_noexcept::g>(functor); + sink.disconnect<&const_nonconst_noexcept::h>(cfunctor); + sink.disconnect<&const_nonconst_noexcept::i>(cfunctor); sigh.publish(); ASSERT_EQ(functor.cnt, 2); diff --git a/test/lib/lib.cpp b/test/lib/lib.cpp index 3e7fd0867..236441da4 100644 --- a/test/lib/lib.cpp +++ b/test/lib/lib.cpp @@ -68,8 +68,8 @@ TEST(Lib, Dispatcher) { entt::dispatcher dispatcher; listener listener; - dispatcher.sink().connect<&listener::on_an_event>(&listener); - dispatcher.sink().connect<&listener::on_another_event>(&listener); + dispatcher.sink().connect<&listener::on_an_event>(listener); + dispatcher.sink().connect<&listener::on_another_event>(listener); listener.value = 0;