21 #include <gtest/gtest.h>
23 #include <condition_variable>
33 Expectation(
const T& expected_value) : expected_value(expected_value)
37 bool satisfied()
const
39 return triggered && current_value == expected_value;
42 bool triggered =
false;
48 TEST(Signal, emission_works)
50 Expectation<int> expectation{42};
53 s.
connect([&expectation](
int value) { expectation.triggered =
true; expectation.current_value = value; });
57 EXPECT_TRUE(expectation.satisfied());
60 TEST(Signal, disconnect_results_in_slots_not_invoked_anymore)
62 Expectation<int> expectation{42};
66 [&expectation](
int value)
68 expectation.triggered =
true;
69 expectation.current_value = value;
74 EXPECT_FALSE(expectation.satisfied());
77 TEST(Signal, disconnect_via_scoped_connection_results_in_slots_not_invoked_anymore)
79 Expectation<int> expectation{42};
83 [&expectation](
int value)
85 expectation.triggered =
true;
86 expectation.current_value = value;
93 EXPECT_FALSE(expectation.satisfied());
96 TEST(Signal, a_signal_going_out_of_scope_disconnects_from_slots)
98 auto signal = std::make_shared<core::Signal<int>>();
100 auto connection = signal->connect([](
int value) { std::cout << value << std::endl; });
106 EXPECT_NO_THROW(connection.disconnect());
107 EXPECT_NO_THROW(connection.dispatch_via(dispatcher));
116 typedef std::function<void()> Handler;
120 stop_requested =
true;
125 while (!stop_requested)
127 std::unique_lock<std::mutex> ul(guard);
128 wait_condition.wait_for(
130 std::chrono::milliseconds{500},
131 [
this]() {
return handlers.size() > 0; });
133 while (handlers.size() > 0)
141 void dispatch(
const Handler& h)
143 std::lock_guard<std::mutex> lg(guard);
147 bool stop_requested =
false;
148 std::queue<Handler> handlers;
150 std::condition_variable wait_condition;
154 TEST(Signal, installing_a_custom_dispatcher_ensures_invocation_on_correct_thread)
157 EventLoop dispatcher;
158 std::thread dispatcher_thread{[&dispatcher]() { dispatcher.run(); }};
159 std::thread::id dispatcher_thread_id = dispatcher_thread.get_id();
164 static const int expected_invocation_count = 10000;
170 [&dispatcher, dispatcher_thread_id](
int value,
double)
172 EXPECT_EQ(dispatcher_thread_id,
173 std::this_thread::get_id());
175 if (value == expected_invocation_count)
182 &EventLoop::dispatch,
183 std::ref(dispatcher),
184 std::placeholders::_1));
187 for (
unsigned int i = 1; i <= expected_invocation_count; i++)
190 if (dispatcher_thread.joinable())
191 dispatcher_thread.join();
void dispatch_via(const Dispatcher &dispatcher)
Installs a dispatcher for this signal-slot connection.
void disconnect()
End a signal-slot connection.
std::function< void(const std::function< void()> &)> Dispatcher
Scoped helper class to map signal-slot connection mgmt. to RAII.
A signal class that observers can subscribe to.
Connection connect(const Slot &slot) const
Connects the provided slot to this signal instance.
TEST(Signal, emission_works)