- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

gslot.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2013 Graeme Walker <graeme_walker@users.sourceforge.net>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
20
21 #ifndef G_SLOT_H
22 #define G_SLOT_H
23
24 #include "gdef.h"
25 #include "gexception.h"
26 #include "gnoncopyable.h"
27
29 namespace G
30 {
31
38 class SlotBase
39 {
40 public:
41 SlotBase() ;
43
44 virtual ~SlotBase() ;
46
47 void up() ;
49
50 void down() ;
53
54 private:
55 SlotBase( const SlotBase & ) ; // not implemented
56 void operator=( const SlotBase & ) ; // not implemented
57
58 private:
59 unsigned long m_ref_count ;
60 } ;
61
66 class SignalImp
67 {
68 public:
69 G_EXCEPTION( AlreadyConnected , "signal already connected to a slot" ) ;
70 static void check( const SlotBase * p ) ;
71 private:
72 SignalImp() ; // not implemented
73 } ;
74
79 template <typename T>
80 void swap_( T & t1 , T & t2 )
81 {
82 T temp( t1 ) ;
83 t1 = t2 ;
84 t2 = temp ;
85 }
86
88
94 template <typename T>
95 class SlotImp0 : public SlotBase
96 {
97 private:
98 T & m_object ;
99 void (T::*m_fn)() ;
100 public:
101 SlotImp0( T & object , void (T::*fn)() ) : m_object(object) , m_fn(fn) {}
102 void callback() { (m_object.*m_fn)() ; }
103 } ;
104
108 template <typename T>
109 class SlotOp0
110 {
111 public:
112 static void callback( SlotBase * imp )
113 { static_cast<SlotImp0<T>*>(imp)->callback() ; }
114 } ;
115
119 class Slot0
120 {
121 private:
122 SlotBase * m_imp ;
123 void (*m_op)( SlotBase * ) ;
124 public:
125 Slot0() : m_imp(0) , m_op(0) {}
126 Slot0( SlotBase * imp , void (*op)(SlotBase*) ) : m_imp(imp) , m_op(op) {}
127 ~Slot0() { if(m_imp) m_imp->down() ; }
128 void callback() { if( m_imp ) (*m_op)( m_imp ) ; }
129 Slot0( const Slot0 & other ) : m_imp(other.m_imp) , m_op(other.m_op) { if(m_imp) m_imp->up() ; }
130 void swap( Slot0 & rhs ) { swap_(m_imp,rhs.m_imp) ; swap_(m_op,rhs.m_op) ; }
131 void operator=( const Slot0 & rhs ) { Slot0 tmp(rhs) ; swap(tmp) ; }
132 const SlotBase * base() const { return m_imp ; }
133 } ;
134
138 class Signal0 : public noncopyable
139 {
140 private:
141 bool m_emitted ;
142 bool m_once ;
143 Slot0 m_slot ;
144 public:
145 explicit Signal0( bool once = false ) : m_emitted(false) , m_once(once) {}
146 void emit() { if(!m_once||!m_emitted) { m_emitted = true ; m_slot.callback() ; } }
147 void connect( Slot0 slot ) { SignalImp::check(m_slot.base()) ; m_slot = slot ; }
148 void disconnect() { m_slot = Slot0() ; }
149 void reset() { m_emitted = false ; }
150 } ;
151
155 template <typename T>
156 Slot0 slot( T & object , void (T::*fn)() )
157 {
158 return Slot0( new SlotImp0<T>(object,fn) , SlotOp0<T>::callback ) ;
159 }
160
162
166 template <typename T, typename P>
167 class SlotImp1 : public SlotBase
168 {
169 private:
170 T & m_object ;
171 void (T::*m_fn)( P ) ;
172 public:
173 SlotImp1( T & object , void (T::*fn)(P) ) : m_object(object) , m_fn(fn) {}
174 void callback( P p ) { (m_object.*m_fn)(p) ; }
175 } ;
176
180 template <typename T, typename P>
181 class SlotOp1
182 {
183 public:
184 static void callback( SlotBase * imp , P p )
185 { static_cast<SlotImp1<T,P>*>(imp)->callback( p ) ; }
186 } ;
187
191 template <typename P>
192 class Slot1
193 {
194 private:
195 SlotBase * m_imp ;
196 void (*m_op)( SlotBase * , P ) ;
197 public:
198 Slot1() : m_imp(0) , m_op(0) {}
199 Slot1( SlotBase * imp , void (*op)(SlotBase*,P) ) : m_imp(imp) , m_op(op) {}
200 ~Slot1() { if( m_imp ) m_imp->down() ; }
201 void callback( P p ) { if( m_imp ) (*m_op)( m_imp , p ) ; }
202 Slot1( const Slot1<P> & other ) : m_imp(other.m_imp) , m_op(other.m_op) { if(m_imp) m_imp->up() ; }
203 void swap( Slot1<P> & rhs ) { swap_(m_imp,rhs.m_imp) ; swap_(m_op,rhs.m_op) ; }
204 void operator=( const Slot1<P> & rhs ) { Slot1 tmp(rhs) ; swap(tmp) ; }
205 const SlotBase * base() const { return m_imp ; }
206 } ;
207
211 template <typename P>
212 class Signal1 : public noncopyable
213 {
214 private:
215 bool m_emitted ;
216 bool m_once ;
217 Slot1<P> m_slot ;
218 public:
219 explicit Signal1( bool once = false ) : m_emitted(false) , m_once(once) {}
220 void emit( P p ) { if(!m_once||!m_emitted) { m_emitted = true ; m_slot.callback( p ) ; } }
221 void connect( Slot1<P> slot ) { SignalImp::check(m_slot.base()) ; m_slot = slot ; }
222 void disconnect() { m_slot = Slot1<P>() ; }
223 void reset() { m_emitted = false ; }
224 } ;
225
229 template <typename T,typename P>
230 Slot1<P> slot( T & object , void (T::*fn)(P) )
231 {
232 return Slot1<P>( new SlotImp1<T,P>(object,fn) , SlotOp1<T,P>::callback ) ;
233 }
234
236
240 template <typename T, typename P1, typename P2>
241 class SlotImp2 : public SlotBase
242 {
243 private:
244 T & m_object ;
245 void (T::*m_fn)( P1 , P2 ) ;
246 public:
247 SlotImp2( T & object , void (T::*fn)(P1,P2) ) : m_object(object) , m_fn(fn) {}
248 void callback( P1 p1 , P2 p2 ) { (m_object.*m_fn)(p1,p2) ; }
249 } ;
250
254 template <typename T, typename P1 , typename P2>
255 class SlotOp2
256 {
257 public:
258 static void callback( SlotBase * imp , P1 p1 , P2 p2 )
259 { static_cast<SlotImp2<T,P1,P2>*>(imp)->callback( p1 , p2 ) ; }
260 } ;
261
265 template <typename P1, typename P2>
266 class Slot2
267 {
268 private:
269 SlotBase * m_imp ;
270 void (*m_op)( SlotBase * , P1 , P2 ) ;
271 public:
272 Slot2() : m_imp(0) , m_op(0) {}
273 Slot2( SlotBase * imp , void (*op)(SlotBase*,P1,P2) ) : m_imp(imp) , m_op(op) {}
274 ~Slot2() { if( m_imp ) m_imp->down() ; }
275 void callback( P1 p1 , P2 p2 ) { if( m_imp ) (*m_op)( m_imp , p1 , p2 ) ; }
276 Slot2( const Slot2<P1,P2> & other ) : m_imp(other.m_imp) , m_op(other.m_op) { if(m_imp) m_imp->up() ; }
277 void swap( Slot2<P1,P2> & rhs ) { swap_(m_imp,rhs.m_imp) ; swap_(m_op,rhs.m_op) ; }
278 void operator=( const Slot2<P1,P2> & rhs ) { Slot2 tmp(rhs) ; swap(tmp) ; }
279 const SlotBase * base() const { return m_imp ; }
280 } ;
281
285 template <typename P1, typename P2>
286 class Signal2 : public noncopyable
287 {
288 private:
289 bool m_emitted ;
290 bool m_once ;
291 Slot2<P1,P2> m_slot ;
292 public:
293 explicit Signal2( bool once = false ) : m_emitted(false) , m_once(once) {}
294 void emit( P1 p1 , P2 p2 ) { if(!m_once||!m_emitted) { m_emitted = true ; m_slot.callback( p1 , p2 ) ; } }
295 void connect( Slot2<P1,P2> slot ) { SignalImp::check(m_slot.base()) ; m_slot = slot ; }
296 void disconnect() { m_slot = Slot2<P1,P2>() ; }
297 void reset() { m_emitted = false ; }
298 } ;
299
303 template <typename T, typename P1, typename P2>
304 Slot2<P1,P2> slot( T & object , void (T::*fn)(P1,P2) )
305 {
306 return Slot2<P1,P2>( new SlotImp2<T,P1,P2>(object,fn) , SlotOp2<T,P1,P2>::callback ) ;
307 }
308
310
314 template <typename T, typename P1, typename P2, typename P3>
315 class SlotImp3 : public SlotBase
316 {
317 private:
318 T & m_object ;
319 void (T::*m_fn)( P1 , P2 , P3 ) ;
320 public:
321 SlotImp3( T & object , void (T::*fn)(P1,P2,P3) ) : m_object(object) , m_fn(fn) {}
322 void callback( P1 p1 , P2 p2 , P3 p3 ) { (m_object.*m_fn)(p1,p2,p3) ; }
323 } ;
324
328 template <typename T, typename P1 , typename P2, typename P3>
329 class SlotOp3
330 {
331 public:
332 static void callback( SlotBase * imp , P1 p1 , P2 p2 , P3 p3 )
333 { static_cast<SlotImp3<T,P1,P2,P3>*>(imp)->callback( p1 , p2 , p3 ) ; }
334 } ;
335
339 template <typename P1, typename P2, typename P3>
340 class Slot3
341 {
342 private:
343 SlotBase * m_imp ;
344 void (*m_op)( SlotBase * , P1 , P2 , P3 ) ;
345 public:
346 Slot3() : m_imp(0) , m_op(0) {}
347 Slot3( SlotBase * imp , void (*op)(SlotBase*,P1,P2,P3) ) : m_imp(imp) , m_op(op) {}
348 ~Slot3() { if( m_imp ) m_imp->down() ; }
349 void callback( P1 p1 , P2 p2 , P3 p3 ) { if( m_imp ) (*m_op)( m_imp , p1 , p2 , p3 ) ; }
350 Slot3( const Slot3<P1,P2,P3> & other ) : m_imp(other.m_imp) , m_op(other.m_op) { if(m_imp) m_imp->up() ; }
351 void swap( Slot3<P1,P2,P3> & rhs ) { swap_(m_imp,rhs.m_imp) ; swap_(m_op,rhs.m_op) ; }
352 void operator=( const Slot3<P1,P2,P3> & rhs ) { Slot3 tmp(rhs) ; swap(tmp) ; }
353 const SlotBase * base() const { return m_imp ; }
354 } ;
355
359 template <typename P1, typename P2, typename P3>
360 class Signal3 : public noncopyable
361 {
362 private:
363 bool m_emitted ;
364 bool m_once ;
365 Slot3<P1,P2,P3> m_slot ;
366 public:
367 explicit Signal3( bool once = false ) : m_emitted(false) , m_once(once) {}
368 void emit( P1 p1 , P2 p2 , P3 p3 ) { if(!m_once||!m_emitted) { m_emitted = true ; m_slot.callback( p1 , p2 , p3 ) ; }}
369 void connect( Slot3<P1,P2,P3> slot ) { SignalImp::check(m_slot.base()) ; m_slot = slot ; }
370 void disconnect() { m_slot = Slot3<P1,P2,P3>() ; }
371 void reset() { m_emitted = false ; }
372 } ;
373
377 template <typename T, typename P1, typename P2, typename P3>
378 Slot3<P1,P2,P3> slot( T & object , void (T::*fn)(P1,P2,P3) )
379 {
380 return Slot3<P1,P2,P3>( new SlotImp3<T,P1,P2,P3>(object,fn) , SlotOp3<T,P1,P2,P3>::callback ) ;
381 }
382
383 }
384
385 #endif
386
G::Slot1::Slot1
Slot1(const Slot1< P > &other)
Definition: gslot.h:202
G::Signal0::connect
void connect(Slot0 slot)
Definition: gslot.h:147
G::Slot1::base
const SlotBase * base() const
Definition: gslot.h:205
G::SlotImp2::SlotImp2
SlotImp2(T &object, void(T::*fn)(P1, P2))
Definition: gslot.h:247
G::noncopyable
A noncopyable base class (a la boost).
Definition: gnoncopyable.h:35
G::Signal1::connect
void connect(Slot1< P > slot)
Definition: gslot.h:221
G::Slot1::~Slot1
~Slot1()
Definition: gslot.h:200
G::Signal2
Part of the slot/signal system.
Definition: gslot.h:286
G::Slot2
Part of the slot/signal system.
Definition: gslot.h:266
G::SlotOp2
Part of the slot/signal system.
Definition: gslot.h:255
G::SlotImp3::SlotImp3
SlotImp3(T &object, void(T::*fn)(P1, P2, P3))
Definition: gslot.h:321
G::Slot1::Slot1
Slot1(SlotBase *imp, void(*op)(SlotBase *, P))
Definition: gslot.h:199
G::Slot0::base
const SlotBase * base() const
Definition: gslot.h:132
G::Slot3::base
const SlotBase * base() const
Definition: gslot.h:353
G::SlotImp3
Part of the slot/signal system.
Definition: gslot.h:315
G::Slot1::swap
void swap(Slot1< P > &rhs)
Definition: gslot.h:203
G::Signal0::disconnect
void disconnect()
Definition: gslot.h:148
G::Slot2::Slot2
Slot2()
Definition: gslot.h:272
G::SlotBase
Part of the slot/signal system.
Definition: gslot.h:38
G::Signal3::connect
void connect(Slot3< P1, P2, P3 > slot)
Definition: gslot.h:369
G::Slot3::swap
void swap(Slot3< P1, P2, P3 > &rhs)
Definition: gslot.h:351
G::Signal2::Signal2
Signal2(bool once=false)
Definition: gslot.h:293
G::Signal2::disconnect
void disconnect()
Definition: gslot.h:296
G::slot
Slot0 slot(T &object, void(T::*fn)())
Part of the slot/signal system.
Definition: gslot.h:156
G::SlotImp0::SlotImp0
SlotImp0(T &object, void(T::*fn)())
Definition: gslot.h:101
G::Signal1
Part of the slot/signal system.
Definition: gslot.h:212
G::Signal0::reset
void reset()
Definition: gslot.h:149
G::Slot1
Part of the slot/signal system.
Definition: gslot.h:192
G::Slot1::Slot1
Slot1()
Definition: gslot.h:198
G::SlotOp3
Part of the slot/signal system.
Definition: gslot.h:329
G::Signal2::emit
void emit(P1 p1, P2 p2)
Definition: gslot.h:294
G::SlotOp1::callback
static void callback(SlotBase *imp, P p)
Definition: gslot.h:184
G::Slot0::Slot0
Slot0(const Slot0 &other)
Definition: gslot.h:129
G::Signal1::emit
void emit(P p)
Definition: gslot.h:220
G::SlotImp0
Part of the slot/signal system.
Definition: gslot.h:95
G::Slot3::operator=
void operator=(const Slot3< P1, P2, P3 > &rhs)
Definition: gslot.h:352
G::SlotImp2::callback
void callback(P1 p1, P2 p2)
Definition: gslot.h:248
G::Signal1::Signal1
Signal1(bool once=false)
Definition: gslot.h:219
G::SignalImp::check
static void check(const SlotBase *p)
Definition: gslot.cpp:46
G::Slot0::callback
void callback()
Definition: gslot.h:128
G::Slot0::swap
void swap(Slot0 &rhs)
Definition: gslot.h:130
G::SlotImp1::callback
void callback(P p)
Definition: gslot.h:174
G::Slot0::~Slot0
~Slot0()
Definition: gslot.h:127
G::SlotOp2::callback
static void callback(SlotBase *imp, P1 p1, P2 p2)
Definition: gslot.h:258
G::Slot3::~Slot3
~Slot3()
Definition: gslot.h:348
G::Slot3
Part of the slot/signal system.
Definition: gslot.h:340
G::SlotBase::SlotBase
SlotBase()
Default constuctor.
Definition: gslot.cpp:28
G::Slot2::~Slot2
~Slot2()
Definition: gslot.h:274
G
Low-level classes.
G::Signal2::reset
void reset()
Definition: gslot.h:297
G::Slot3::Slot3
Slot3(SlotBase *imp, void(*op)(SlotBase *, P1, P2, P3))
Definition: gslot.h:347
G::Slot0::operator=
void operator=(const Slot0 &rhs)
Definition: gslot.h:131
G::Slot2::Slot2
Slot2(SlotBase *imp, void(*op)(SlotBase *, P1, P2))
Definition: gslot.h:273
G::Slot2::base
const SlotBase * base() const
Definition: gslot.h:279
G::SlotOp0::callback
static void callback(SlotBase *imp)
Definition: gslot.h:112
G::swap_
void swap_(T &t1, T &t2)
Part of the slot/signal system.
Definition: gslot.h:80
G::Slot1::callback
void callback(P p)
Definition: gslot.h:201
G::SlotImp0::callback
void callback()
Definition: gslot.h:102
G::Slot0::Slot0
Slot0(SlotBase *imp, void(*op)(SlotBase *))
Definition: gslot.h:126
G::Slot3::callback
void callback(P1 p1, P2 p2, P3 p3)
Definition: gslot.h:349
G::Signal0
Part of the slot/signal system.
Definition: gslot.h:138
G::SlotImp3::callback
void callback(P1 p1, P2 p2, P3 p3)
Definition: gslot.h:322
G::Slot0
Part of the slot/signal system.
Definition: gslot.h:119
G::SlotOp0
Part of the slot/signal system.
Definition: gslot.h:109
G::Signal0::emit
void emit()
Definition: gslot.h:146
G::Slot3::Slot3
Slot3()
Definition: gslot.h:346
G::Slot2::Slot2
Slot2(const Slot2< P1, P2 > &other)
Definition: gslot.h:276
G::Slot2::operator=
void operator=(const Slot2< P1, P2 > &rhs)
Definition: gslot.h:278
gexception.h
G::Signal3
Part of the slot/signal system.
Definition: gslot.h:360
G::Signal3::reset
void reset()
Definition: gslot.h:371
G::Signal3::emit
void emit(P1 p1, P2 p2, P3 p3)
Definition: gslot.h:368
gnoncopyable.h
G_EXCEPTION
#define G_EXCEPTION(class_name, description)
define as a function rather than a type if optimising for size
Definition: gexception.h:93
G::Signal3::disconnect
void disconnect()
Definition: gslot.h:370
G::SlotBase::~SlotBase
virtual ~SlotBase()
Destructor.
Definition: gslot.cpp:24
G::Signal1::reset
void reset()
Definition: gslot.h:223
G::SlotBase::down
void down()
Decrements the reference count and does "delete this" on zero.
Definition: gslot.cpp:37
G::Slot1::operator=
void operator=(const Slot1< P > &rhs)
Definition: gslot.h:204
G::Slot2::swap
void swap(Slot2< P1, P2 > &rhs)
Definition: gslot.h:277
G::SlotImp2
Part of the slot/signal system.
Definition: gslot.h:241
G::SlotOp3::callback
static void callback(SlotBase *imp, P1 p1, P2 p2, P3 p3)
Definition: gslot.h:332
G::Slot0::Slot0
Slot0()
Definition: gslot.h:125
G::SlotBase::up
void up()
Increments the reference count.
Definition: gslot.cpp:32
G::Slot3::Slot3
Slot3(const Slot3< P1, P2, P3 > &other)
Definition: gslot.h:350
G::SlotOp1
Part of the slot/signal system.
Definition: gslot.h:181
G::Signal2::connect
void connect(Slot2< P1, P2 > slot)
Definition: gslot.h:295
G::Signal3::Signal3
Signal3(bool once=false)
Definition: gslot.h:367
G::SignalImp
Part of the slot/signal system.
Definition: gslot.h:66
G::Signal1::disconnect
void disconnect()
Definition: gslot.h:222
G::SlotImp1::SlotImp1
SlotImp1(T &object, void(T::*fn)(P))
Definition: gslot.h:173
G::Slot2::callback
void callback(P1 p1, P2 p2)
Definition: gslot.h:275
G::Signal0::Signal0
Signal0(bool once=false)
Definition: gslot.h:145
G::SlotImp1
Part of the slot/signal system.
Definition: gslot.h:167