diff --git a/generate.rb b/generate.rb index a676a0a..d1a6d0c 100755 --- a/generate.rb +++ b/generate.rb @@ -88,7 +88,7 @@ def make_template(nargs) text += "template <#{template_params}>\n" if i == nargs - text += "class signal: public signal#{i}<#{template_args} { /* empty class */ };\n" + text += "class signal: public signal#{i}<#{template_args}> { /* empty class */ };\n" else text += "class signal<#{template_args}>: public signal#{i}<#{template_args}> { /* empty class */ };\n" end diff --git a/signal.h b/signal.h index 6228148..fb8a9bd 100644 --- a/signal.h +++ b/signal.h @@ -1,1517 +1,1517 @@ -#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 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__ +#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__