diff options
| author | Mike Buland <eichlan@xagasoft.com> | 2009-12-16 21:22:39 +0000 |
|---|---|---|
| committer | Mike Buland <eichlan@xagasoft.com> | 2009-12-16 21:22:39 +0000 |
| commit | afac5804b069e5eb76c799e9edd2eaeff0d99b94 (patch) | |
| tree | d2b3a51f899c7ad1bb828885ff8178613f9ebd63 /src | |
| parent | f72c6e4b97afeb69d9ea4d743c0c302d647ea424 (diff) | |
| download | libbu++-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.cpp | 3 | ||||
| -rw-r--r-- | src/signals.h | 75 |
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 | |||
| 3 | namespace 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 | ||
| 6 | namespace Bu | 7 | namespace 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 | ); |
