15 #ifndef EMP_CONTROL_SIGNAL 16 #define EMP_CONTROL_SIGNAL 21 #include "../meta/TypePack.h" 22 #include "../tools/FunctionSet.h" 23 #include "../tools/map_utils.h" 37 if (signal_id < in.signal_id)
return -1;
38 if (signal_id > in.signal_id)
return 1;
39 if (key_id < in.key_id)
return -1;
40 if (key_id > in.key_id)
return 1;
44 SignalKey(uint32_t _kid=0, uint32_t _sid=0) : signal_id(_sid), key_id(_kid) { ; }
61 uint32_t
GetID()
const {
return key_id; }
70 void Set(uint32_t _kid=0, uint32_t _sid=0) { signal_id = _sid; key_id = _kid; }
73 void Clear() { signal_id = 0; key_id = 0; }
75 operator bool() {
return key_id > 0; }
85 virtual void NotifyConstruct(
SignalBase * sig_ptr) = 0;
86 virtual void NotifyDestruct(
SignalBase * sig_ptr) = 0;
91 virtual void NotifyConstruct(
SignalBase * sig_ptr) = 0;
114 : name(n), signal_id(0), next_link_id(0), link_key_map(), managers(), prime_manager(nullptr)
126 for (
auto * m : managers)
if (m != prime_manager) m->NotifyDestruct(
this);
130 const std::string &
GetName()
const {
return name; }
131 virtual size_t GetNumArgs()
const = 0;
132 virtual size_t GetNumActions()
const = 0;
136 template <
typename... ARGS>
137 void BaseTrigger(ARGS... args);
140 template <
typename... ARGS>
141 SignalKey AddAction(
const std::function<
void(ARGS...)> & in_fun);
152 while (link_key_map.size()) Remove(link_key_map.begin()->first);
159 template <
typename... ARGS>
class Signal;
162 template <
typename... ARGS>
173 :
this_t(name, &(control.GetSignalManager())) { ; }
184 void Trigger(ARGS... args) { actions.Run(args...); }
188 const SignalKey link_id = NextSignalKey();
189 link_key_map[link_id] = actions.size();
197 emp_assert( a !=
nullptr &&
"action type must match signal type." );
198 return AddAction(a->GetFun());
202 template <
typename... FUN_ARGS,
typename... EXTRA_ARGS>
207 const SignalKey link_id = NextSignalKey();
208 link_key_map[link_id] = actions.size();
209 std::function<void(ARGS...)> expand_fun =
210 [in_fun](FUN_ARGS &&... args, EXTRA_ARGS...){ in_fun(std::forward<FUN_ARGS>(args)...); };
211 actions.Add(expand_fun);
217 template <
typename... FUN_ARGS>
220 using extra_type =
typename TypePack<ARGS...>::template popN<
sizeof...(FUN_ARGS)>;
221 return AddAction(in_fun, extra_type());
226 template <
typename... FUN_ARGS>
229 using extra_type =
typename TypePack<ARGS...>::template popN<
sizeof...(FUN_ARGS)>;
230 return AddAction(std::function<
void(FUN_ARGS...)>(in_fun), extra_type());
237 size_t pos = link_key_map[key];
241 link_key_map.erase(key);
244 for (
auto & x : link_key_map) {
245 if (x.second > pos) x.second = x.second - 1;
252 return link_key_map[key];
258 template <
typename RETURN,
typename... ARGS>
269 :
this_t(name, &(control.GetSignalManager())) { ; }
283 const SignalKey link_id = NextSignalKey();
284 link_key_map[link_id] = actions.size();
291 emp_assert( a !=
nullptr &&
"action type must match signal type." );
292 return AddAction(a->GetFun());
296 template <
typename... FUN_ARGS,
typename... EXTRA_ARGS>
301 const SignalKey link_id = NextSignalKey();
302 link_key_map[link_id] = actions.size();
303 std::function<fun_t> expand_fun =
304 [in_fun](FUN_ARGS &&... args, EXTRA_ARGS...){ in_fun(std::forward<FUN_ARGS>(args)...); };
305 actions.Add(expand_fun);
311 template <
typename... FUN_ARGS>
314 using extra_type =
typename TypePack<ARGS...>::template popN<
sizeof...(FUN_ARGS)>;
315 return AddAction(in_fun, extra_type());
320 template <
typename... FUN_ARGS>
323 using extra_type =
typename TypePack<ARGS...>::template popN<
sizeof...(FUN_ARGS)>;
324 return AddAction(std::function<RETURN(FUN_ARGS...)>(in_fun), extra_type());
330 size_t pos = link_key_map[key];
334 link_key_map.erase(key);
337 for (
auto & x : link_key_map) {
338 if (x.second > pos) x.second = x.second - 1;
344 return link_key_map[key];
349 template<
typename... ARGS>
354 ((
Signal<void(ARGS...)> *)
this)->Trigger(args...);
357 template <
typename... ARGS>
361 return ((
Signal<
void(ARGS...)> *)
this)->AddAction(in_fun);
const std::string & GetName() const
Definition: Signal.h:130
SignalKey tracks a specific function triggered by a signal. For now, its just a value pair...
Definition: Signal.h:30
SignalKey & operator=(const SignalKey &)=default
uint32_t signal_id
What is the unique ID of this signal?
Definition: Signal.h:103
virtual this_t * Clone() const
Definition: Signal.h:270
Signal(const std::string &name="", internal::SignalManager_Base *manager=nullptr)
Definition: Signal.h:170
SignalKey AddAction(const std::function< void(ARGS...)> &in_fun)
Add an action that takes the proper arguments.
Definition: Signal.h:187
SignalKey AddAction(ActionBase &in_action)
Add an action using an Action object.
Definition: Signal.h:289
bool IsActive() const
Is this key currently pointing to a signal action?
Definition: Signal.h:67
SignalKey NextSignalKey()
Definition: Signal.h:110
Base class for all signals.
Definition: Signal.h:97
bool operator!=(const SignalKey &in) const
Are two signal keys different?
Definition: Signal.h:53
virtual void NotifyConstruct(SignalBase *sig_ptr)=0
bool operator<(const SignalKey &in) const
Definition: Signal.h:55
size_t GetNumActions() const
Definition: Signal.h:181
size_t GetNumArgs() const
Definition: Signal.h:180
A mechanism to abstract functions from their underlying type and provide run-time names...
void Trigger(ARGS...args)
Trigger this signal, providing all needed arguments.
Definition: Signal.h:184
uint32_t GetID() const
What is the KeyID associated with this signal key.
Definition: Signal.h:61
SignalKey AddAction(const std::function< fun_t > &in_fun)
Definition: Signal.h:282
void Remove(SignalKey key)
Remove an action from this signal by providing its key.
Definition: Signal.h:234
virtual ~SignalControl_Base()
Definition: Signal.h:92
size_t GetNumActions() const
Definition: Signal.h:277
std::map< SignalKey, size_t > link_key_map
Map unique link keys to link index for actions.
Definition: Signal.h:105
std::string name
What is the unique name of this signal?
Definition: Signal.h:102
RETURN(ARGS...) fun_t
Definition: Signal.h:263
SignalKey AddAction(RETURN in_fun(FUN_ARGS...))
Definition: Signal.h:321
size_t GetPriority(SignalKey key)
Retrieve the relative priority associated with a specific.
Definition: Signal.h:250
~SignalKey()
Definition: Signal.h:47
virtual ~SignalBase()
Definition: Signal.h:124
void Clear()
Remove all actions from this signal.
Definition: Signal.h:150
virtual ~SignalManager_Base()
Definition: Signal.h:87
SignalBase(const std::string &n, internal::SignalManager_Base *manager=nullptr)
Definition: Signal.h:113
void(ARGS...) fun_t
Definition: Signal.h:167
const emp::vector< RETURN > & Trigger(ARGS...args)
Definition: Signal.h:279
Generic version of Signals; needs specialization to a function type..
Definition: Signal.h:159
Definition: SignalManager.h:21
FunctionSet< void(ARGS...)> actions
Set of functions (actions) to be triggered with this signal.
Definition: Signal.h:165
bool operator==(const SignalKey &in) const
Are two signal keys identical?
Definition: Signal.h:50
void BaseTrigger(ARGS...args)
Definition: Signal.h:350
bool operator<=(const SignalKey &in) const
Definition: Signal.h:57
SignalKey(uint32_t _kid=0, uint32_t _sid=0)
Definition: Signal.h:44
SignalKey AddAction(const std::function< RETURN(FUN_ARGS...)> &in_fun, TypePack< EXTRA_ARGS... >)
Definition: Signal.h:297
void Remove(SignalKey key)
Remove an action specified by its key.
Definition: Signal.h:327
size_t GetNumArgs() const
Definition: Signal.h:276
void Set(uint32_t _kid=0, uint32_t _sid=0)
Set this key to specified values.
Definition: Signal.h:70
bool Has(const MAP_T &in_map, const KEY_T &key)
Take any map type, and run find to determine if a key is present.
Definition: map_utils.h:21
Signal(const std::string &name="", internal::SignalManager_Base *manager=nullptr)
Definition: Signal.h:266
SignalKey AddAction(const std::function< void(FUN_ARGS...)> &in_fun)
Definition: Signal.h:218
emp::vector< man_t * > managers
What manager is handling this signal?
Definition: Signal.h:106
void Clear()
Clear this key.
Definition: Signal.h:73
uint32_t GetSignalID() const
What is the ID of the signal that this key is associated with.
Definition: Signal.h:64
size_t GetPriority(SignalKey key)
Definition: Signal.h:342
SignalKey AddAction(ActionBase &in_action)
Add a specified action to this signal.
Definition: Signal.h:195
If we are in emscripten, make sure to include the header.
Definition: array.h:37
SignalKey AddAction(const std::function< void(FUN_ARGS...)> &in_fun, TypePack< EXTRA_ARGS... >)
Add an action that takes too few arguments... but provide specific padding info.
Definition: Signal.h:203
virtual this_t * Clone() const
Definition: Signal.h:174
Definition: FunctionSet.h:19
Build a debug wrapper emp::vector around std::vector.
Definition: vector.h:42
#define emp_assert(...)
Definition: assert.h:199
Signal(const std::string &name, internal::SignalControl_Base &control)
Definition: Signal.h:268
SignalKey AddAction(void in_fun(FUN_ARGS...))
Definition: Signal.h:227
bool Has(SignalKey key) const
Definition: Signal.h:155
bool operator>(const SignalKey &in) const
Definition: Signal.h:56
uint32_t next_link_id
What ID shouild the next link have?
Definition: Signal.h:104
FunctionSet< RETURN(ARGS...)> actions
Definition: Signal.h:261
Signal(const std::string &name, internal::SignalControl_Base &control)
Definition: Signal.h:172
SignalKey AddAction(const std::function< RETURN(FUN_ARGS...)> &in_fun)
Definition: Signal.h:312
man_t * prime_manager
Which manager leads deletion? (nullptr for self)
Definition: Signal.h:107
Definition: TypePack.h:71
SignalKey AddAction(const std::function< void(ARGS...)> &in_fun)
Actions without arguments or a return type can be associated with any signal.
Definition: Signal.h:358
bool operator>=(const SignalKey &in) const
Definition: Signal.h:58