/* * Copyright (C) 2007-2010 Xagasoft, All rights reserved. * * This file is part of the libbu++ library and is released under the * terms of the license contained in the file LICENSE. */ #ifndef BU_OBJECT_SIGNALS_H #define BU_OBJECT_SIGNALS_H #include "bu/util.h" #include "bu/exceptionbase.h" namespace Bu { subExceptionDecl( SignalException ); // // 0 Parameters // template class _Slot0 { public: _Slot0() { } virtual ~_Slot0() { } virtual ret operator()()=0; virtual _Slot0 *clone() const=0; }; template class __Slot0 : public _Slot0 { public: __Slot0( cls *pCls, ret (cls::*pFnc)() ) : pCls( pCls ), pFnc( pFnc ) { } virtual ~__Slot0() { } virtual ret operator()() { return (pCls->*pFnc)(); } virtual _Slot0 *clone() const { return new __Slot0( pCls, pFnc ); } private: cls *pCls; ret (cls::*pFnc)(); }; template class __Slot0F : public _Slot0 { public: __Slot0F( ret (*pFnc)() ) : pFnc( pFnc ) { } virtual ~__Slot0F() { } virtual ret operator()() { return (*pFnc)(); } virtual _Slot0 *clone() const { return new __Slot0F( pFnc ); } private: ret (*pFnc)(); }; template class Signal0 { public: Signal0() : pCb( NULL ) { } Signal0( _Slot0 *pCb ) : pCb( pCb ) { } Signal0( const Signal0 &rSrc ) : pCb( (rSrc.pCb)?(rSrc.pCb->clone()):(NULL) ) { } virtual ~Signal0() { delete pCb; pCb = NULL; } 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; }; template Signal0 slot( cls *pCls, ret (cls::*pFnc)() ) { if( !pCls || !pFnc ) throw SignalException("NULL pointer in slot()."); return Signal0( new __Slot0( pCls, pFnc ) ); } template Signal0 slot( ret (*pFnc)() ) { if( !pFnc ) throw SignalException("NULL pointer in slot()."); return Signal0( new __Slot0F( pFnc ) ); } // // 1 Parameter // template class _Slot1 { public: _Slot1() { } virtual ~_Slot1() { } virtual ret operator()( p1t p1 )=0; virtual _Slot1 *clone() const=0; }; template class __Slot1 : public _Slot1 { public: __Slot1( cls *pCls, ret (cls::*pFnc)( p1t ) ) : pCls( pCls ), pFnc( pFnc ) { } virtual ~__Slot1() { } virtual ret operator()( p1t p1 ) { return (pCls->*pFnc)( p1 ); } virtual _Slot1 *clone() const { return new __Slot1( pCls, pFnc ); } private: cls *pCls; ret (cls::*pFnc)( p1t ); }; template class __Slot1F : public _Slot1 { public: __Slot1F( ret (*pFnc)( p1t ) ) : pFnc( pFnc ) { } virtual ~__Slot1F() { } virtual ret operator()( p1t p1 ) { return (*pFnc)( p1 ); } virtual _Slot1 *clone() const { return new __Slot1F( pFnc ); } private: ret (*pFnc)( p1t p1 ); }; template class Signal1 { public: Signal1() : pCb( NULL ) { } Signal1( _Slot1 *pCb ) : pCb( pCb ) { } Signal1( const Signal1 &rSrc ) : pCb( (rSrc.pCb)?(rSrc.pCb->clone()):(NULL) ) { } virtual ~Signal1() { delete pCb; pCb = NULL; } 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; }; template Signal1 slot( cls *pCls, ret (cls::*pFnc)( p1t ) ) { if( !pCls || !pFnc ) throw SignalException("NULL pointer in slot()."); return Signal1( new __Slot1( pCls, pFnc ) ); } template Signal1 slot( ret (*pFnc)( p1t ) ) { if( !pFnc ) throw SignalException("NULL pointer in slot()."); return Signal1( new __Slot1F( pFnc ) ); } // // 2 Parameters // template class _Slot2 { public: _Slot2() { } virtual ~_Slot2() { } virtual ret operator()( p1t p1, p2t p2 )=0; virtual _Slot2 *clone() const=0; }; template class __Slot2 : public _Slot2 { public: __Slot2( cls *pCls, ret (cls::*pFnc)( p1t, p2t ) ) : pCls( pCls ), pFnc( pFnc ) { } virtual ~__Slot2() { } virtual ret operator()( p1t p1, p2t p2 ) { return (pCls->*pFnc)( p1, p2 ); } virtual _Slot2 *clone() const { return new __Slot2( pCls, pFnc ); } private: cls *pCls; ret (cls::*pFnc)( p1t, p2t ); }; template class __Slot2F : public _Slot2 { public: __Slot2F( ret (*pFnc)( p1t, p2t ) ) : pFnc( pFnc ) { } virtual ~__Slot2F() { } virtual ret operator()( p1t p1, p2t p2 ) { return (*pFnc)( p1, p2 ); } virtual _Slot2 *clone() const { return new __Slot2F( pFnc ); } private: ret (*pFnc)( p1t, p2t ); }; template class Signal2 { public: Signal2() : pCb( NULL ) { } Signal2( _Slot2 *pCb ) : pCb( pCb ) { } Signal2( const Signal2 &rSrc ) : pCb( (rSrc.pCb)?(rSrc.pCb->clone()):(NULL) ) { } virtual ~Signal2() { delete pCb; pCb = NULL; } 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; }; 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 ) ); } template Signal2 slot( ret (*pFnc)( p1t, p2t ) ) { if( !pFnc ) throw SignalException("NULL pointer in slot()."); return Signal2( new __Slot2F( pFnc ) ); } // // 3 Parameters // template class _Slot3 { public: _Slot3() { } virtual ~_Slot3() { } virtual ret operator()( p1t p1, p2t p2, p3t p3 )=0; virtual _Slot3 *clone() const=0; }; template class __Slot3 : public _Slot3 { public: __Slot3( cls *pCls, ret (cls::*pFnc)( p1t, p2t, p3t ) ) : pCls( pCls ), pFnc( pFnc ) { } virtual ~__Slot3() { } virtual ret operator()( p1t p1, p2t p2, p3t p3 ) { return (pCls->*pFnc)( p1, p2, p3 ); } virtual _Slot3 *clone() const { return new __Slot3( pCls, pFnc ); } private: cls *pCls; ret (cls::*pFnc)( p1t, p2t, p3t ); }; template class __Slot3F : public _Slot3 { public: __Slot3F( ret (*pFnc)( p1t, p2t, p3t ) ) : pFnc( pFnc ) { } virtual ~__Slot3F() { } virtual ret operator()( p1t p1, p2t p2, p3t p3 ) { return (*pFnc)( p1, p2, p3 ); } virtual _Slot3 *clone() const { return new __Slot3F( pFnc ); } private: ret (*pFnc)( p1t, p2t, p3t ); }; template class Signal3 { public: Signal3() : pCb( NULL ) { } Signal3( _Slot3 *pCb ) : pCb( pCb ) { } Signal3( const Signal3 &rSrc ) : pCb( (rSrc.pCb)?(rSrc.pCb->clone()):(NULL) ) { } virtual ~Signal3() { delete pCb; pCb = NULL; } 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; }; 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 ) ); } template Signal3 slot( ret (*pFnc)( p1t, p2t, p3t ) ) { if( !pFnc ) throw SignalException("NULL pointer in slot()."); return Signal3( new __Slot3F( pFnc ) ); } // // 4 Parameters // template class _Slot4 { public: _Slot4() { } virtual ~_Slot4() { } virtual ret operator()( p1t p1, p2t p2, p3t p3, p4t p4 )=0; virtual _Slot4 *clone() const=0; }; template class __Slot4 : public _Slot4 { public: __Slot4( cls *pCls, ret (cls::*pFnc)( p1t, p2t, p3t, p4t ) ) : pCls( pCls ), pFnc( pFnc ) { } virtual ~__Slot4() { } virtual ret operator()( p1t p1, p2t p2, p3t p3, p4t p4 ) { return (pCls->*pFnc)( p1, p2, p3, p4 ); } virtual _Slot4 *clone() const { return new __Slot4( pCls, pFnc ); } private: cls *pCls; ret (cls::*pFnc)( p1t, p2t, p3t, p4t ); }; template class __Slot4F : public _Slot4 { public: __Slot4F( ret (*pFnc)( p1t, p2t, p3t, p4t ) ) : pFnc( pFnc ) { } virtual ~__Slot4F() { } virtual ret operator()( p1t p1, p2t p2, p3t p3, p4t p4 ) { return (*pFnc)( p1, p2, p3, p4 ); } virtual _Slot4 *clone() const { return new __Slot4F( pFnc ); } private: ret (*pFnc)( p1t, p2t, p3t, p4t ); }; template class Signal4 { public: Signal4() : pCb( NULL ) { } Signal4( _Slot4 *pCb ) : pCb( pCb ) { } Signal4( const Signal4 &rSrc ) : pCb( (rSrc.pCb)?(rSrc.pCb->clone()):(NULL) ) { } virtual ~Signal4() { delete pCb; pCb = NULL; } 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; }; 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 ) ); } template Signal4 slot( ret (*pFnc)( p1t, p2t, p3t, p4t ) ) { if( !pFnc ) throw SignalException("NULL pointer in slot()."); return Signal4( new __Slot4F( pFnc ) ); } // // 5 Parameters // template class _Slot5 { public: _Slot5() { } virtual ~_Slot5() { } virtual ret operator()( p1t p1, p2t p2, p3t p3, p4t p4, p5t p5 )=0; virtual _Slot5 *clone() const=0; }; template class __Slot5 : public _Slot5 { public: __Slot5( cls *pCls, ret (cls::*pFnc)( p1t, p2t, p3t, p4t, p5t ) ) : pCls( pCls ), pFnc( pFnc ) { } virtual ~__Slot5() { } virtual ret operator()( p1t p1, p2t p2, p3t p3, p4t p4, p5t p5 ) { return (pCls->*pFnc)( p1, p2, p3, p4, p5 ); } virtual _Slot5 *clone() const { return new __Slot5( pCls, pFnc ); } private: cls *pCls; ret (cls::*pFnc)( p1t, p2t, p3t, p4t, p5t ); }; template class __Slot5F : public _Slot5 { public: __Slot5F( ret (*pFnc)( p1t, p2t, p3t, p4t, p5t ) ) : pFnc( pFnc ) { } virtual ~__Slot5F() { } virtual ret operator()( p1t p1, p2t p2, p3t p3, p4t p4, p5t p5 ) { return (*pFnc)( p1, p2, p3, p4, p5 ); } virtual _Slot5 *clone() const { return new __Slot5F( pFnc ); } private: ret (*pFnc)( p1t, p2t, p3t, p4t, p5t ); }; template class Signal5 { public: Signal5() : pCb( NULL ) { } Signal5( _Slot5 *pCb ) : pCb( pCb ) { } Signal5( const Signal5 &rSrc ) : pCb( (rSrc.pCb)?(rSrc.pCb->clone()):(NULL) ) { } virtual ~Signal5() { delete pCb; pCb = NULL; } 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; }; 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 ) ); } template Signal5 slot( ret (*pFnc)( p1t, p2t, p3t, p4t, p5t ) ) { if( !pFnc ) throw SignalException("NULL pointer in slot()."); return Signal5( new __Slot5F( pFnc ) ); } }; #endif