aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2009-12-16 21:22:39 +0000
committerMike Buland <eichlan@xagasoft.com>2009-12-16 21:22:39 +0000
commitafac5804b069e5eb76c799e9edd2eaeff0d99b94 (patch)
treed2b3a51f899c7ad1bb828885ff8178613f9ebd63 /src
parentf72c6e4b97afeb69d9ea4d743c0c302d647ea424 (diff)
downloadlibbu++-afac5804b069e5eb76c799e9edd2eaeff0d99b94.tar.gz
libbu++-afac5804b069e5eb76c799e9edd2eaeff0d99b94.tar.bz2
libbu++-afac5804b069e5eb76c799e9edd2eaeff0d99b94.tar.xz
libbu++-afac5804b069e5eb76c799e9edd2eaeff0d99b94.zip
Signals are now not only typesafe, but also will throw an exception if you try
to construct a slot with a null pointer, or call a signal that has not been set yet. Also, signals can be checked for being set, and assigned to one another.
Diffstat (limited to '')
-rw-r--r--src/signals.cpp3
-rw-r--r--src/signals.h75
2 files changed, 78 insertions, 0 deletions
diff --git a/src/signals.cpp b/src/signals.cpp
new file mode 100644
index 0000000..7952053
--- /dev/null
+++ b/src/signals.cpp
@@ -0,0 +1,3 @@
1#include "bu/signals.h"
2
3namespace Bu { subExceptionDef( SignalException ) }
diff --git a/src/signals.h b/src/signals.h
index 722f928..3f892b8 100644
--- a/src/signals.h
+++ b/src/signals.h
@@ -2,9 +2,11 @@
2#define BU_OBJECT_SIGNALS_H 2#define BU_OBJECT_SIGNALS_H
3 3
4#include "bu/util.h" 4#include "bu/util.h"
5#include "bu/exceptionbase.h"
5 6
6namespace Bu 7namespace Bu
7{ 8{
9 subExceptionDecl( SignalException );
8 // 10 //
9 // 0 Parameters 11 // 0 Parameters
10 // 12 //
@@ -31,6 +33,7 @@ namespace Bu
31 33
32 virtual ret operator()() 34 virtual ret operator()()
33 { 35 {
36
34 return (pCls->*pFnc)(); 37 return (pCls->*pFnc)();
35 } 38 }
36 39
@@ -79,9 +82,19 @@ namespace Bu
79 82
80 ret operator()() 83 ret operator()()
81 { 84 {
85 if( !pCb ) throw SignalException("Uninitialized signal used.");
82 return (*pCb)(); 86 return (*pCb)();
83 } 87 }
84 88
89 bool isSet() const { return pCb != NULL; }
90 operator bool() const { return isSet(); }
91
92 Signal0 &operator=( const Signal0 &rhs )
93 {
94 pCb = rhs.pCb->clone();
95 return *this;
96 }
97
85 private: 98 private:
86 _Slot0<ret> *pCb; 99 _Slot0<ret> *pCb;
87 }; 100 };
@@ -89,6 +102,7 @@ namespace Bu
89 template<typename cls, typename ret> 102 template<typename cls, typename ret>
90 Signal0<ret> slot( cls *pCls, ret (cls::*pFnc)() ) 103 Signal0<ret> slot( cls *pCls, ret (cls::*pFnc)() )
91 { 104 {
105 if( !pCls || !pFnc ) throw SignalException("NULL pointer in slot().");
92 return Signal0<ret>( 106 return Signal0<ret>(
93 new __Slot0<cls, ret>( pCls, pFnc ) 107 new __Slot0<cls, ret>( pCls, pFnc )
94 ); 108 );
@@ -97,6 +111,7 @@ namespace Bu
97 template<typename ret> 111 template<typename ret>
98 Signal0<ret> slot( ret (*pFnc)() ) 112 Signal0<ret> slot( ret (*pFnc)() )
99 { 113 {
114 if( !pFnc ) throw SignalException("NULL pointer in slot().");
100 return Signal0<ret>( 115 return Signal0<ret>(
101 new __Slot0F<ret>( pFnc ) 116 new __Slot0F<ret>( pFnc )
102 ); 117 );
@@ -176,9 +191,19 @@ namespace Bu
176 191
177 ret operator()( p1t p1 ) 192 ret operator()( p1t p1 )
178 { 193 {
194 if( !pCb ) throw SignalException("Uninitialized signal used.");
179 return (*pCb)( p1 ); 195 return (*pCb)( p1 );
180 } 196 }
181 197
198 bool isSet() const { return pCb != NULL; }
199 operator bool() const { return isSet(); }
200
201 Signal1 &operator=( const Signal1 &rhs )
202 {
203 pCb = rhs.pCb->clone();
204 return *this;
205 }
206
182 private: 207 private:
183 _Slot1<ret, p1t> *pCb; 208 _Slot1<ret, p1t> *pCb;
184 }; 209 };
@@ -186,6 +211,7 @@ namespace Bu
186 template<typename cls, typename ret, typename p1t> 211 template<typename cls, typename ret, typename p1t>
187 Signal1<ret, p1t> slot( cls *pCls, ret (cls::*pFnc)( p1t ) ) 212 Signal1<ret, p1t> slot( cls *pCls, ret (cls::*pFnc)( p1t ) )
188 { 213 {
214 if( !pCls || !pFnc ) throw SignalException("NULL pointer in slot().");
189 return Signal1<ret, p1t>( 215 return Signal1<ret, p1t>(
190 new __Slot1<cls, ret, p1t>( pCls, pFnc ) 216 new __Slot1<cls, ret, p1t>( pCls, pFnc )
191 ); 217 );
@@ -194,6 +220,7 @@ namespace Bu
194 template<typename ret, typename p1t> 220 template<typename ret, typename p1t>
195 Signal1<ret, p1t> slot( ret (*pFnc)( p1t ) ) 221 Signal1<ret, p1t> slot( ret (*pFnc)( p1t ) )
196 { 222 {
223 if( !pFnc ) throw SignalException("NULL pointer in slot().");
197 return Signal1<ret, p1t>( 224 return Signal1<ret, p1t>(
198 new __Slot1F<ret, p1t>( pFnc ) 225 new __Slot1F<ret, p1t>( pFnc )
199 ); 226 );
@@ -273,9 +300,19 @@ namespace Bu
273 300
274 ret operator()( p1t p1, p2t p2 ) 301 ret operator()( p1t p1, p2t p2 )
275 { 302 {
303 if( !pCb ) throw SignalException("Uninitialized signal used.");
276 return (*pCb)( p1, p2 ); 304 return (*pCb)( p1, p2 );
277 } 305 }
278 306
307 bool isSet() const { return pCb != NULL; }
308 operator bool() const { return isSet(); }
309
310 Signal2 &operator=( const Signal2 &rhs )
311 {
312 pCb = rhs.pCb->clone();
313 return *this;
314 }
315
279 private: 316 private:
280 _Slot2<ret, p1t, p2t> *pCb; 317 _Slot2<ret, p1t, p2t> *pCb;
281 }; 318 };
@@ -283,6 +320,7 @@ namespace Bu
283 template<typename cls, typename ret, typename p1t, typename p2t> 320 template<typename cls, typename ret, typename p1t, typename p2t>
284 Signal2<ret, p1t, p2t> slot( cls *pCls, ret (cls::*pFnc)( p1t, p2t ) ) 321 Signal2<ret, p1t, p2t> slot( cls *pCls, ret (cls::*pFnc)( p1t, p2t ) )
285 { 322 {
323 if( !pCls || !pFnc ) throw SignalException("NULL pointer in slot().");
286 return Signal2<ret, p1t, p2t>( 324 return Signal2<ret, p1t, p2t>(
287 new __Slot2<cls, ret, p1t, p2t>( pCls, pFnc ) 325 new __Slot2<cls, ret, p1t, p2t>( pCls, pFnc )
288 ); 326 );
@@ -291,6 +329,7 @@ namespace Bu
291 template<typename ret, typename p1t, typename p2t> 329 template<typename ret, typename p1t, typename p2t>
292 Signal2<ret, p1t, p2t> slot( ret (*pFnc)( p1t, p2t ) ) 330 Signal2<ret, p1t, p2t> slot( ret (*pFnc)( p1t, p2t ) )
293 { 331 {
332 if( !pFnc ) throw SignalException("NULL pointer in slot().");
294 return Signal2<ret, p1t, p2t>( 333 return Signal2<ret, p1t, p2t>(
295 new __Slot2F<ret, p1t, p2t>( pFnc ) 334 new __Slot2F<ret, p1t, p2t>( pFnc )
296 ); 335 );
@@ -370,9 +409,19 @@ namespace Bu
370 409
371 ret operator()( p1t p1, p2t p2, p3t p3 ) 410 ret operator()( p1t p1, p2t p2, p3t p3 )
372 { 411 {
412 if( !pCb ) throw SignalException("Uninitialized signal used.");
373 return (*pCb)( p1, p2, p3 ); 413 return (*pCb)( p1, p2, p3 );
374 } 414 }
375 415
416 bool isSet() const { return pCb != NULL; }
417 operator bool() const { return isSet(); }
418
419 Signal3 &operator=( const Signal3 &rhs )
420 {
421 pCb = rhs.pCb->clone();
422 return *this;
423 }
424
376 private: 425 private:
377 _Slot3<ret, p1t, p2t, p3t> *pCb; 426 _Slot3<ret, p1t, p2t, p3t> *pCb;
378 }; 427 };
@@ -380,6 +429,7 @@ namespace Bu
380 template<typename cls, typename ret, typename p1t, typename p2t, typename p3t> 429 template<typename cls, typename ret, typename p1t, typename p2t, typename p3t>
381 Signal3<ret, p1t, p2t, p3t> slot( cls *pCls, ret (cls::*pFnc)( p1t, p2t, p3t ) ) 430 Signal3<ret, p1t, p2t, p3t> slot( cls *pCls, ret (cls::*pFnc)( p1t, p2t, p3t ) )
382 { 431 {
432 if( !pCls || !pFnc ) throw SignalException("NULL pointer in slot().");
383 return Signal3<ret, p1t, p2t, p3t>( 433 return Signal3<ret, p1t, p2t, p3t>(
384 new __Slot3<cls, ret, p1t, p2t, p3t>( pCls, pFnc ) 434 new __Slot3<cls, ret, p1t, p2t, p3t>( pCls, pFnc )
385 ); 435 );
@@ -388,6 +438,7 @@ namespace Bu
388 template<typename ret, typename p1t, typename p2t, typename p3t> 438 template<typename ret, typename p1t, typename p2t, typename p3t>
389 Signal3<ret, p1t, p2t, p3t> slot( ret (*pFnc)( p1t, p2t, p3t ) ) 439 Signal3<ret, p1t, p2t, p3t> slot( ret (*pFnc)( p1t, p2t, p3t ) )
390 { 440 {
441 if( !pFnc ) throw SignalException("NULL pointer in slot().");
391 return Signal3<ret, p1t, p2t, p3t>( 442 return Signal3<ret, p1t, p2t, p3t>(
392 new __Slot3F<ret, p1t, p2t, p3t>( pFnc ) 443 new __Slot3F<ret, p1t, p2t, p3t>( pFnc )
393 ); 444 );
@@ -467,9 +518,19 @@ namespace Bu
467 518
468 ret operator()( p1t p1, p2t p2, p3t p3, p4t p4 ) 519 ret operator()( p1t p1, p2t p2, p3t p3, p4t p4 )
469 { 520 {
521 if( !pCb ) throw SignalException("Uninitialized signal used.");
470 return (*pCb)( p1, p2, p3, p4 ); 522 return (*pCb)( p1, p2, p3, p4 );
471 } 523 }
472 524
525 bool isSet() const { return pCb != NULL; }
526 operator bool() const { return isSet(); }
527
528 Signal4 &operator=( const Signal4 &rhs )
529 {
530 pCb = rhs.pCb->clone();
531 return *this;
532 }
533
473 private: 534 private:
474 _Slot4<ret, p1t, p2t, p3t, p4t> *pCb; 535 _Slot4<ret, p1t, p2t, p3t, p4t> *pCb;
475 }; 536 };
@@ -477,6 +538,7 @@ namespace Bu
477 template<typename cls, typename ret, typename p1t, typename p2t, typename p3t, typename p4t> 538 template<typename cls, typename ret, typename p1t, typename p2t, typename p3t, typename p4t>
478 Signal4<ret, p1t, p2t, p3t, p4t> slot( cls *pCls, ret (cls::*pFnc)( p1t, p2t, p3t, p4t ) ) 539 Signal4<ret, p1t, p2t, p3t, p4t> slot( cls *pCls, ret (cls::*pFnc)( p1t, p2t, p3t, p4t ) )
479 { 540 {
541 if( !pCls || !pFnc ) throw SignalException("NULL pointer in slot().");
480 return Signal4<ret, p1t, p2t, p3t, p4t>( 542 return Signal4<ret, p1t, p2t, p3t, p4t>(
481 new __Slot4<cls, ret, p1t, p2t, p3t, p4t>( pCls, pFnc ) 543 new __Slot4<cls, ret, p1t, p2t, p3t, p4t>( pCls, pFnc )
482 ); 544 );
@@ -485,6 +547,7 @@ namespace Bu
485 template<typename ret, typename p1t, typename p2t, typename p3t, typename p4t> 547 template<typename ret, typename p1t, typename p2t, typename p3t, typename p4t>
486 Signal4<ret, p1t, p2t, p3t, p4t> slot( ret (*pFnc)( p1t, p2t, p3t, p4t ) ) 548 Signal4<ret, p1t, p2t, p3t, p4t> slot( ret (*pFnc)( p1t, p2t, p3t, p4t ) )
487 { 549 {
550 if( !pFnc ) throw SignalException("NULL pointer in slot().");
488 return Signal4<ret, p1t, p2t, p3t, p4t>( 551 return Signal4<ret, p1t, p2t, p3t, p4t>(
489 new __Slot4F<ret, p1t, p2t, p3t, p4t>( pFnc ) 552 new __Slot4F<ret, p1t, p2t, p3t, p4t>( pFnc )
490 ); 553 );
@@ -564,9 +627,19 @@ namespace Bu
564 627
565 ret operator()( p1t p1, p2t p2, p3t p3, p4t p4, p5t p5 ) 628 ret operator()( p1t p1, p2t p2, p3t p3, p4t p4, p5t p5 )
566 { 629 {
630 if( !pCb ) throw SignalException("Uninitialized signal used.");
567 return (*pCb)( p1, p2, p3, p4, p5 ); 631 return (*pCb)( p1, p2, p3, p4, p5 );
568 } 632 }
569 633
634 bool isSet() const { return pCb != NULL; }
635 operator bool() const { return isSet(); }
636
637 Signal5 &operator=( const Signal5 &rhs )
638 {
639 pCb = rhs.pCb->clone();
640 return *this;
641 }
642
570 private: 643 private:
571 _Slot5<ret, p1t, p2t, p3t, p4t, p5t> *pCb; 644 _Slot5<ret, p1t, p2t, p3t, p4t, p5t> *pCb;
572 }; 645 };
@@ -574,6 +647,7 @@ namespace Bu
574 template<typename cls, typename ret, typename p1t, typename p2t, typename p3t, typename p4t, typename p5t> 647 template<typename cls, typename ret, typename p1t, typename p2t, typename p3t, typename p4t, typename p5t>
575 Signal5<ret, p1t, p2t, p3t, p4t, p5t> slot( cls *pCls, ret (cls::*pFnc)( p1t, p2t, p3t, p4t, p5t ) ) 648 Signal5<ret, p1t, p2t, p3t, p4t, p5t> slot( cls *pCls, ret (cls::*pFnc)( p1t, p2t, p3t, p4t, p5t ) )
576 { 649 {
650 if( !pCls || !pFnc ) throw SignalException("NULL pointer in slot().");
577 return Signal5<ret, p1t, p2t, p3t, p4t, p5t>( 651 return Signal5<ret, p1t, p2t, p3t, p4t, p5t>(
578 new __Slot5<cls, ret, p1t, p2t, p3t, p4t, p5t>( pCls, pFnc ) 652 new __Slot5<cls, ret, p1t, p2t, p3t, p4t, p5t>( pCls, pFnc )
579 ); 653 );
@@ -582,6 +656,7 @@ namespace Bu
582 template<typename ret, typename p1t, typename p2t, typename p3t, typename p4t, typename p5t> 656 template<typename ret, typename p1t, typename p2t, typename p3t, typename p4t, typename p5t>
583 Signal5<ret, p1t, p2t, p3t, p4t, p5t> slot( ret (*pFnc)( p1t, p2t, p3t, p4t, p5t ) ) 657 Signal5<ret, p1t, p2t, p3t, p4t, p5t> slot( ret (*pFnc)( p1t, p2t, p3t, p4t, p5t ) )
584 { 658 {
659 if( !pFnc ) throw SignalException("NULL pointer in slot().");
585 return Signal5<ret, p1t, p2t, p3t, p4t, p5t>( 660 return Signal5<ret, p1t, p2t, p3t, p4t, p5t>(
586 new __Slot5F<ret, p1t, p2t, p3t, p4t, p5t>( pFnc ) 661 new __Slot5F<ret, p1t, p2t, p3t, p4t, p5t>( pFnc )
587 ); 662 );