From afac5804b069e5eb76c799e9edd2eaeff0d99b94 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Wed, 16 Dec 2009 21:22:39 +0000 Subject: 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. --- src/signals.cpp | 3 +++ src/signals.h | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 src/signals.cpp 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 @@ +#include "bu/signals.h" + +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 @@ #define BU_OBJECT_SIGNALS_H #include "bu/util.h" +#include "bu/exceptionbase.h" namespace Bu { + subExceptionDecl( SignalException ); // // 0 Parameters // @@ -31,6 +33,7 @@ namespace Bu virtual ret operator()() { + return (pCls->*pFnc)(); } @@ -79,9 +82,19 @@ namespace Bu ret operator()() { + if( !pCb ) throw SignalException("Uninitialized signal used."); return (*pCb)(); } + bool isSet() const { return pCb != NULL; } + operator bool() const { return isSet(); } + + Signal0 &operator=( const Signal0 &rhs ) + { + pCb = rhs.pCb->clone(); + return *this; + } + private: _Slot0 *pCb; }; @@ -89,6 +102,7 @@ namespace Bu template Signal0 slot( cls *pCls, ret (cls::*pFnc)() ) { + if( !pCls || !pFnc ) throw SignalException("NULL pointer in slot()."); return Signal0( new __Slot0( pCls, pFnc ) ); @@ -97,6 +111,7 @@ namespace Bu template Signal0 slot( ret (*pFnc)() ) { + if( !pFnc ) throw SignalException("NULL pointer in slot()."); return Signal0( new __Slot0F( pFnc ) ); @@ -176,9 +191,19 @@ namespace Bu ret operator()( p1t p1 ) { + if( !pCb ) throw SignalException("Uninitialized signal used."); return (*pCb)( p1 ); } + bool isSet() const { return pCb != NULL; } + operator bool() const { return isSet(); } + + Signal1 &operator=( const Signal1 &rhs ) + { + pCb = rhs.pCb->clone(); + return *this; + } + private: _Slot1 *pCb; }; @@ -186,6 +211,7 @@ namespace Bu template Signal1 slot( cls *pCls, ret (cls::*pFnc)( p1t ) ) { + if( !pCls || !pFnc ) throw SignalException("NULL pointer in slot()."); return Signal1( new __Slot1( pCls, pFnc ) ); @@ -194,6 +220,7 @@ namespace Bu template Signal1 slot( ret (*pFnc)( p1t ) ) { + if( !pFnc ) throw SignalException("NULL pointer in slot()."); return Signal1( new __Slot1F( pFnc ) ); @@ -273,9 +300,19 @@ namespace Bu ret operator()( p1t p1, p2t p2 ) { + if( !pCb ) throw SignalException("Uninitialized signal used."); return (*pCb)( p1, p2 ); } + bool isSet() const { return pCb != NULL; } + operator bool() const { return isSet(); } + + Signal2 &operator=( const Signal2 &rhs ) + { + pCb = rhs.pCb->clone(); + return *this; + } + private: _Slot2 *pCb; }; @@ -283,6 +320,7 @@ namespace Bu template Signal2 slot( cls *pCls, ret (cls::*pFnc)( p1t, p2t ) ) { + if( !pCls || !pFnc ) throw SignalException("NULL pointer in slot()."); return Signal2( new __Slot2( pCls, pFnc ) ); @@ -291,6 +329,7 @@ namespace Bu template Signal2 slot( ret (*pFnc)( p1t, p2t ) ) { + if( !pFnc ) throw SignalException("NULL pointer in slot()."); return Signal2( new __Slot2F( pFnc ) ); @@ -370,9 +409,19 @@ namespace Bu ret operator()( p1t p1, p2t p2, p3t p3 ) { + if( !pCb ) throw SignalException("Uninitialized signal used."); return (*pCb)( p1, p2, p3 ); } + bool isSet() const { return pCb != NULL; } + operator bool() const { return isSet(); } + + Signal3 &operator=( const Signal3 &rhs ) + { + pCb = rhs.pCb->clone(); + return *this; + } + private: _Slot3 *pCb; }; @@ -380,6 +429,7 @@ namespace Bu template Signal3 slot( cls *pCls, ret (cls::*pFnc)( p1t, p2t, p3t ) ) { + if( !pCls || !pFnc ) throw SignalException("NULL pointer in slot()."); return Signal3( new __Slot3( pCls, pFnc ) ); @@ -388,6 +438,7 @@ namespace Bu template Signal3 slot( ret (*pFnc)( p1t, p2t, p3t ) ) { + if( !pFnc ) throw SignalException("NULL pointer in slot()."); return Signal3( new __Slot3F( pFnc ) ); @@ -467,9 +518,19 @@ namespace Bu ret operator()( p1t p1, p2t p2, p3t p3, p4t p4 ) { + if( !pCb ) throw SignalException("Uninitialized signal used."); return (*pCb)( p1, p2, p3, p4 ); } + bool isSet() const { return pCb != NULL; } + operator bool() const { return isSet(); } + + Signal4 &operator=( const Signal4 &rhs ) + { + pCb = rhs.pCb->clone(); + return *this; + } + private: _Slot4 *pCb; }; @@ -477,6 +538,7 @@ namespace Bu template Signal4 slot( cls *pCls, ret (cls::*pFnc)( p1t, p2t, p3t, p4t ) ) { + if( !pCls || !pFnc ) throw SignalException("NULL pointer in slot()."); return Signal4( new __Slot4( pCls, pFnc ) ); @@ -485,6 +547,7 @@ namespace Bu template Signal4 slot( ret (*pFnc)( p1t, p2t, p3t, p4t ) ) { + if( !pFnc ) throw SignalException("NULL pointer in slot()."); return Signal4( new __Slot4F( pFnc ) ); @@ -564,9 +627,19 @@ namespace Bu ret operator()( p1t p1, p2t p2, p3t p3, p4t p4, p5t p5 ) { + if( !pCb ) throw SignalException("Uninitialized signal used."); return (*pCb)( p1, p2, p3, p4, p5 ); } + bool isSet() const { return pCb != NULL; } + operator bool() const { return isSet(); } + + Signal5 &operator=( const Signal5 &rhs ) + { + pCb = rhs.pCb->clone(); + return *this; + } + private: _Slot5 *pCb; }; @@ -574,6 +647,7 @@ namespace Bu template Signal5 slot( cls *pCls, ret (cls::*pFnc)( p1t, p2t, p3t, p4t, p5t ) ) { + if( !pCls || !pFnc ) throw SignalException("NULL pointer in slot()."); return Signal5( new __Slot5( pCls, pFnc ) ); @@ -582,6 +656,7 @@ namespace Bu template Signal5 slot( ret (*pFnc)( p1t, p2t, p3t, p4t, p5t ) ) { + if( !pFnc ) throw SignalException("NULL pointer in slot()."); return Signal5( new __Slot5F( pFnc ) ); -- cgit v1.2.3