Skip to content

Commit

Permalink
more on sigh/sink
Browse files Browse the repository at this point in the history
  • Loading branch information
skypjack committed May 31, 2019
1 parent 1cdb9ef commit ddba29c
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 17 deletions.
1 change: 1 addition & 0 deletions TODO
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* debugging tools (#60): the issue online already contains interesting tips on this, look at it
* runner proposal: https://en.wikipedia.org/wiki/Fork%E2%80%93join_model https://slide-rs.github.io/specs/03_dispatcher.html
* work stealing job system (see #100)
- mt scheduler based on const awareness for types
* meta: sort of meta view based on meta stuff to iterate entities, void * and meta info objects
* allow for built-in parallel each if possible
* allow to replace std:: with custom implementations
Expand Down
7 changes: 5 additions & 2 deletions docs/md/signal.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ signal.sink().disconnect<&foo>();
// disconnect a member function of an instance
signal.sink().disconnect<&listener::bar>(&instance);

// disconnect all the member functions of an instance, if any
signal.sink().disconnect(&instance);

// discards all the listeners at once
signal.sink().disconnect();
```
Expand Down Expand Up @@ -289,11 +292,11 @@ dispatcher.sink<another_event>().connect<&listener::method>(&listener);
```

The `disconnect` member function follows the same pattern and can be used to
selectively remove listeners:
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::method>(&listener);
dispatcher.sink<another_event>().disconnect(&listener);
```

The `trigger` member function serves the purpose of sending an immediate event
Expand Down
11 changes: 11 additions & 0 deletions src/entt/signal/sigh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,17 @@ class sink<Ret(Args...)> {
}), calls->end());
}

/**
* @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.
*/
void disconnect(const void *value_or_instance) {
calls->erase(std::remove_if(calls->begin(), calls->end(), [value_or_instance](const auto &delegate) {
return value_or_instance == delegate.instance();
}), calls->end());
}

/**
* @brief Disconnects all the listeners from a signal.
*/
Expand Down
35 changes: 20 additions & 15 deletions test/entt/signal/sigh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,50 +111,55 @@ TEST(SigH, Functions) {
sigh.publish(v);

ASSERT_FALSE(sigh.empty());
ASSERT_EQ(static_cast<entt::sigh<bool(int)>::size_type>(1), sigh.size());
ASSERT_EQ(static_cast<entt::sigh<void(int &)>::size_type>(1), sigh.size());
ASSERT_EQ(42, v);

v = 0;
sigh.sink().disconnect<&sigh_listener::f>();
sigh.publish(v);

ASSERT_TRUE(sigh.empty());
ASSERT_EQ(static_cast<entt::sigh<bool(int)>::size_type>(0), sigh.size());
ASSERT_EQ(static_cast<entt::sigh<void(int &)>::size_type>(0), sigh.size());
ASSERT_EQ(v, 0);

sigh.sink().connect<&sigh_listener::f>();
}

ASSERT_FALSE(sigh.empty());
ASSERT_EQ(static_cast<entt::sigh<void(int &)>::size_type>(1), sigh.size());

sigh.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 s;
sigh_listener *ptr = &s;
sigh_listener l1, l2;
entt::sigh<bool(int)> sigh;

sigh.sink().connect<&sigh_listener::g>(ptr);
sigh.sink().connect<&sigh_listener::g>(&l1);
sigh.publish(42);

ASSERT_TRUE(s.k);
ASSERT_TRUE(l1.k);
ASSERT_FALSE(sigh.empty());
ASSERT_EQ(static_cast<entt::sigh<bool(int)>::size_type>(1), sigh.size());

sigh.sink().disconnect<&sigh_listener::g>(ptr);
sigh.sink().disconnect<&sigh_listener::g>(&l1);
sigh.publish(42);

ASSERT_TRUE(s.k);
ASSERT_TRUE(l1.k);
ASSERT_TRUE(sigh.empty());
ASSERT_EQ(static_cast<entt::sigh<bool(int)>::size_type>(0), sigh.size());

sigh.sink().connect<&sigh_listener::g>(ptr);
sigh.sink().connect<&sigh_listener::h>(ptr);
sigh.sink().connect<&sigh_listener::g>(&l1);
sigh.sink().connect<&sigh_listener::h>(&l2);

ASSERT_FALSE(sigh.empty());
ASSERT_EQ(static_cast<entt::sigh<bool(int)>::size_type>(2), sigh.size());

sigh.sink().disconnect<&sigh_listener::g>(ptr);
sigh.sink().disconnect<&sigh_listener::h>(ptr);
sigh.sink().disconnect(&l1);

ASSERT_TRUE(sigh.empty());
ASSERT_EQ(static_cast<entt::sigh<bool(int)>::size_type>(0), sigh.size());
ASSERT_FALSE(sigh.empty());
ASSERT_EQ(static_cast<entt::sigh<bool(int)>::size_type>(1), sigh.size());
}

TEST(SigH, Collector) {
Expand Down

0 comments on commit ddba29c

Please sign in to comment.