3 #ifndef SPECTMORPH_SIGNAL_HH
4 #define SPECTMORPH_SIGNAL_HH
15 template<
class... Args>
23 static uint64 next_id = 1;
27 virtual void disconnect_impl (uint64
id) = 0;
41 struct SignalReceiverData
48 assert (ref_count > 0);
55 assert (ref_count > 0);
58 if (cleanup && ref_count == 1)
60 sources.remove_if ([](SignalSource& signal_source) ->
bool
62 return signal_source.id == 0;
65 else if (ref_count == 0)
68 std::list<SignalSource> sources;
70 struct SignalReceiverData *signal_receiver_data;
73 template<
class... Args,
class CbFunction>
77 assert (signal_receiver_data);
79 SignalReceiverData *data = signal_receiver_data->ref();
81 auto id = signal.connect_impl (
this, callback);
82 data->sources.push_back ({ &signal,
id });
87 template<
class... Args,
class Instance,
class Method>
89 connect (
Signal<Args...>& signal, Instance *instance,
const Method& method)
91 return SignalReceiver::connect (signal, [instance, method](Args&&... args)
93 (instance->*method) (std::forward<Args>(args)...);
97 disconnect (uint64
id)
99 assert (signal_receiver_data);
101 SignalReceiverData *data = signal_receiver_data->ref();
103 for (
auto& signal_source : data->sources)
105 if (signal_source.id ==
id)
107 signal_source.signal->disconnect_impl (
id);
108 signal_source.id = 0;
114 signal_receiver_data (
new SignalReceiverData())
120 assert (signal_receiver_data);
122 for (
auto& signal_source : signal_receiver_data->sources)
124 if (signal_source.id)
126 signal_source.signal->disconnect_impl (signal_source.id);
127 signal_source.id = 0;
130 signal_receiver_data->unref (
false);
131 signal_receiver_data =
nullptr;
134 dead_signal (uint64
id)
136 SignalReceiverData *data = signal_receiver_data->ref();
138 for (
auto& signal_source : data->sources)
140 if (signal_source.id ==
id)
141 signal_source.id = 0;
148 template<
class... Args>
151 SPECTMORPH_CLASS_NON_COPYABLE(
Signal);
153 typedef std::function<void (Args...)> CbFunction;
168 assert (ref_count > 0);
176 assert (ref_count > 0);
179 if (cleanup && ref_count == 1)
181 connections.remove_if ([](Connection& conn) ->
bool
186 else if (ref_count == 0)
190 std::list<Connection> connections;
195 connect_impl (
SignalReceiver *receiver,
const CbFunction& callback)
197 assert (signal_data);
199 Data *data = signal_data->ref();
200 uint64
id = next_signal_id();
201 data->connections.push_back ({callback, id, receiver});
207 disconnect_impl (uint64
id)
override
209 assert (signal_data);
211 Data *data = signal_data->ref();
212 for (
auto& conn : data->connections)
220 operator()(Args... args)
222 assert (signal_data);
224 Data *data = signal_data->ref();
226 for (
auto& conn : data->connections)
235 signal_data (
new Data())
240 assert (signal_data);
242 for (
auto& conn : signal_data->connections)
246 conn.receiver->dead_signal (conn.id);
251 signal_data->unref (
false);
252 signal_data =
nullptr;
Definition: smsignal.hh:35
Definition: smsignal.hh:150
Definition: smsignal.hh:19