Midge  v3.9.2
Data Processing Framework
signal.hh
Go to the documentation of this file.
1 /*
2  * m_signal.hh
3  *
4  * Created on: Dec 18, 2018
5  * Adapted by: N.S. Oblath
6  * Original author: Simon Schneegans
7  * License: public domain
8  * URL: http://simmesimme.github.io/tutorials/2015/09/20/m_signal-slot
9  */
10 
11 #ifndef MIDGE_SIGNAL_HH_
12 #define MIDGE_SIGNAL_HH_
13 
14 #include "coremsg.hh"
15 #include "midge_error.hh"
16 #include "types.hh"
17 
18 #include "member_variables.hh"
19 
20 #include <functional>
21 #include <map>
22 
23 namespace midge
24 {
25  class slot;
26 
27  class signal
28  {
29  public:
30  signal( const string_t& p_name );
31  template< typename x_owner >
32  signal( const string_t& p_name, x_owner* p_owner );
33  virtual ~signal();
34 
35  virtual unsigned connect( slot* p_slot ) = 0;
36 
37  mv_referrable( string_t, name );
38  };
39 
46  template< typename... x_args >
47  class m_signal : public signal
48  {
49  public:
50  using signature = void( x_args... );
51 
52  public:
53  m_signal( const string_t& p_name );
54  template< typename x_owner >
55  m_signal( const string_t& p_name, x_owner* p_owner );
56  m_signal( const m_signal& ) = delete;
57  m_signal( m_signal&& ) = delete;
58  virtual ~m_signal();
59 
60  virtual unsigned connect( slot* p_slot );
61 
62  // connects a member function to this Signal
63  template< typename T >
64  unsigned connect_function( T *inst, void (T::*func)( x_args... ) );
65 
66  // connects a const member function to this Signal
67  template< typename T >
68  unsigned connect_function( T *inst, void (T::*func)( x_args... ) const );
69 
70  // connects a std::function to the m_signal. The returned
71  // value can be used to disconnect the function again
72  unsigned connect_function( const std::function< signature > & slot ) const;
73 
74  // disconnects a previously connected function
75  void disconnect( unsigned id ) const;
76 
77  // disconnects all previously connected functions
78  void disconnect_all() const;
79 
80  // calls all connected functions
81  void emit( x_args... args );
82  void operator()( x_args... args );
83 
84  // assignment creates new Signal
85  m_signal& operator=( m_signal const& other );
86 
87  private:
88  typedef std::map< unsigned, std::function< signature > > slot_map; // to get around the problem of having a comma inside a macro function argument
89  mv_referrable_mutable_const( slot_map, slots );
90  mv_accessible_mutable_noset( unsigned, current_id );
91  };
92 
93 
94  template< typename x_owner >
95  signal::signal( const string_t& p_name, x_owner* p_owner ) :
96  f_name( p_name )
97  {
98  if( p_owner ) p_owner->signal_ptr( this, p_name );
99  }
100 
101 
102  template< typename... x_args >
104  signal( name ),
105  f_slots(),
106  f_current_id( 0 )
107  {}
108 
109  template< typename... x_args >
110  template< typename x_owner >
111  m_signal< x_args... >::m_signal( const string_t& name, x_owner* owner ) :
112  signal( name, owner ),
113  f_slots(),
114  f_current_id( 0 )
115  {}
116 
117  template< typename... x_args >
119  {
120  disconnect_all();
121  }
122 
123  // connects a member function to this Signal
124  template< typename... x_args >
125  template< typename T >
126  unsigned m_signal< x_args... >::connect_function( T *inst, void (T::*func)( x_args... ) )
127  {
128  return connect( [=]( x_args... args )
129  {
130  (inst->*func)( args... );
131  });
132  }
133 
134  // connects a const member function to this Signal
135  template< typename... x_args >
136  template< typename T >
137  unsigned m_signal< x_args... >::connect_function( T *inst, void (T::*func)( x_args... ) const )
138  {
139  return connect( [=]( x_args... args )
140  {
141  (inst->*func)( args... );
142  });
143  }
144 
145  // connects a std::function to the m_signal. The returned
146  // value can be used to disconnect the function again
147  template< typename... x_args >
148  unsigned m_signal< x_args... >::connect_function( std::function< signature > const& slot ) const
149  {
150  f_slots.insert( std::make_pair( ++f_current_id, slot ) );
151  return f_current_id;
152  }
153 
154  // disconnects a previously connected function
155  template< typename... x_args >
156  void m_signal< x_args... >::disconnect( unsigned id ) const
157  {
158  f_slots.erase( id );
159  }
160 
161  // disconnects all previously connected functions
162  template< typename... x_args >
164  {
165  f_slots.clear();
166  }
167 
168  // calls all connected functions
169  template< typename... x_args >
170  void m_signal< x_args... >::emit( x_args... args )
171  {
172  for( auto it : f_slots )
173  {
174  it.second( args... );
175  }
176  }
177 
178  template< typename... x_args >
179  void m_signal< x_args... >::operator()( x_args... args )
180  {
181  emit( args... );
182  }
183 
184 }
185 
186 #endif /* MIDGE_SIGNAL_HH_ */
void disconnect_all() const
Definition: signal.hh:163
virtual ~m_signal()
Definition: signal.hh:118
void disconnect(unsigned id) const
Definition: signal.hh:156
Definition: _buffer.hh:11
unsigned connect_function(T *inst, void(T::*func)(x_args...))
Definition: signal.hh:126
void(x_args...) signature
Definition: signal.hh:50
virtual unsigned connect(slot *p_slot)
Definition: signal_slot.hh:24
virtual unsigned connect(slot *p_slot)=0
virtual ~signal()
Definition: signal.cc:17
signal(const string_t &p_name)
Definition: signal.cc:13
m_signal(const string_t &p_name)
Definition: signal.hh:103
std::string string_t
Definition: types.hh:21
void operator()(x_args... args)
Definition: signal.hh:179
void emit(x_args... args)
Definition: signal.hh:170
std::map< unsigned, std::function< signature > > slot_map
Definition: signal.hh:88