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 typedef std::function<void (Args...)> CbFunction;
166 assert (ref_count > 0);
174 assert (ref_count > 0);
177 if (cleanup && ref_count == 1)
179 connections.remove_if ([](Connection& conn) ->
bool 184 else if (ref_count == 0)
188 std::list<Connection> connections;
193 connect_impl (
SignalReceiver *receiver,
const CbFunction& callback)
195 assert (signal_data);
197 Data *data = signal_data->ref();
198 uint64
id = next_signal_id();
199 data->connections.push_back ({callback, id, receiver});
205 disconnect_impl (uint64
id)
override 207 assert (signal_data);
209 Data *data = signal_data->ref();
210 for (
auto& conn : data->connections)
218 operator()(Args... args)
220 assert (signal_data);
222 Data *data = signal_data->ref();
224 for (
auto& conn : data->connections)
233 signal_data (
new Data())
238 assert (signal_data);
240 for (
auto& conn : signal_data->connections)
244 conn.receiver->dead_signal (conn.id);
249 signal_data->unref (
false);
250 signal_data =
nullptr;
Definition: smsignal.hh:16
Definition: smadsrenvelope.hh:8
Definition: smsignal.hh:18
Definition: smsignal.hh:34