signals meet references (close #289)
This commit is contained in:
1
TODO
1
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
|
||||
|
||||
@@ -348,13 +348,13 @@ notified on the creation of a component, use the `on_construct` member function:
|
||||
registry.on_construct<position>().connect<&my_free_function>();
|
||||
|
||||
// connects a member function
|
||||
registry.on_construct<position>().connect<&my_class::member>(&instance);
|
||||
registry.on_construct<position>().connect<&my_class::member>(instance);
|
||||
|
||||
// disconnects a free function
|
||||
registry.on_construct<position>().disconnect<&my_free_function>();
|
||||
|
||||
// disconnects a member function
|
||||
registry.on_construct<position>().disconnect<&my_class::member>(&instance);
|
||||
registry.on_construct<position>().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.<br/>
|
||||
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
|
||||
|
||||
@@ -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.<br/>
|
||||
@@ -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<an_event>().connect<&listener::receive>(&listener);
|
||||
dispatcher.sink<another_event>().connect<&listener::method>(&listener);
|
||||
dispatcher.sink<an_event>().connect<&listener::receive>(listener);
|
||||
dispatcher.sink<another_event>().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<an_event>().disconnect<&listener::receive>(&listener);
|
||||
dispatcher.sink<another_event>().disconnect(&listener);
|
||||
dispatcher.sink<an_event>().disconnect<&listener::receive>(listener);
|
||||
dispatcher.sink<another_event>().disconnect(listener);
|
||||
```
|
||||
|
||||
The `trigger` member function serves the purpose of sending an immediate event
|
||||
|
||||
@@ -173,72 +173,72 @@ class basic_observer {
|
||||
template<typename... Reject, typename... Require, typename AnyOf>
|
||||
struct matcher_handler<matcher<matcher<type_list<Reject...>, type_list<Require...>>, AnyOf>> {
|
||||
template<std::size_t Index>
|
||||
static void maybe_valid_if(basic_observer *obs, const basic_registry<Entity> ®, const Entity entt) {
|
||||
static void maybe_valid_if(basic_observer &obs, const basic_registry<Entity> ®, const Entity entt) {
|
||||
if(reg.template has<Require...>(entt) && !(reg.template has<Reject>(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<std::size_t Index>
|
||||
static void discard_if(basic_observer *obs, const basic_registry<Entity> &, 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<Entity> &, const Entity entt) {
|
||||
if(auto *value = obs.view.try_get(entt); value && !(*value &= (~(1 << Index)))) {
|
||||
obs.view.destroy(entt);
|
||||
}
|
||||
}
|
||||
|
||||
template<std::size_t Index>
|
||||
static void connect(basic_observer &obs, basic_registry<Entity> ®) {
|
||||
(reg.template on_destroy<Require>().template connect<&discard_if<Index>>(&obs), ...);
|
||||
(reg.template on_construct<Reject>().template connect<&discard_if<Index>>(&obs), ...);
|
||||
reg.template on_replace<AnyOf>().template connect<&maybe_valid_if<Index>>(&obs);
|
||||
reg.template on_destroy<AnyOf>().template connect<&discard_if<Index>>(&obs);
|
||||
(reg.template on_destroy<Require>().template connect<&discard_if<Index>>(obs), ...);
|
||||
(reg.template on_construct<Reject>().template connect<&discard_if<Index>>(obs), ...);
|
||||
reg.template on_replace<AnyOf>().template connect<&maybe_valid_if<Index>>(obs);
|
||||
reg.template on_destroy<AnyOf>().template connect<&discard_if<Index>>(obs);
|
||||
}
|
||||
|
||||
static void disconnect(basic_observer &obs, basic_registry<Entity> ®) {
|
||||
(reg.template on_destroy<Require>().disconnect(&obs), ...);
|
||||
(reg.template on_construct<Reject>().disconnect(&obs), ...);
|
||||
reg.template on_replace<AnyOf>().disconnect(&obs);
|
||||
reg.template on_destroy<AnyOf>().disconnect(&obs);
|
||||
(reg.template on_destroy<Require>().disconnect(obs), ...);
|
||||
(reg.template on_construct<Reject>().disconnect(obs), ...);
|
||||
reg.template on_replace<AnyOf>().disconnect(obs);
|
||||
reg.template on_destroy<AnyOf>().disconnect(obs);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename... Reject, typename... Require, typename... NoneOf, typename... AllOf>
|
||||
struct matcher_handler<matcher<matcher<type_list<Reject...>, type_list<Require...>>, type_list<NoneOf...>, type_list<AllOf...>>> {
|
||||
template<std::size_t Index>
|
||||
static void maybe_valid_if(basic_observer *obs, const basic_registry<Entity> ®, const Entity entt) {
|
||||
static void maybe_valid_if(basic_observer &obs, const basic_registry<Entity> ®, const Entity entt) {
|
||||
if(reg.template has<AllOf...>(entt) && !(reg.template has<NoneOf>(entt) || ...)
|
||||
&& reg.template has<Require...>(entt) && !(reg.template has<Reject>(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<std::size_t Index>
|
||||
static void discard_if(basic_observer *obs, const basic_registry<Entity> &, 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<Entity> &, const Entity entt) {
|
||||
if(auto *value = obs.view.try_get(entt); value && !(*value &= (~(1 << Index)))) {
|
||||
obs.view.destroy(entt);
|
||||
}
|
||||
}
|
||||
|
||||
template<std::size_t Index>
|
||||
static void connect(basic_observer &obs, basic_registry<Entity> ®) {
|
||||
(reg.template on_destroy<Require>().template connect<&discard_if<Index>>(&obs), ...);
|
||||
(reg.template on_construct<Reject>().template connect<&discard_if<Index>>(&obs), ...);
|
||||
(reg.template on_construct<AllOf>().template connect<&maybe_valid_if<Index>>(&obs), ...);
|
||||
(reg.template on_destroy<NoneOf>().template connect<&maybe_valid_if<Index>>(&obs), ...);
|
||||
(reg.template on_destroy<AllOf>().template connect<&discard_if<Index>>(&obs), ...);
|
||||
(reg.template on_construct<NoneOf>().template connect<&discard_if<Index>>(&obs), ...);
|
||||
(reg.template on_destroy<Require>().template connect<&discard_if<Index>>(obs), ...);
|
||||
(reg.template on_construct<Reject>().template connect<&discard_if<Index>>(obs), ...);
|
||||
(reg.template on_construct<AllOf>().template connect<&maybe_valid_if<Index>>(obs), ...);
|
||||
(reg.template on_destroy<NoneOf>().template connect<&maybe_valid_if<Index>>(obs), ...);
|
||||
(reg.template on_destroy<AllOf>().template connect<&discard_if<Index>>(obs), ...);
|
||||
(reg.template on_construct<NoneOf>().template connect<&discard_if<Index>>(obs), ...);
|
||||
}
|
||||
|
||||
static void disconnect(basic_observer &obs, basic_registry<Entity> ®) {
|
||||
(reg.template on_destroy<Require>().disconnect(&obs), ...);
|
||||
(reg.template on_construct<Reject>().disconnect(&obs), ...);
|
||||
(reg.template on_construct<AllOf>().disconnect(&obs), ...);
|
||||
(reg.template on_destroy<NoneOf>().disconnect(&obs), ...);
|
||||
(reg.template on_destroy<AllOf>().disconnect(&obs), ...);
|
||||
(reg.template on_construct<NoneOf>().disconnect(&obs), ...);
|
||||
(reg.template on_destroy<Require>().disconnect(obs), ...);
|
||||
(reg.template on_construct<Reject>().disconnect(obs), ...);
|
||||
(reg.template on_construct<AllOf>().disconnect(obs), ...);
|
||||
(reg.template on_destroy<NoneOf>().disconnect(obs), ...);
|
||||
(reg.template on_destroy<AllOf>().disconnect(obs), ...);
|
||||
(reg.template on_construct<NoneOf>().disconnect(obs), ...);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1347,14 +1347,14 @@ public:
|
||||
ENTT_ASSERT((!std::get<pool_type<Owned> *>(curr->cpools)->group && ...));
|
||||
|
||||
((std::get<pool_type<Owned> *>(curr->cpools)->group = curr), ...);
|
||||
(std::get<pool_type<Owned> *>(curr->cpools)->on_construct().template connect<&handler_type::template maybe_valid_if<Owned>>(curr), ...);
|
||||
(std::get<pool_type<Owned> *>(curr->cpools)->on_destroy().template connect<&handler_type::discard_if>(curr), ...);
|
||||
(std::get<pool_type<Owned> *>(curr->cpools)->on_construct().template connect<&handler_type::template maybe_valid_if<Owned>>(*curr), ...);
|
||||
(std::get<pool_type<Owned> *>(curr->cpools)->on_destroy().template connect<&handler_type::discard_if>(*curr), ...);
|
||||
|
||||
(std::get<pool_type<Get> *>(curr->cpools)->on_construct().template connect<&handler_type::template maybe_valid_if<Get>>(curr), ...);
|
||||
(std::get<pool_type<Get> *>(curr->cpools)->on_destroy().template connect<&handler_type::discard_if>(curr), ...);
|
||||
(std::get<pool_type<Get> *>(curr->cpools)->on_construct().template connect<&handler_type::template maybe_valid_if<Get>>(*curr), ...);
|
||||
(std::get<pool_type<Get> *>(curr->cpools)->on_destroy().template connect<&handler_type::discard_if>(*curr), ...);
|
||||
|
||||
(std::get<pool_type<Exclude> *>(curr->cpools)->on_destroy().template connect<&handler_type::template maybe_valid_if<Exclude>>(curr), ...);
|
||||
(std::get<pool_type<Exclude> *>(curr->cpools)->on_construct().template connect<&handler_type::discard_if>(curr), ...);
|
||||
(std::get<pool_type<Exclude> *>(curr->cpools)->on_destroy().template connect<&handler_type::template maybe_valid_if<Exclude>>(*curr), ...);
|
||||
(std::get<pool_type<Exclude> *>(curr->cpools)->on_construct().template connect<&handler_type::discard_if>(*curr), ...);
|
||||
|
||||
const auto *cpool = std::min({
|
||||
static_cast<sparse_set<Entity> *>(std::get<pool_type<Owned> *>(curr->cpools))...,
|
||||
|
||||
@@ -27,20 +27,20 @@ template<typename Ret, typename... Args>
|
||||
auto to_function_pointer(Ret(*)(Args...)) -> Ret(*)(Args...);
|
||||
|
||||
|
||||
template<typename Ret, typename... Args, typename Type, typename Payload, typename = std::enable_if_t<std::is_convertible_v<Payload *, Type *>>>
|
||||
auto to_function_pointer(Ret(*)(Type *, Args...), Payload *) -> Ret(*)(Args...);
|
||||
template<typename Ret, typename... Args, typename Type, typename Payload, typename = std::enable_if_t<std::is_convertible_v<Payload &, Type &>>>
|
||||
auto to_function_pointer(Ret(*)(Type &, Args...), Payload &) -> Ret(*)(Args...);
|
||||
|
||||
|
||||
template<typename Class, typename Ret, typename... Args>
|
||||
auto to_function_pointer(Ret(Class:: *)(Args...), const Class *) -> Ret(*)(Args...);
|
||||
auto to_function_pointer(Ret(Class:: *)(Args...), const Class &) -> Ret(*)(Args...);
|
||||
|
||||
|
||||
template<typename Class, typename Ret, typename... Args>
|
||||
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<typename Class, typename Type>
|
||||
auto to_function_pointer(Type Class:: *, const Class *) -> Type(*)();
|
||||
auto to_function_pointer(Type Class:: *, const Class &) -> Type(*)();
|
||||
|
||||
|
||||
template<typename>
|
||||
@@ -115,9 +115,9 @@ class delegate<Ret(Args...)> {
|
||||
}
|
||||
|
||||
template<auto Candidate, typename Type, std::size_t... Index>
|
||||
void connect(Type *value_or_instance, std::index_sequence<Index...>) ENTT_NOEXCEPT {
|
||||
static_assert(std::is_invocable_r_v<Ret, decltype(Candidate), Type *, std::tuple_element_t<Index, std::tuple<Args...>>...>);
|
||||
data = value_or_instance;
|
||||
void connect(Type &value_or_instance, std::index_sequence<Index...>) ENTT_NOEXCEPT {
|
||||
static_assert(std::is_invocable_r_v<Ret, decltype(Candidate), Type &, std::tuple_element_t<Index, std::tuple<Args...>>...>);
|
||||
data = &value_or_instance;
|
||||
|
||||
fn = [](const void *payload, std::tuple<Args &&...> args) -> Ret {
|
||||
Type *curr = nullptr;
|
||||
@@ -129,7 +129,7 @@ class delegate<Ret(Args...)> {
|
||||
}
|
||||
|
||||
// Ret(...) makes void(...) eat the return values to avoid errors
|
||||
return Ret(std::invoke(Candidate, curr, std::forward<std::tuple_element_t<Index, std::tuple<Args...>>>(std::get<Index>(args))...));
|
||||
return Ret(std::invoke(Candidate, *curr, std::forward<std::tuple_element_t<Index, std::tuple<Args...>>>(std::get<Index>(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<auto Candidate, typename Type>
|
||||
delegate(connect_arg_t<Candidate>, Type *value_or_instance) ENTT_NOEXCEPT
|
||||
delegate(connect_arg_t<Candidate>, Type &value_or_instance) ENTT_NOEXCEPT
|
||||
: delegate{}
|
||||
{
|
||||
connect<Candidate>(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<auto Candidate, typename Type>
|
||||
void connect(Type *value_or_instance) ENTT_NOEXCEPT {
|
||||
constexpr auto extent = internal::function_extent_v<decltype(internal::to_function_pointer(std::declval<decltype(Candidate)>(), std::declval<Type *>()))>;
|
||||
void connect(Type &value_or_instance) ENTT_NOEXCEPT {
|
||||
constexpr auto extent = internal::function_extent_v<decltype(internal::to_function_pointer(std::declval<decltype(Candidate)>(), value_or_instance))>;
|
||||
connect<Candidate>(value_or_instance, std::make_index_sequence<extent>{});
|
||||
}
|
||||
|
||||
@@ -292,12 +292,13 @@ delegate(connect_arg_t<Function>) 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<auto Candidate, typename Type>
|
||||
delegate(connect_arg_t<Candidate>, Type *) ENTT_NOEXCEPT
|
||||
-> delegate<std::remove_pointer_t<decltype(internal::to_function_pointer(Candidate, std::declval<Type *>()))>>;
|
||||
delegate(connect_arg_t<Candidate>, Type &value_or_instance) ENTT_NOEXCEPT
|
||||
-> delegate<std::remove_pointer_t<decltype(internal::to_function_pointer(Candidate, value_or_instance))>>;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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<struct internal_dispatcher_event_family>;
|
||||
|
||||
@@ -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<Ret(Args...)> {
|
||||
using signal_type = sigh<Ret(Args...)>;
|
||||
|
||||
template<auto Candidate, typename Type>
|
||||
static void release(Type *value_or_instance, void *signal) {
|
||||
static void release(Type &value_or_instance, void *signal) {
|
||||
sink{*static_cast<signal_type *>(signal)}.disconnect<Candidate>(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<auto Candidate, typename Type>
|
||||
connection connect(Type *value_or_instance) {
|
||||
connection connect(Type &value_or_instance) {
|
||||
disconnect<Candidate>(value_or_instance);
|
||||
delegate<void(void *)> conn{};
|
||||
conn.template connect<&sink::release<Candidate, Type>>(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<auto Candidate, typename Type>
|
||||
void disconnect(Type *value_or_instance) {
|
||||
void disconnect(Type &value_or_instance) {
|
||||
auto &calls = signal->calls;
|
||||
delegate<Ret(Args...)> delegate{};
|
||||
delegate.template connect<Candidate>(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<typename Type>
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
@@ -925,10 +925,10 @@ TEST(Registry, Signals) {
|
||||
entt::registry registry;
|
||||
listener listener;
|
||||
|
||||
registry.on_construct<empty_type>().connect<&listener::incr<empty_type>>(&listener);
|
||||
registry.on_destroy<empty_type>().connect<&listener::decr<empty_type>>(&listener);
|
||||
registry.on_construct<int>().connect<&listener::incr<int>>(&listener);
|
||||
registry.on_destroy<int>().connect<&listener::decr<int>>(&listener);
|
||||
registry.on_construct<empty_type>().connect<&listener::incr<empty_type>>(listener);
|
||||
registry.on_destroy<empty_type>().connect<&listener::decr<empty_type>>(listener);
|
||||
registry.on_construct<int>().connect<&listener::incr<int>>(listener);
|
||||
registry.on_destroy<int>().connect<&listener::decr<int>>(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<empty_type>().disconnect<&listener::decr<empty_type>>(&listener);
|
||||
registry.on_destroy<int>().disconnect<&listener::decr<int>>(&listener);
|
||||
registry.on_destroy<empty_type>().disconnect<&listener::decr<empty_type>>(listener);
|
||||
registry.on_destroy<int>().disconnect<&listener::decr<int>>(listener);
|
||||
|
||||
registry.remove<empty_type>(e1);
|
||||
registry.remove<int>(e1);
|
||||
@@ -960,8 +960,8 @@ TEST(Registry, Signals) {
|
||||
ASSERT_EQ(listener.counter, 2);
|
||||
ASSERT_EQ(listener.last, e0);
|
||||
|
||||
registry.on_construct<empty_type>().disconnect<&listener::incr<empty_type>>(&listener);
|
||||
registry.on_construct<int>().disconnect<&listener::incr<int>>(&listener);
|
||||
registry.on_construct<empty_type>().disconnect<&listener::incr<empty_type>>(listener);
|
||||
registry.on_construct<int>().disconnect<&listener::incr<int>>(listener);
|
||||
|
||||
registry.assign<empty_type>(e1);
|
||||
registry.assign<int>(e1);
|
||||
@@ -969,8 +969,8 @@ TEST(Registry, Signals) {
|
||||
ASSERT_EQ(listener.counter, 2);
|
||||
ASSERT_EQ(listener.last, e0);
|
||||
|
||||
registry.on_construct<int>().connect<&listener::incr<int>>(&listener);
|
||||
registry.on_destroy<int>().connect<&listener::decr<int>>(&listener);
|
||||
registry.on_construct<int>().connect<&listener::incr<int>>(listener);
|
||||
registry.on_destroy<int>().connect<&listener::decr<int>>(listener);
|
||||
|
||||
registry.assign<int>(e0);
|
||||
registry.reset<int>(e1);
|
||||
@@ -978,8 +978,8 @@ TEST(Registry, Signals) {
|
||||
ASSERT_EQ(listener.counter, 2);
|
||||
ASSERT_EQ(listener.last, e1);
|
||||
|
||||
registry.on_construct<empty_type>().connect<&listener::incr<empty_type>>(&listener);
|
||||
registry.on_destroy<empty_type>().connect<&listener::decr<empty_type>>(&listener);
|
||||
registry.on_construct<empty_type>().connect<&listener::incr<empty_type>>(listener);
|
||||
registry.on_destroy<empty_type>().connect<&listener::decr<empty_type>>(listener);
|
||||
|
||||
registry.reset<empty_type>(e1);
|
||||
registry.assign<empty_type>(e0);
|
||||
@@ -1011,8 +1011,8 @@ TEST(Registry, Signals) {
|
||||
ASSERT_EQ(listener.counter, 2);
|
||||
ASSERT_EQ(listener.last, e0);
|
||||
|
||||
registry.on_destroy<empty_type>().disconnect<&listener::decr<empty_type>>(&listener);
|
||||
registry.on_destroy<int>().disconnect<&listener::decr<int>>(&listener);
|
||||
registry.on_destroy<empty_type>().disconnect<&listener::decr<empty_type>>(listener);
|
||||
registry.on_destroy<int>().disconnect<&listener::decr<int>>(listener);
|
||||
|
||||
registry.assign_or_replace<empty_type>(e0);
|
||||
registry.assign_or_replace<int>(e0);
|
||||
@@ -1020,8 +1020,8 @@ TEST(Registry, Signals) {
|
||||
ASSERT_EQ(listener.counter, 2);
|
||||
ASSERT_EQ(listener.last, e0);
|
||||
|
||||
registry.on_replace<empty_type>().connect<&listener::incr<empty_type>>(&listener);
|
||||
registry.on_replace<int>().connect<&listener::incr<int>>(&listener);
|
||||
registry.on_replace<empty_type>().connect<&listener::incr<empty_type>>(listener);
|
||||
registry.on_replace<int>().connect<&listener::incr<int>>(listener);
|
||||
|
||||
registry.assign_or_replace<empty_type>(e0);
|
||||
registry.assign_or_replace<int>(e0);
|
||||
@@ -1179,13 +1179,13 @@ TEST(Registry, CreateManyEntitiesWithComponentsAtOnceWithListener) {
|
||||
entt::entity entities[3];
|
||||
listener listener;
|
||||
|
||||
registry.on_construct<int>().connect<&listener::incr<int>>(&listener);
|
||||
registry.on_construct<int>().connect<&listener::incr<int>>(listener);
|
||||
registry.create<int, char>(std::begin(entities), std::end(entities));
|
||||
|
||||
ASSERT_EQ(listener.counter, 3);
|
||||
|
||||
registry.on_construct<int>().disconnect<&listener::incr<int>>(&listener);
|
||||
registry.on_construct<empty_type>().connect<&listener::incr<empty_type>>(&listener);
|
||||
registry.on_construct<int>().disconnect<&listener::incr<int>>(listener);
|
||||
registry.on_construct<empty_type>().connect<&listener::incr<empty_type>>(listener);
|
||||
registry.create<char, empty_type>(std::begin(entities), std::end(entities));
|
||||
|
||||
ASSERT_EQ(listener.counter, 6);
|
||||
|
||||
@@ -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<double()> 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<int(int)>{entt::connect_arg<&curried_function>, &value}));
|
||||
ASSERT_EQ(lhs, (entt::delegate<int(int)>{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<int(int)>{entt::connect_arg<&curried_function>, &value}));
|
||||
ASSERT_EQ(rhs, (entt::delegate<int(int)>{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<int(int)>{entt::connect_arg<&delegate_functor::operator()>, &functor}));
|
||||
ASSERT_EQ(lhs, (entt::delegate<int(int)>{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<int(int)>{entt::connect_arg<&delegate_functor::operator()>, &functor}));
|
||||
ASSERT_EQ(rhs, (entt::delegate<int(int)>{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<int(int)>{entt::connect_arg<&delegate_functor::operator()>, &other}));
|
||||
ASSERT_EQ(lhs, (entt::delegate<int(int)>{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<void()> 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<typename decltype(func)::function_type, int(const int &)>);
|
||||
static_assert(std::is_same_v<typename decltype(curried_func)::function_type, int(int)>);
|
||||
@@ -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<int(int)> 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<int(int)> empty{};
|
||||
entt::delegate<int(int)> func{entt::connect_arg<&delegate_function>};
|
||||
entt::delegate<int(int)> curr{entt::connect_arg<&curried_function>, &value};
|
||||
entt::delegate<int(int)> member{entt::connect_arg<&delegate_functor::operator()>, &functor};
|
||||
entt::delegate<int(int)> curr{entt::connect_arg<&curried_function>, value};
|
||||
entt::delegate<int(int)> member{entt::connect_arg<&delegate_functor::operator()>, functor};
|
||||
|
||||
ASSERT_FALSE(empty);
|
||||
|
||||
@@ -297,8 +297,8 @@ TEST(Delegate, VoidVsNonVoidReturnType) {
|
||||
delegate_functor functor;
|
||||
|
||||
entt::delegate<void(int)> func{entt::connect_arg<&delegate_function>};
|
||||
entt::delegate<void(int)> member{entt::connect_arg<&delegate_functor::operator()>, &functor};
|
||||
entt::delegate<void(int)> cmember{entt::connect_arg<&delegate_functor::identity>, &std::as_const(functor)};
|
||||
entt::delegate<void(int)> member{entt::connect_arg<&delegate_functor::operator()>, functor};
|
||||
entt::delegate<void(int)> 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);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ TEST(Dispatcher, Functionalities) {
|
||||
dispatcher.enqueue<one_more_event>();
|
||||
dispatcher.update<one_more_event>();
|
||||
|
||||
dispatcher.sink<an_event>().connect<&receiver::receive>(&receiver);
|
||||
dispatcher.sink<an_event>().connect<&receiver::receive>(receiver);
|
||||
dispatcher.trigger<an_event>();
|
||||
dispatcher.enqueue<an_event>();
|
||||
|
||||
@@ -43,7 +43,7 @@ TEST(Dispatcher, Functionalities) {
|
||||
|
||||
an_event event{};
|
||||
|
||||
dispatcher.sink<an_event>().disconnect<&receiver::receive>(&receiver);
|
||||
dispatcher.sink<an_event>().disconnect<&receiver::receive>(receiver);
|
||||
dispatcher.trigger<an_event>();
|
||||
dispatcher.enqueue(event);
|
||||
dispatcher.update();
|
||||
|
||||
@@ -96,43 +96,34 @@ TEST(SigH, Functions) {
|
||||
ASSERT_TRUE(sigh.empty());
|
||||
ASSERT_EQ(static_cast<entt::sigh<void(int &)>::size_type>(0), sigh.size());
|
||||
ASSERT_EQ(v, 0);
|
||||
|
||||
sink.connect<&sigh_listener::f>();
|
||||
|
||||
ASSERT_FALSE(sigh.empty());
|
||||
ASSERT_EQ(static_cast<entt::sigh<void(int &)>::size_type>(1), sigh.size());
|
||||
|
||||
sink.disconnect(nullptr);
|
||||
|
||||
ASSERT_TRUE(sigh.empty());
|
||||
ASSERT_EQ(static_cast<entt::sigh<void(int &)>::size_type>(0), sigh.size());}
|
||||
}
|
||||
|
||||
TEST(SigH, Members) {
|
||||
sigh_listener l1, l2;
|
||||
entt::sigh<bool(int)> 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<entt::sigh<bool(int)>::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<entt::sigh<bool(int)>::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<entt::sigh<bool(int)>::size_type>(2), sigh.size());
|
||||
|
||||
sink.disconnect(&l1);
|
||||
sink.disconnect(l1);
|
||||
|
||||
ASSERT_FALSE(sigh.empty());
|
||||
ASSERT_EQ(static_cast<entt::sigh<bool(int)>::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);
|
||||
|
||||
@@ -68,8 +68,8 @@ TEST(Lib, Dispatcher) {
|
||||
entt::dispatcher dispatcher;
|
||||
listener listener;
|
||||
|
||||
dispatcher.sink<an_event>().connect<&listener::on_an_event>(&listener);
|
||||
dispatcher.sink<another_event>().connect<&listener::on_another_event>(&listener);
|
||||
dispatcher.sink<an_event>().connect<&listener::on_an_event>(listener);
|
||||
dispatcher.sink<another_event>().connect<&listener::on_another_event>(listener);
|
||||
|
||||
listener.value = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user