#ifndef __signal_h__ #define __signal_h__ #include "horrible_cast.h" #include "slot_base.h" #include "signal_base.h" /* * Begin signal[X] definitions */ #ifndef __signal0_h__ #define __signal0_h__ // // classes slot0, slot0_function, and slot0_method // // // Abstract base class for slots with 0 parameter(s). // template class slot0: public slot_base { public: /** * Method which performs the actual callback. Must be overridden. * * @return Returns an object of type T_return; the result of the user callback. */ virtual T_return operator() () const = 0; }; // // A concrete slot class for a normal function. // template class slot0_function: public slot0 { public: typedef T_return (*FUNCTION_POINTER)(); // convenience typedef /** * Constructor. * * Converts a function pointer into raw data. */ slot0_function( const FUNCTION_POINTER func ) { // convert and store function pointer in slot_base this->data[0] = safe_horrible_cast(func); } /** * Perform callback. * * Converts raw data back into a function pointer, and calls it. * * @return Returns an object of type T_return; the result of the user callback. */ T_return operator() () const { // retrieve data from slot_base and convert back to a function pointer FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); // call function return func(); } }; // // A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method'). // template class slot0_method: public slot0 { public: /** * Constructor. * * Converts an object and method pointer into raw data. */ slot0_method(const T_object* p_object, const T_member p_member) { // convert and store object pointer and member function pointer in slot_base this->data[0] = safe_horrible_cast(p_object); this->data[1] = safe_horrible_cast(p_member); } /** * Perform callback. * * Converts raw data back into a method pointer, and calls it. * * @return Returns an object of type T_return; the result of the user callback. */ T_return operator() () const { // retrieve data from slot_base and convert back to an object pointer and member function pointer T_object* p_object = dangerous_horrible_cast(this->data[0]); T_member p_member = dangerous_horrible_cast (this->data[1]); // call member function return (p_object->*p_member)(); } }; // // class signal0 // template< typename T_return > class signal0: public signal_base { public: /** * Emit the signal. * * Iterate through the list of slots, and call each one. */ void operator() () { // if we're already emitting, return (i.e. no re-entrancy allowed) if( signal_base::emitting ) { #if defined( _DEBUG ) printf("WARNING: signal0<...> @ 0x%p recursive emit attempt\n", this); #endif return; } // set emitting flag signal_base::emitting = true; // iterate through the list signal_base::list_node* cur = signal_base::head; while( cur ) { // cast the slot_base pointer to a slot0 pointer (converts from raw memory to pointer again) slot0* s = static_cast*>(cur->slot); // call the signal as long as it's still valid if ( !cur->deleted ) { (*s)(); } // move to next slot in the list. cur = cur->next; } // delete any pending slot deletions signal_base::remove_pending_nodes( ); // clear emitting flag signal_base::emitting = false; } // // signal connections to slots // // convenience typedef typedef T_return (*FUNCTION_POINTER)(); // connect to normal functions bool connect( FUNCTION_POINTER func ) { // make a copy of the slot to store in our list slot0* sNewFunc = new slot0_function( func ); // add it to the end of our linked list return signal_base::bind(sNewFunc); } // connect to an object's method template bool connect(T_object* p_object, T_member p_member) { // make a copy of the slot to store in our list slot0* sNewMethod = new slot0_method( p_object, p_member ); // add it to the end of our linked list return signal_base::bind(sNewMethod); } // // signal disconnections from slots // // disconnect from a normal function bool disconnect( FUNCTION_POINTER func ) { // make a temporary slot we can use to find a match in the list slot0_function sTest( func ); // search and remove it return signal_base::unbind(&sTest); } // disconnect from an object's method template bool disconnect(T_object* p_object, T_member p_member) { // make a temporary slot we can use to find a match in the list slot0_method sTemp(p_object,p_member); // search and remove it return signal_base::unbind(&sTemp); } }; #endif // __signal0_h__ #ifndef __signal1_h__ #define __signal1_h__ // // classes slot1, slot1_function, and slot1_method // // // Abstract base class for slots with 1 parameter(s). // template class slot1: public slot_base { public: /** * Method which performs the actual callback. Must be overridden. * * @return Returns an object of type T_return; the result of the user callback. */ virtual T_return operator() (T_arg0 a0) const = 0; }; // // A concrete slot class for a normal function. // template class slot1_function: public slot1 { public: typedef T_return (*FUNCTION_POINTER)(T_arg0 a0); // convenience typedef /** * Constructor. * * Converts a function pointer into raw data. */ slot1_function( const FUNCTION_POINTER func ) { // convert and store function pointer in slot_base this->data[0] = safe_horrible_cast(func); } /** * Perform callback. * * Converts raw data back into a function pointer, and calls it. * * @return Returns an object of type T_return; the result of the user callback. */ T_return operator() (T_arg0 a0) const { // retrieve data from slot_base and convert back to a function pointer FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); // call function return func(a0); } }; // // A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method'). // template class slot1_method: public slot1 { public: /** * Constructor. * * Converts an object and method pointer into raw data. */ slot1_method(const T_object* p_object, const T_member p_member) { // convert and store object pointer and member function pointer in slot_base this->data[0] = safe_horrible_cast(p_object); this->data[1] = safe_horrible_cast(p_member); } /** * Perform callback. * * Converts raw data back into a method pointer, and calls it. * * @return Returns an object of type T_return; the result of the user callback. */ T_return operator() (T_arg0 a0) const { // retrieve data from slot_base and convert back to an object pointer and member function pointer T_object* p_object = dangerous_horrible_cast(this->data[0]); T_member p_member = dangerous_horrible_cast (this->data[1]); // call member function return (p_object->*p_member)(a0); } }; // // class signal1 // template< typename T_return, typename T_arg0 > class signal1: public signal_base { public: /** * Emit the signal. * * Iterate through the list of slots, and call each one. */ void operator() (T_arg0 a0) { // if we're already emitting, return (i.e. no re-entrancy allowed) if( signal_base::emitting ) { #if defined( _DEBUG ) printf("WARNING: signal1<...> @ 0x%p recursive emit attempt\n", this); #endif return; } // set emitting flag signal_base::emitting = true; // iterate through the list signal_base::list_node* cur = signal_base::head; while( cur ) { // cast the slot_base pointer to a slot1 pointer (converts from raw memory to pointer again) slot1* s = static_cast*>(cur->slot); // call the signal as long as it's still valid if ( !cur->deleted ) { (*s)(a0); } // move to next slot in the list. cur = cur->next; } // delete any pending slot deletions signal_base::remove_pending_nodes( ); // clear emitting flag signal_base::emitting = false; } // // signal connections to slots // // convenience typedef typedef T_return (*FUNCTION_POINTER)(T_arg0 a0); // connect to normal functions bool connect( FUNCTION_POINTER func ) { // make a copy of the slot to store in our list slot1* sNewFunc = new slot1_function( func ); // add it to the end of our linked list return signal_base::bind(sNewFunc); } // connect to an object's method template bool connect(T_object* p_object, T_member p_member) { // make a copy of the slot to store in our list slot1* sNewMethod = new slot1_method( p_object, p_member ); // add it to the end of our linked list return signal_base::bind(sNewMethod); } // // signal disconnections from slots // // disconnect from a normal function bool disconnect( FUNCTION_POINTER func ) { // make a temporary slot we can use to find a match in the list slot1_function sTest( func ); // search and remove it return signal_base::unbind(&sTest); } // disconnect from an object's method template bool disconnect(T_object* p_object, T_member p_member) { // make a temporary slot we can use to find a match in the list slot1_method sTemp(p_object,p_member); // search and remove it return signal_base::unbind(&sTemp); } }; #endif // __signal1_h__ #ifndef __signal2_h__ #define __signal2_h__ // // classes slot2, slot2_function, and slot2_method // // // Abstract base class for slots with 2 parameter(s). // template class slot2: public slot_base { public: /** * Method which performs the actual callback. Must be overridden. * * @return Returns an object of type T_return; the result of the user callback. */ virtual T_return operator() (T_arg0 a0, T_arg1 a1) const = 0; }; // // A concrete slot class for a normal function. // template class slot2_function: public slot2 { public: typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1); // convenience typedef /** * Constructor. * * Converts a function pointer into raw data. */ slot2_function( const FUNCTION_POINTER func ) { // convert and store function pointer in slot_base this->data[0] = safe_horrible_cast(func); } /** * Perform callback. * * Converts raw data back into a function pointer, and calls it. * * @return Returns an object of type T_return; the result of the user callback. */ T_return operator() (T_arg0 a0, T_arg1 a1) const { // retrieve data from slot_base and convert back to a function pointer FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); // call function return func(a0, a1); } }; // // A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method'). // template class slot2_method: public slot2 { public: /** * Constructor. * * Converts an object and method pointer into raw data. */ slot2_method(const T_object* p_object, const T_member p_member) { // convert and store object pointer and member function pointer in slot_base this->data[0] = safe_horrible_cast(p_object); this->data[1] = safe_horrible_cast(p_member); } /** * Perform callback. * * Converts raw data back into a method pointer, and calls it. * * @return Returns an object of type T_return; the result of the user callback. */ T_return operator() (T_arg0 a0, T_arg1 a1) const { // retrieve data from slot_base and convert back to an object pointer and member function pointer T_object* p_object = dangerous_horrible_cast(this->data[0]); T_member p_member = dangerous_horrible_cast (this->data[1]); // call member function return (p_object->*p_member)(a0, a1); } }; // // class signal2 // template< typename T_return, typename T_arg0, typename T_arg1 > class signal2: public signal_base { public: /** * Emit the signal. * * Iterate through the list of slots, and call each one. */ void operator() (T_arg0 a0, T_arg1 a1) { // if we're already emitting, return (i.e. no re-entrancy allowed) if( signal_base::emitting ) { #if defined( _DEBUG ) printf("WARNING: signal2<...> @ 0x%p recursive emit attempt\n", this); #endif return; } // set emitting flag signal_base::emitting = true; // iterate through the list signal_base::list_node* cur = signal_base::head; while( cur ) { // cast the slot_base pointer to a slot2 pointer (converts from raw memory to pointer again) slot2* s = static_cast*>(cur->slot); // call the signal as long as it's still valid if ( !cur->deleted ) { (*s)(a0, a1); } // move to next slot in the list. cur = cur->next; } // delete any pending slot deletions signal_base::remove_pending_nodes( ); // clear emitting flag signal_base::emitting = false; } // // signal connections to slots // // convenience typedef typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1); // connect to normal functions bool connect( FUNCTION_POINTER func ) { // make a copy of the slot to store in our list slot2* sNewFunc = new slot2_function( func ); // add it to the end of our linked list return signal_base::bind(sNewFunc); } // connect to an object's method template bool connect(T_object* p_object, T_member p_member) { // make a copy of the slot to store in our list slot2* sNewMethod = new slot2_method( p_object, p_member ); // add it to the end of our linked list return signal_base::bind(sNewMethod); } // // signal disconnections from slots // // disconnect from a normal function bool disconnect( FUNCTION_POINTER func ) { // make a temporary slot we can use to find a match in the list slot2_function sTest( func ); // search and remove it return signal_base::unbind(&sTest); } // disconnect from an object's method template bool disconnect(T_object* p_object, T_member p_member) { // make a temporary slot we can use to find a match in the list slot2_method sTemp(p_object,p_member); // search and remove it return signal_base::unbind(&sTemp); } }; #endif // __signal2_h__ #ifndef __signal3_h__ #define __signal3_h__ // // classes slot3, slot3_function, and slot3_method // // // Abstract base class for slots with 3 parameter(s). // template class slot3: public slot_base { public: /** * Method which performs the actual callback. Must be overridden. * * @return Returns an object of type T_return; the result of the user callback. */ virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2) const = 0; }; // // A concrete slot class for a normal function. // template class slot3_function: public slot3 { public: typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2); // convenience typedef /** * Constructor. * * Converts a function pointer into raw data. */ slot3_function( const FUNCTION_POINTER func ) { // convert and store function pointer in slot_base this->data[0] = safe_horrible_cast(func); } /** * Perform callback. * * Converts raw data back into a function pointer, and calls it. * * @return Returns an object of type T_return; the result of the user callback. */ T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2) const { // retrieve data from slot_base and convert back to a function pointer FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); // call function return func(a0, a1, a2); } }; // // A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method'). // template class slot3_method: public slot3 { public: /** * Constructor. * * Converts an object and method pointer into raw data. */ slot3_method(const T_object* p_object, const T_member p_member) { // convert and store object pointer and member function pointer in slot_base this->data[0] = safe_horrible_cast(p_object); this->data[1] = safe_horrible_cast(p_member); } /** * Perform callback. * * Converts raw data back into a method pointer, and calls it. * * @return Returns an object of type T_return; the result of the user callback. */ T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2) const { // retrieve data from slot_base and convert back to an object pointer and member function pointer T_object* p_object = dangerous_horrible_cast(this->data[0]); T_member p_member = dangerous_horrible_cast (this->data[1]); // call member function return (p_object->*p_member)(a0, a1, a2); } }; // // class signal3 // template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2 > class signal3: public signal_base { public: /** * Emit the signal. * * Iterate through the list of slots, and call each one. */ void operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2) { // if we're already emitting, return (i.e. no re-entrancy allowed) if( signal_base::emitting ) { #if defined( _DEBUG ) printf("WARNING: signal3<...> @ 0x%p recursive emit attempt\n", this); #endif return; } // set emitting flag signal_base::emitting = true; // iterate through the list signal_base::list_node* cur = signal_base::head; while( cur ) { // cast the slot_base pointer to a slot3 pointer (converts from raw memory to pointer again) slot3* s = static_cast*>(cur->slot); // call the signal as long as it's still valid if ( !cur->deleted ) { (*s)(a0, a1, a2); } // move to next slot in the list. cur = cur->next; } // delete any pending slot deletions signal_base::remove_pending_nodes( ); // clear emitting flag signal_base::emitting = false; } // // signal connections to slots // // convenience typedef typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2); // connect to normal functions bool connect( FUNCTION_POINTER func ) { // make a copy of the slot to store in our list slot3* sNewFunc = new slot3_function( func ); // add it to the end of our linked list return signal_base::bind(sNewFunc); } // connect to an object's method template bool connect(T_object* p_object, T_member p_member) { // make a copy of the slot to store in our list slot3* sNewMethod = new slot3_method( p_object, p_member ); // add it to the end of our linked list return signal_base::bind(sNewMethod); } // // signal disconnections from slots // // disconnect from a normal function bool disconnect( FUNCTION_POINTER func ) { // make a temporary slot we can use to find a match in the list slot3_function sTest( func ); // search and remove it return signal_base::unbind(&sTest); } // disconnect from an object's method template bool disconnect(T_object* p_object, T_member p_member) { // make a temporary slot we can use to find a match in the list slot3_method sTemp(p_object,p_member); // search and remove it return signal_base::unbind(&sTemp); } }; #endif // __signal3_h__ #ifndef __signal4_h__ #define __signal4_h__ // // classes slot4, slot4_function, and slot4_method // // // Abstract base class for slots with 4 parameter(s). // template class slot4: public slot_base { public: /** * Method which performs the actual callback. Must be overridden. * * @return Returns an object of type T_return; the result of the user callback. */ virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3) const = 0; }; // // A concrete slot class for a normal function. // template class slot4_function: public slot4 { public: typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3); // convenience typedef /** * Constructor. * * Converts a function pointer into raw data. */ slot4_function( const FUNCTION_POINTER func ) { // convert and store function pointer in slot_base this->data[0] = safe_horrible_cast(func); } /** * Perform callback. * * Converts raw data back into a function pointer, and calls it. * * @return Returns an object of type T_return; the result of the user callback. */ T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3) const { // retrieve data from slot_base and convert back to a function pointer FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); // call function return func(a0, a1, a2, a3); } }; // // A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method'). // template class slot4_method: public slot4 { public: /** * Constructor. * * Converts an object and method pointer into raw data. */ slot4_method(const T_object* p_object, const T_member p_member) { // convert and store object pointer and member function pointer in slot_base this->data[0] = safe_horrible_cast(p_object); this->data[1] = safe_horrible_cast(p_member); } /** * Perform callback. * * Converts raw data back into a method pointer, and calls it. * * @return Returns an object of type T_return; the result of the user callback. */ T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3) const { // retrieve data from slot_base and convert back to an object pointer and member function pointer T_object* p_object = dangerous_horrible_cast(this->data[0]); T_member p_member = dangerous_horrible_cast (this->data[1]); // call member function return (p_object->*p_member)(a0, a1, a2, a3); } }; // // class signal4 // template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2, typename T_arg3 > class signal4: public signal_base { public: /** * Emit the signal. * * Iterate through the list of slots, and call each one. */ void operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3) { // if we're already emitting, return (i.e. no re-entrancy allowed) if( signal_base::emitting ) { #if defined( _DEBUG ) printf("WARNING: signal4<...> @ 0x%p recursive emit attempt\n", this); #endif return; } // set emitting flag signal_base::emitting = true; // iterate through the list signal_base::list_node* cur = signal_base::head; while( cur ) { // cast the slot_base pointer to a slot4 pointer (converts from raw memory to pointer again) slot4* s = static_cast*>(cur->slot); // call the signal as long as it's still valid if ( !cur->deleted ) { (*s)(a0, a1, a2, a3); } // move to next slot in the list. cur = cur->next; } // delete any pending slot deletions signal_base::remove_pending_nodes( ); // clear emitting flag signal_base::emitting = false; } // // signal connections to slots // // convenience typedef typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3); // connect to normal functions bool connect( FUNCTION_POINTER func ) { // make a copy of the slot to store in our list slot4* sNewFunc = new slot4_function( func ); // add it to the end of our linked list return signal_base::bind(sNewFunc); } // connect to an object's method template bool connect(T_object* p_object, T_member p_member) { // make a copy of the slot to store in our list slot4* sNewMethod = new slot4_method( p_object, p_member ); // add it to the end of our linked list return signal_base::bind(sNewMethod); } // // signal disconnections from slots // // disconnect from a normal function bool disconnect( FUNCTION_POINTER func ) { // make a temporary slot we can use to find a match in the list slot4_function sTest( func ); // search and remove it return signal_base::unbind(&sTest); } // disconnect from an object's method template bool disconnect(T_object* p_object, T_member p_member) { // make a temporary slot we can use to find a match in the list slot4_method sTemp(p_object,p_member); // search and remove it return signal_base::unbind(&sTemp); } }; #endif // __signal4_h__ #ifndef __signal5_h__ #define __signal5_h__ // // classes slot5, slot5_function, and slot5_method // // // Abstract base class for slots with 5 parameter(s). // template class slot5: public slot_base { public: /** * Method which performs the actual callback. Must be overridden. * * @return Returns an object of type T_return; the result of the user callback. */ virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4) const = 0; }; // // A concrete slot class for a normal function. // template class slot5_function: public slot5 { public: typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4); // convenience typedef /** * Constructor. * * Converts a function pointer into raw data. */ slot5_function( const FUNCTION_POINTER func ) { // convert and store function pointer in slot_base this->data[0] = safe_horrible_cast(func); } /** * Perform callback. * * Converts raw data back into a function pointer, and calls it. * * @return Returns an object of type T_return; the result of the user callback. */ T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4) const { // retrieve data from slot_base and convert back to a function pointer FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); // call function return func(a0, a1, a2, a3, a4); } }; // // A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method'). // template class slot5_method: public slot5 { public: /** * Constructor. * * Converts an object and method pointer into raw data. */ slot5_method(const T_object* p_object, const T_member p_member) { // convert and store object pointer and member function pointer in slot_base this->data[0] = safe_horrible_cast(p_object); this->data[1] = safe_horrible_cast(p_member); } /** * Perform callback. * * Converts raw data back into a method pointer, and calls it. * * @return Returns an object of type T_return; the result of the user callback. */ T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4) const { // retrieve data from slot_base and convert back to an object pointer and member function pointer T_object* p_object = dangerous_horrible_cast(this->data[0]); T_member p_member = dangerous_horrible_cast (this->data[1]); // call member function return (p_object->*p_member)(a0, a1, a2, a3, a4); } }; // // class signal5 // template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2, typename T_arg3, typename T_arg4 > class signal5: public signal_base { public: /** * Emit the signal. * * Iterate through the list of slots, and call each one. */ void operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4) { // if we're already emitting, return (i.e. no re-entrancy allowed) if( signal_base::emitting ) { #if defined( _DEBUG ) printf("WARNING: signal5<...> @ 0x%p recursive emit attempt\n", this); #endif return; } // set emitting flag signal_base::emitting = true; // iterate through the list signal_base::list_node* cur = signal_base::head; while( cur ) { // cast the slot_base pointer to a slot5 pointer (converts from raw memory to pointer again) slot5* s = static_cast*>(cur->slot); // call the signal as long as it's still valid if ( !cur->deleted ) { (*s)(a0, a1, a2, a3, a4); } // move to next slot in the list. cur = cur->next; } // delete any pending slot deletions signal_base::remove_pending_nodes( ); // clear emitting flag signal_base::emitting = false; } // // signal connections to slots // // convenience typedef typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4); // connect to normal functions bool connect( FUNCTION_POINTER func ) { // make a copy of the slot to store in our list slot5* sNewFunc = new slot5_function( func ); // add it to the end of our linked list return signal_base::bind(sNewFunc); } // connect to an object's method template bool connect(T_object* p_object, T_member p_member) { // make a copy of the slot to store in our list slot5* sNewMethod = new slot5_method( p_object, p_member ); // add it to the end of our linked list return signal_base::bind(sNewMethod); } // // signal disconnections from slots // // disconnect from a normal function bool disconnect( FUNCTION_POINTER func ) { // make a temporary slot we can use to find a match in the list slot5_function sTest( func ); // search and remove it return signal_base::unbind(&sTest); } // disconnect from an object's method template bool disconnect(T_object* p_object, T_member p_member) { // make a temporary slot we can use to find a match in the list slot5_method sTemp(p_object,p_member); // search and remove it return signal_base::unbind(&sTemp); } }; #endif // __signal5_h__ #ifndef __signal6_h__ #define __signal6_h__ // // classes slot6, slot6_function, and slot6_method // // // Abstract base class for slots with 6 parameter(s). // template class slot6: public slot_base { public: /** * Method which performs the actual callback. Must be overridden. * * @return Returns an object of type T_return; the result of the user callback. */ virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5) const = 0; }; // // A concrete slot class for a normal function. // template class slot6_function: public slot6 { public: typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5); // convenience typedef /** * Constructor. * * Converts a function pointer into raw data. */ slot6_function( const FUNCTION_POINTER func ) { // convert and store function pointer in slot_base this->data[0] = safe_horrible_cast(func); } /** * Perform callback. * * Converts raw data back into a function pointer, and calls it. * * @return Returns an object of type T_return; the result of the user callback. */ T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5) const { // retrieve data from slot_base and convert back to a function pointer FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); // call function return func(a0, a1, a2, a3, a4, a5); } }; // // A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method'). // template class slot6_method: public slot6 { public: /** * Constructor. * * Converts an object and method pointer into raw data. */ slot6_method(const T_object* p_object, const T_member p_member) { // convert and store object pointer and member function pointer in slot_base this->data[0] = safe_horrible_cast(p_object); this->data[1] = safe_horrible_cast(p_member); } /** * Perform callback. * * Converts raw data back into a method pointer, and calls it. * * @return Returns an object of type T_return; the result of the user callback. */ T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5) const { // retrieve data from slot_base and convert back to an object pointer and member function pointer T_object* p_object = dangerous_horrible_cast(this->data[0]); T_member p_member = dangerous_horrible_cast (this->data[1]); // call member function return (p_object->*p_member)(a0, a1, a2, a3, a4, a5); } }; // // class signal6 // template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2, typename T_arg3, typename T_arg4, typename T_arg5 > class signal6: public signal_base { public: /** * Emit the signal. * * Iterate through the list of slots, and call each one. */ void operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5) { // if we're already emitting, return (i.e. no re-entrancy allowed) if( signal_base::emitting ) { #if defined( _DEBUG ) printf("WARNING: signal6<...> @ 0x%p recursive emit attempt\n", this); #endif return; } // set emitting flag signal_base::emitting = true; // iterate through the list signal_base::list_node* cur = signal_base::head; while( cur ) { // cast the slot_base pointer to a slot6 pointer (converts from raw memory to pointer again) slot6* s = static_cast*>(cur->slot); // call the signal as long as it's still valid if ( !cur->deleted ) { (*s)(a0, a1, a2, a3, a4, a5); } // move to next slot in the list. cur = cur->next; } // delete any pending slot deletions signal_base::remove_pending_nodes( ); // clear emitting flag signal_base::emitting = false; } // // signal connections to slots // // convenience typedef typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5); // connect to normal functions bool connect( FUNCTION_POINTER func ) { // make a copy of the slot to store in our list slot6* sNewFunc = new slot6_function( func ); // add it to the end of our linked list return signal_base::bind(sNewFunc); } // connect to an object's method template bool connect(T_object* p_object, T_member p_member) { // make a copy of the slot to store in our list slot6* sNewMethod = new slot6_method( p_object, p_member ); // add it to the end of our linked list return signal_base::bind(sNewMethod); } // // signal disconnections from slots // // disconnect from a normal function bool disconnect( FUNCTION_POINTER func ) { // make a temporary slot we can use to find a match in the list slot6_function sTest( func ); // search and remove it return signal_base::unbind(&sTest); } // disconnect from an object's method template bool disconnect(T_object* p_object, T_member p_member) { // make a temporary slot we can use to find a match in the list slot6_method sTemp(p_object,p_member); // search and remove it return signal_base::unbind(&sTemp); } }; #endif // __signal6_h__ /* * Begin signal template definitions and specilizations */ struct nilarg; // full template for signal<> (signal<> inherits signal6<>) template class signal: public signal6 { /* empty class */ }; // partial specialization for signal<> with 5 parameters (signal<> inherits signal5<>) template class signal: public signal5 { /* empty class */ }; // partial specialization for signal<> with 4 parameters (signal<> inherits signal4<>) template class signal: public signal4 { /* empty class */ }; // partial specialization for signal<> with 3 parameters (signal<> inherits signal3<>) template class signal: public signal3 { /* empty class */ }; // partial specialization for signal<> with 2 parameters (signal<> inherits signal2<>) template class signal: public signal2 { /* empty class */ }; // partial specialization for signal<> with 1 parameters (signal<> inherits signal1<>) template class signal: public signal1 { /* empty class */ }; // partial specialization for signal<> with 0 parameters (signal<> inherits signal0<>) template class signal: public signal0 { /* empty class */ }; #endif // __signal_h__