Empirical
SignalControl.h
Go to the documentation of this file.
1 // This file is part of Empirical, https://github.com/devosoft/Empirical
2 // Copyright (C) Michigan State University, 2016-2017.
3 // Released under the MIT Software license; see doc/LICENSE
4 //
5 //
6 // The SignalControl class manages all of the signals and actions, linking them together
7 // upon request (by name, base class, or derived class).
8 //
9 //
10 // Developer notes:
11 // * Right now SignalControl can only link to signals that it creates. Ideally, external signals
12 // should also be able to be added to it. The question is, how should this be done?
13 // - They could be copied. But should we copy existing actions? How do we provide keys?
14 // - They could use a smart pointer style, so only deleted with final version (slow down?)
15 // - They could reference the originally and automatically clean up if its deleted (confusing?)
16 
17 #ifndef EMP_SIGNAL_CONTROL
18 #define EMP_SIGNAL_CONTROL
19 
20 #include <string>
21 #include <unordered_map>
22 
23 #include "ActionManager.h"
24 #include "SignalManager.h"
25 
26 namespace emp {
27 
29  private:
30  ActionManager action_m;
31  SignalManager signal_m;
32  // uint32_t next_signal_id; // Give each signal a unique id.
33  std::unordered_map<uint32_t, SignalBase *> id_to_signal; // Map signal ID to associated pointer
34 
35  public:
36  SignalControl() : action_m(), signal_m(), id_to_signal() {;} // : next_signal_id(1) { ; }
38 
39  size_t GetNumActions() const { return action_m.GetSize(); }
40  size_t GetNumSignals() const { return signal_m.GetSize(); }
41 
42  const ActionBase & GetAction(const std::string & name) const { return action_m[name]; }
43  const SignalBase & GetSignal(const std::string & name) const { return signal_m[name]; }
44 
45  ActionManager & GetActionManager() { return action_m; }
46  SignalManager & GetSignalManager() override { return signal_m; }
47 
48  template <typename... Ts>
49  auto & AddAction(Ts &&... act) { return action_m.Add( std::forward<Ts>(act)... ); }
50 
51  template <typename... ARGS>
52  auto & AddSignal(const std::string & name="") {
53  return signal_m.Add<ARGS...>(name);
54  }
55 
56  template <typename... ARGS>
57  auto & AddSignal(Signal<void(ARGS...)> & signal) {
58  return signal_m.Add<ARGS...>(signal);
59  }
60 
61  // Link a specified signal to a specified function.
62  template <typename... ARGS>
63  auto Link(SignalBase & s, const std::function<void(ARGS...)> & f) { return s.AddAction(f); }
64 
65  // If a name is passed in for the signal, convert it to a SignalBase.
66  // Pass through anything for actions and return a unique key for the pairing.
67  template <typename A>
68  auto Link(const std::string & s, A && a) { return Link(signal_m[s], std::forward<A>(a)); }
69 
70  // If a name is passed in for the action, convert it to an ActionBase.
71  // (signal names were handled in the previous overload of this function)
72  auto Link(SignalBase & s, const std::string & a) { return s.AddAction(action_m[a]); }
73 
74  // If we have base classes for both signals and actions. Convert to derrived versions!
75  auto Link(SignalBase & s, ActionBase & a) { return s.AddAction(a); }
76 
77 
78  template <typename... ARGS>
79  void Trigger(const std::string & name, ARGS &&... args) {
80  auto & base_signal = signal_m[name];
81  auto * signal = dynamic_cast< Signal<void(ARGS...)>* >(&base_signal);
82  emp_assert( signal != nullptr && "invalid signal conversion!" );
83  signal->Trigger(std::forward<ARGS>(args)...);
84  }
85 
86 
87  void NotifyConstruct(SignalBase * sig_ptr) override { signal_m.NotifyConstruct(sig_ptr); }
88 
89 
90  void PrintNames(std::ostream & os=std::cout) {
91  action_m.PrintNames(os);
92  signal_m.PrintNames(os);
93  }
94  };
95 
96 }
97 
98 #endif
SignalManager & GetSignalManager() override
Definition: SignalControl.h:46
Definition: Action.h:28
Base class for all signals.
Definition: Signal.h:97
void NotifyConstruct(SignalBase *sig_ptr) override
Definition: SignalControl.h:87
auto & AddSignal(Signal< void(ARGS...)> &signal)
Definition: SignalControl.h:57
auto & AddSignal(const std::string &name="")
Definition: SignalControl.h:52
size_t GetNumActions() const
Definition: SignalControl.h:39
SignalControl()
Definition: SignalControl.h:36
size_t GetSize() const
Definition: SignalManager.h:44
void Trigger(const std::string &name, ARGS &&...args)
Definition: SignalControl.h:79
const ActionBase & GetAction(const std::string &name) const
Definition: SignalControl.h:42
Generic version of Signals; needs specialization to a function type..
Definition: Signal.h:159
Definition: SignalManager.h:21
auto & Add(const std::string &name)
Definition: SignalManager.h:58
auto Link(const std::string &s, A &&a)
Definition: SignalControl.h:68
void PrintNames(std::ostream &os=std::cout)
Definition: SignalControl.h:90
const SignalBase & GetSignal(const std::string &name) const
Definition: SignalControl.h:43
void PrintNames(std::ostream &os=std::cout)
Definition: SignalManager.h:87
auto & Add(const std::function< RETURN(ARGS...)> &in_fun, const std::string &name)
Add a functon to this manager with a pre-specified name.
Definition: ActionManager.h:61
ActionManager & GetActionManager()
Definition: SignalControl.h:45
auto Link(SignalBase &s, ActionBase &a)
Definition: SignalControl.h:75
size_t GetSize() const
How many actions are in this manager?
Definition: ActionManager.h:44
void NotifyConstruct(SignalBase *signal) override
Definition: SignalManager.h:75
If we are in emscripten, make sure to include the header.
Definition: array.h:37
Definition: Signal.h:89
auto & AddAction(Ts &&...act)
Definition: SignalControl.h:49
~SignalControl()
Definition: SignalControl.h:37
#define emp_assert(...)
Definition: assert.h:199
void PrintNames(std::ostream &os=std::cout)
Print out the name of all actions maintained by this manager.
Definition: ActionManager.h:84
Definition: SignalControl.h:28
Definition: ActionManager.h:23
auto Link(SignalBase &s, const std::function< void(ARGS...)> &f)
Definition: SignalControl.h:63
auto Link(SignalBase &s, const std::string &a)
Definition: SignalControl.h:72
size_t GetNumSignals() const
Definition: SignalControl.h:40
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