So-Bogus
A c++ sparse block matrix library aimed at Second Order cone problems
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
Signal.hpp
1 /*
2  * This file is part of bogus, a C++ sparse block matrix library.
3  *
4  * Copyright 2013 Gilles Daviet <gdaviet@gmail.com>
5  *
6  * This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0. If a copy of the MPL was not distributed with this
8  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 */
10 
11 #ifndef BOGUS_SIGNAL_HPP
12 #define BOGUS_SIGNAL_HPP
13 
14 #include <list>
15 
16 namespace bogus {
17 
18 template < typename Derived >
20 { } ;
21 
22 template< typename Arg1, typename Arg2 = void, typename Arg3 = void >
23 struct Signal ;
24 
26 template< typename Derived >
28 {
30 
31 public:
32  virtual ~SignalBase()
33  {
34  disconnectAll();
35  }
36 
38  void disconnectAll() ;
39 
41 
42  void connect( typename Traits::Function::Type func ) ;
43 
45 
46  template <typename T >
47  void connect( T& object, typename Traits::template Method< T >::Type member_func ) ;
48 
50 
51  void connect( const Derived &other ) ;
52 
53 protected:
54  typedef std::list< typename Traits::Callable* > Callables ;
55  Callables m_callees ;
56 
57 } ;
58 
59 template < typename Arg1, typename Arg2, typename Arg3 >
60 struct SignalTraits< Signal< Arg1, Arg2, Arg3 > >
61 {
62  struct Callable
63  {
64  virtual ~Callable() {}
65  virtual void call( Arg1, Arg2, Arg3 ) = 0 ;
66  } ;
67 
68  struct Function : public Callable
69  {
70  typedef void (*Type)( Arg1, Arg2, Arg3 ) ;
71  Type func ;
72  Function ( Type _func ) : func( _func ) {}
73  virtual void call( Arg1 arg1, Arg2 arg2, Arg3 arg3 ) { func( arg1, arg2, arg3 ) ; }
74  } ;
75  template< typename T >
76  struct Method : public Callable
77  {
78  typedef void (T::*Type)( Arg1, Arg2, Arg3 ) ;
79  T& obj ;
80  Type func ;
81  Method ( T& _obj, Type _func ) : obj( _obj ), func( _func ) {}
82  virtual void call( Arg1 arg1, Arg2 arg2, Arg3 arg3 ) { (obj.*func)( arg1, arg2, arg3 ) ; }
83  } ;
84  struct Proxy : public Callable
85  {
87  const Type& obj ;
88  Proxy( const Type& _obj ) : obj( _obj ) {}
89  virtual void call( Arg1 arg1, Arg2 arg2, Arg3 arg3 ) { obj.trigger( arg1, arg2, arg3 ) ; }
90  };
91 } ;
92 
93 template < typename Arg1, typename Arg2 >
94 struct SignalTraits< Signal< Arg1, Arg2 > >
95 {
96  struct Callable
97  {
98  virtual ~Callable() {}
99  virtual void call( Arg1, Arg2 ) = 0 ;
100  } ;
101 
102  struct Function : public Callable
103  {
104  typedef void (*Type)( Arg1, Arg2 ) ;
105  Type func ;
106  Function ( Type _func ) : func( _func ) {}
107  virtual void call( Arg1 arg1, Arg2 arg2 ) { func( arg1, arg2 ) ; }
108  } ;
109  template< typename T >
110  struct Method : public Callable
111  {
112  typedef void (T::*Type)( Arg1, Arg2 ) ;
113  T& obj ;
114  Type func ;
115  Method ( T& _obj, Type _func ) : obj( _obj ), func( _func ) {}
116  virtual void call( Arg1 arg1, Arg2 arg2 ) { (obj.*func)( arg1, arg2 ) ; }
117  } ;
118  struct Proxy : public Callable
119  {
120  typedef Signal< Arg1, Arg2 > Type ;
121  const Type& obj ;
122  Proxy( const Type& _obj ) : obj( _obj ) {}
123  virtual void call( Arg1 arg1, Arg2 arg2 ) { obj.trigger( arg1, arg2 ) ; }
124  };
125 } ;
126 
127 template< typename Arg >
128 struct SignalTraits< Signal< Arg, void > >
129 {
130  struct Callable
131  {
132  virtual ~Callable() {}
133  virtual void call( Arg ) = 0 ;
134  } ;
135 
136  struct Function : public Callable
137  {
138  typedef void (*Type)( Arg ) ;
139  Type func ;
140  Function ( Type _func ) : func( _func ) {}
141  virtual void call( Arg arg ) { func( arg ) ; }
142  } ;
143  template< typename T >
144  struct Method : public Callable
145  {
146  typedef void (T::*Type)( Arg ) ;
147  T& obj ;
148  Type func ;
149  Method ( T& _obj, Type _func ) : obj( _obj ), func( _func ) {}
150  virtual void call( Arg arg ) { (obj.*func)( arg ) ; }
151  } ;
152  struct Proxy : public Callable
153  {
154  typedef Signal< Arg, void > Type ;
155  const Type& obj ;
156  Proxy( const Type& _obj ) : obj( _obj ) {}
157  virtual void call( Arg arg ) { trigger( arg ) ; }
158  };
159 
160 } ;
161 
163 
170 template< typename Arg1, typename Arg2, typename Arg3 >
171 struct Signal : public SignalBase< Signal< Arg1, Arg2, Arg3 > >
172 {
174  void trigger( Arg1 arg1, Arg2 arg2, Arg3 arg3 ) const
175  {
176  typedef SignalBase< Signal > Base ;
177 
178  for( typename Base::Callables::const_iterator it = this->m_callees.begin() ; it != this->m_callees.end() ; ++it )
179  { (*it)->call( arg1, arg2, arg3 ) ; }
180  }
181 
182 } ;
183 
184 template< typename Arg1, typename Arg2 >
185 struct Signal< Arg1, Arg2, void > : public SignalBase< Signal< Arg1, Arg2 > >
186 {
188  void trigger( Arg1 arg1, Arg2 arg2 ) const
189  {
190  typedef SignalBase< Signal > Base ;
191 
192  for( typename Base::Callables::const_iterator it = this->m_callees.begin() ; it != this->m_callees.end() ; ++it )
193  { (*it)->call( arg1, arg2 ) ; }
194  }
195 
196 } ;
197 
198 template< typename Arg >
199 struct Signal< Arg, void, void > : public SignalBase< Signal< Arg, void > >
200 {
202  void trigger( Arg arg ) const
203  {
204  typedef SignalBase< Signal > Base ;
205 
206  for( typename Base::Callables::const_iterator it = this->m_callees.begin() ; it != this->m_callees.end() ; ++it )
207  { (*it)->call( arg ) ; }
208  }
209 
210 } ;
211 
212 template< typename Derived >
214  for( typename Callables::iterator it = m_callees.begin() ; it != m_callees.end() ; ++it )
215  {
216  delete *it ;
217  }
218  m_callees.clear() ;
219 }
220 
221 template< typename Derived >
222 void SignalBase< Derived >::connect( typename Traits::Function::Type func )
223 {
224  m_callees.push_back( new typename Traits::Function( func ) );
225 }
226 
227 template< typename Derived >
228 template <typename T >
229 void SignalBase< Derived >::connect( T& object, typename Traits::template Method< T >::Type member_func )
230 {
231  m_callees.push_back( new typename Traits::template Method< T >( object, member_func ) );
232 }
233 
234 template< typename Derived >
235 void SignalBase< Derived >::connect( const Derived& other )
236 {
237  m_callees.push_back( new typename Traits::Proxy( other ) );
238 }
239 
240 } // namespace bogus
241 
242 #endif
Base class for Signal of different arities.
Definition: Signal.hpp:27
Definition: Signal.hpp:19
void trigger(Arg arg) const
Triggers the signal.
Definition: Signal.hpp:202
void trigger(Arg1 arg1, Arg2 arg2) const
Triggers the signal.
Definition: Signal.hpp:188
void disconnectAll()
Disconnects all listeners.
Definition: Signal.hpp:213
void trigger(Arg1 arg1, Arg2 arg2, Arg3 arg3) const
Triggers the signal.
Definition: Signal.hpp:174
void connect(typename Traits::Function::Type func)
Connects the signal to a free function.
Definition: Signal.hpp:222
Signal class, to which an arbitrary number of listeners can be connected.
Definition: Signal.hpp:23