diff --git a/generate.rb b/generate.rb new file mode 100644 index 0000000..6f651d8 --- /dev/null +++ b/generate.rb @@ -0,0 +1,30 @@ +#!/usr/bin/env ruby + +############################################################## +# script to generate signal*.h files from signal_template.h +############################################################## + +def make_header_file(nargs) + # hash to store our substitutions in + subs = {} + + # create subst strings for template and function arguments (template args follow T_return, so start with a comma) + subs["===NARG==="] = nargs.to_s + subs["===TEMPLATE_ARG_DECL==="] = (nargs > 0 ? ", ":"") + nargs.times.map { |i| "typename T_arg#{i}" }.join(", ") + subs["===TEMPLATE_ARG==="] = (nargs > 0 ? ", ":"") + nargs.times.map { |i| "T_arg#{i}" }.join(", ") + subs["===FORMAL_ARG_DECL==="] = nargs.times.map { |i| "T_arg#{i} a#{i}" }.join(", ") + subs["===FORMAL_ARG==="] = nargs.times.map { |i| "a#{i}" }.join(", ") + + # load template file + text = IO.read("signal_template.h") + + # do substitutions + subs.each { |k,v| text.gsub!(k,v) } + + # write output file + File.open("signal#{nargs}.h","w") { |f| f.write(text) } +end + +# generate [signal0.h,signal16.h] +(0..16).each { |i| make_header_file(i) } + diff --git a/signal.h b/signal.h index 4870dd1..6cea138 100644 --- a/signal.h +++ b/signal.h @@ -1,5 +1,5 @@ -#ifndef __Signal_h__ -#define __Signal_h__ +#ifndef __signal_h__ +#define __signal_h__ @@ -26,109 +26,106 @@ struct nilarg; template -class Signal : - public Signal16 +class signal : + public signal16 { }; template -class Signal : - public Signal15 +class signal : + public signal15 { }; template -class Signal : - public Signal14 +class signal : + public signal14 { }; template -class Signal : - public Signal13 +class signal : + public signal13 { }; template -class Signal : - public Signal12 +class signal : + public signal12 { }; template -class Signal : - public Signal11 +class signal : + public signal11 { }; template -class Signal : - public Signal10 +class signal : + public signal10 { }; template -class Signal : - public Signal9 +class signal : + public signal9 { }; template -class Signal : - public Signal8 +class signal : + public signal8 { }; template -class Signal : - public Signal7 +class signal : + public signal7 { }; template -class Signal : - public Signal6 +class signal : + public signal6 { }; template -class Signal : - public Signal5 +class signal : + public signal5 { }; template -class Signal : - public Signal4 +class signal : + public signal4 { }; template -class Signal : - public Signal3 +class signal : + public signal3 { }; template -class Signal : - public Signal2 +class signal : + public signal2 { }; template -class Signal : - public Signal1 +class signal : + public signal1 { }; template -class Signal : - public Signal0 +class signal : + public signal0 { }; -#include "signal/FixedArgSlot.h" - - -#endif // __Signal_h__ +#endif // __signal_h__ diff --git a/signal.pl b/signal.pl deleted file mode 100644 index 7714241..0000000 --- a/signal.pl +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/perl - -############################################################## -# script to generate signal*.h files from signal_template.h -############################################################## - - -############################################## -# -# globals -# -############################################## - -# a variable to store our template text in -my $template = ""; - - -############################################## -# -# main() -# -############################################## - -# load template text (see bottom of script) -open(INFILE,") -{ - $template .= $_; -} -close(INFILE); - -# generate [signal0.h,signal16.h] -for (my $i=0;$i<=16;$i++) -{ - GenerateSignalXHeader($i); -} - - -############################################## -# -# Subroutines -# -############################################## - -# subroutine to generate one signal header file -sub GenerateSignalXHeader -{ - # only argument is number of template arguments to allow for this signal - my($nargs) = @_; - - # create a local copy of template text - my $file = $template; - - # create other substitution strings - my $narg_str = ""; - my $template_arg_decl_str = ""; - my $template_arg_str = ""; - my $formal_arg_decl_str = ""; - my $formal_arg_str = ""; - - # create subst string for # of args - $narg_str = sprintf("%d",$nargs); - - # create subst strings for template and function arguments - if ( $nargs > 0 ) - { - # template args follow T_return, so start with a comma - $template_arg_decl_str = ", "; - $template_arg_str = ", "; - - for (my $i=0;$i<($nargs-1);$i++) - { - # args with trailing comma - $template_arg_decl_str .= sprintf("typename T_arg%d, ",$i); - $template_arg_str .= sprintf("T_arg%d, ",$i); - $formal_arg_decl_str .= sprintf("T_arg%d a%d, ",$i,$i); - $formal_arg_str .= sprintf("a%d, ",$i); - } - - # args without trailing comma - $template_arg_decl_str .= sprintf("typename T_arg%d",$nargs-1); - $template_arg_str .= sprintf("T_arg%d",$nargs-1); - $formal_arg_decl_str .= sprintf("T_arg%d a%d",$nargs-1,$nargs-1); - $formal_arg_str .= sprintf("a%d",$nargs-1); - } - - # do substitution - $file =~ s/===NARG===/$narg_str/g; - $file =~ s/===TEMPLATE_ARG_DECL===/$template_arg_decl_str/g; - $file =~ s/===TEMPLATE_ARG===/$template_arg_str/g; - $file =~ s/===FORMAL_ARG_DECL===/$formal_arg_decl_str/g; - $file =~ s/===FORMAL_ARG===/$formal_arg_str/g; - - # create filename - my $filename = sprintf("signal%d.h",$nargs); - - # write file - open(OUTFILE,">$filename") || die; - print OUTFILE $file; - close(OUTFILE); -} - diff --git a/signal0.h b/signal0.h index ec66e33..09452de 100644 --- a/signal0.h +++ b/signal0.h @@ -1,20 +1,21 @@ - -#ifndef __Signal0_h__ -#define __Signal0_h__ +#ifndef __signal0_h__ +#define __signal0_h__ #include "horrible_cast.h" #include "slot_base.h" #include "signal_base.h" -//========================================================================================================================================= -// Slot tempplate. -//========================================================================================================================================= -/** - * Abstract base class for Slots with 0 parameter(s). - */ + +// +// classes slot0, slot0_function, and slot0_method +// + +// +// Abstract base class for slots with 0 parameter(s). +// template -class Slot0 : public slot_base +class slot0 : public slot_base { public: /** @@ -25,23 +26,34 @@ class Slot0 : public slot_base virtual T_return operator() () const = 0; }; - // -// a concrete Slot class for a normal function +// A concrete slot class for a normal function. // template -class Slot0_function: public Slot0 +class slot0_function: public slot0 { public: - typedef T_return (*FUNCTION_POINTER)(); + typedef T_return (*FUNCTION_POINTER)(); // convenience typedef - Slot0_function( const FUNCTION_POINTER func ) + /** + * 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 @@ -52,22 +64,33 @@ class Slot0_function: public Slot0 } }; - // -// a concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method') +// A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method'). // template -class Slot0_method: public Slot0 +class slot0_method: public slot0 { public: - Slot0_method(const T_object* p_object, const T_member p_member) + /** + * 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 @@ -79,103 +102,113 @@ class Slot0_method: public Slot0 } }; -//========================================================================================================================================= -// Signal tempplate. -//========================================================================================================================================= + + +// +// class signal0 +// template< typename T_return > -class Signal0: public signal_base +class signal0: public signal_base { public: - //----------------------------------------------------------------------------------------------------------------------------------------- - // Execute the Signal: - // - Walk the list of Slot nodes. - //----------------------------------------------------------------------------------------------------------------------------------------- + /** + * Emit the signal. + * + * Iterate through the list of slots, and call each one. + */ void operator() () { - if( IsSignalEmitting( ) ) + // 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); + printf("WARNING: signal0<...> @ 0x%p recursive emit attempt\n", this); #endif return; } - BeginEmit( ); - - list_node* cur = GetFirstNode( ); + // set emitting flag + signal_base::emitting = true; // iterate through the list + signal_base::list_node* cur = signal_base::head; while( cur ) { - // make the slot_base pointer a Slot0 pointer - Slot0* s = static_cast*>(cur->slot); + // 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 - (*s)(); + // call the signal as long as it's still valid + if ( !cur->deleted ) + { + (*s)(); + } - // move to next Slot in the list. + // move to next slot in the list. cur = cur->next; } - EndEmit( ); + // delete any pending slot deletions + signal_base::remove_pending_nodes( ); + + // clear emitting flag + signal_base::emitting = false; } - //========================================================================================================================================= - // Signal connections - //========================================================================================================================================= + + // + // signal connections to slots + // + + // convenience typedef typedef T_return (*FUNCTION_POINTER)(); - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // 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 ); + // 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 bind(sNewFunc); + return signal_base::bind(sNewFunc); } - // Object methods - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 ); + // 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 bind(sNewMethod); + return signal_base::bind(sNewMethod); } - //========================================================================================================================================= - // Signal Disconnections - //========================================================================================================================================= - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // + // 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 ); + // make a temporary slot we can use to find a match in the list + slot0_function sTest( func ); // search and remove it - return unbind(&sTest); + return signal_base::unbind(&sTest); } - - // Object method - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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); + // 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 unbind(&sTemp); + return signal_base::unbind(&sTemp); } }; -#endif // __Signal0_h__ +#endif // __signal0_h__ diff --git a/signal1.h b/signal1.h index dbab0b3..b66d7a7 100644 --- a/signal1.h +++ b/signal1.h @@ -1,20 +1,21 @@ - -#ifndef __Signal1_h__ -#define __Signal1_h__ +#ifndef __signal1_h__ +#define __signal1_h__ #include "horrible_cast.h" #include "slot_base.h" #include "signal_base.h" -//========================================================================================================================================= -// Slot tempplate. -//========================================================================================================================================= -/** - * Abstract base class for Slots with 1 parameter(s). - */ + +// +// classes slot1, slot1_function, and slot1_method +// + +// +// Abstract base class for slots with 1 parameter(s). +// template -class Slot1 : public slot_base +class slot1 : public slot_base { public: /** @@ -25,23 +26,34 @@ class Slot1 : public slot_base virtual T_return operator() (T_arg0 a0) const = 0; }; - // -// a concrete Slot class for a normal function +// A concrete slot class for a normal function. // template -class Slot1_function: public Slot1 +class slot1_function: public slot1 { public: - typedef T_return (*FUNCTION_POINTER)(T_arg0 a0); + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0); // convenience typedef - Slot1_function( const FUNCTION_POINTER func ) + /** + * 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 @@ -52,22 +64,33 @@ class Slot1_function: public Slot1 } }; - // -// a concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method') +// A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method'). // template -class Slot1_method: public Slot1 +class slot1_method: public slot1 { public: - Slot1_method(const T_object* p_object, const T_member p_member) + /** + * 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 @@ -79,103 +102,113 @@ class Slot1_method: public Slot1 } }; -//========================================================================================================================================= -// Signal tempplate. -//========================================================================================================================================= + + +// +// class signal1 +// template< typename T_return, typename T_arg0 > -class Signal1: public signal_base +class signal1: public signal_base { public: - //----------------------------------------------------------------------------------------------------------------------------------------- - // Execute the Signal: - // - Walk the list of Slot nodes. - //----------------------------------------------------------------------------------------------------------------------------------------- + /** + * Emit the signal. + * + * Iterate through the list of slots, and call each one. + */ void operator() (T_arg0 a0) { - if( IsSignalEmitting( ) ) + // 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); + printf("WARNING: signal1<...> @ 0x%p recursive emit attempt\n", this); #endif return; } - BeginEmit( ); - - list_node* cur = GetFirstNode( ); + // set emitting flag + signal_base::emitting = true; // iterate through the list + signal_base::list_node* cur = signal_base::head; while( cur ) { - // make the slot_base pointer a Slot1 pointer - Slot1* s = static_cast*>(cur->slot); + // 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 - (*s)(a0); + // call the signal as long as it's still valid + if ( !cur->deleted ) + { + (*s)(a0); + } - // move to next Slot in the list. + // move to next slot in the list. cur = cur->next; } - EndEmit( ); + // delete any pending slot deletions + signal_base::remove_pending_nodes( ); + + // clear emitting flag + signal_base::emitting = false; } - //========================================================================================================================================= - // Signal connections - //========================================================================================================================================= + + // + // signal connections to slots + // + + // convenience typedef typedef T_return (*FUNCTION_POINTER)(T_arg0 a0); - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // 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 ); + // 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 bind(sNewFunc); + return signal_base::bind(sNewFunc); } - // Object methods - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 ); + // 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 bind(sNewMethod); + return signal_base::bind(sNewMethod); } - //========================================================================================================================================= - // Signal Disconnections - //========================================================================================================================================= - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // + // 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 ); + // make a temporary slot we can use to find a match in the list + slot1_function sTest( func ); // search and remove it - return unbind(&sTest); + return signal_base::unbind(&sTest); } - - // Object method - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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); + // 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 unbind(&sTemp); + return signal_base::unbind(&sTemp); } }; -#endif // __Signal1_h__ +#endif // __signal1_h__ diff --git a/signal10.h b/signal10.h index 239251f..fcfc1c2 100644 --- a/signal10.h +++ b/signal10.h @@ -1,20 +1,21 @@ - -#ifndef __Signal10_h__ -#define __Signal10_h__ +#ifndef __signal10_h__ +#define __signal10_h__ #include "horrible_cast.h" #include "slot_base.h" #include "signal_base.h" -//========================================================================================================================================= -// Slot tempplate. -//========================================================================================================================================= -/** - * Abstract base class for Slots with 10 parameter(s). - */ + +// +// classes slot10, slot10_function, and slot10_method +// + +// +// Abstract base class for slots with 10 parameter(s). +// template -class Slot10 : public slot_base +class slot10 : public slot_base { public: /** @@ -25,23 +26,34 @@ class Slot10 : public slot_base virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9) const = 0; }; - // -// a concrete Slot class for a normal function +// A concrete slot class for a normal function. // template -class Slot10_function: public Slot10 +class slot10_function: public slot10 { public: - typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9); + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9); // convenience typedef - Slot10_function( const FUNCTION_POINTER func ) + /** + * Constructor. + * + * Converts a function pointer into raw data. + */ + slot10_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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9) const { // retrieve data from slot_base and convert back to a function pointer @@ -52,22 +64,33 @@ class Slot10_function: public Slot10 -class Slot10_method: public Slot10 +class slot10_method: public slot10 { public: - Slot10_method(const T_object* p_object, const T_member p_member) + /** + * Constructor. + * + * Converts an object and method pointer into raw data. + */ + slot10_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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9) const { // retrieve data from slot_base and convert back to an object pointer and member function pointer @@ -79,103 +102,113 @@ class Slot10_method: public Slot10 -class Signal10: public signal_base +class signal10: public signal_base { public: - //----------------------------------------------------------------------------------------------------------------------------------------- - // Execute the Signal: - // - Walk the list of Slot nodes. - //----------------------------------------------------------------------------------------------------------------------------------------- + /** + * 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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9) { - if( IsSignalEmitting( ) ) + // if we're already emitting, return (i.e. no re-entrancy allowed) + if( signal_base::emitting ) { #if defined( _DEBUG ) - printf("WARNING: Signal10<...> @ 0x%p recursive Emit attempt\n", this); + printf("WARNING: signal10<...> @ 0x%p recursive emit attempt\n", this); #endif return; } - BeginEmit( ); - - list_node* cur = GetFirstNode( ); + // set emitting flag + signal_base::emitting = true; // iterate through the list + signal_base::list_node* cur = signal_base::head; while( cur ) { - // make the slot_base pointer a Slot10 pointer - Slot10* s = static_cast*>(cur->slot); + // cast the slot_base pointer to a slot10 pointer (converts from raw memory to pointer again) + slot10* s = static_cast*>(cur->slot); - // call the Signal - (*s)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); + // call the signal as long as it's still valid + if ( !cur->deleted ) + { + (*s)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); + } - // move to next Slot in the list. + // move to next slot in the list. cur = cur->next; } - EndEmit( ); + // delete any pending slot deletions + signal_base::remove_pending_nodes( ); + + // clear emitting flag + signal_base::emitting = false; } - //========================================================================================================================================= - // Signal connections - //========================================================================================================================================= + + // + // 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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9); - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // connect to normal functions bool Connect( FUNCTION_POINTER func ) { - // make a copy of the Slot to store in our list - Slot10* sNewFunc = new Slot10_function( func ); + // make a copy of the slot to store in our list + slot10* sNewFunc = new slot10_function( func ); // add it to the end of our linked list - return bind(sNewFunc); + return signal_base::bind(sNewFunc); } - // Object methods - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 - Slot10* sNewMethod = new Slot10_method( p_object, p_member ); + // make a copy of the slot to store in our list + slot10* sNewMethod = new slot10_method( p_object, p_member ); // add it to the end of our linked list - return bind(sNewMethod); + return signal_base::bind(sNewMethod); } - //========================================================================================================================================= - // Signal Disconnections - //========================================================================================================================================= - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // + // 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 - Slot10_function sTest( func ); + // make a temporary slot we can use to find a match in the list + slot10_function sTest( func ); // search and remove it - return unbind(&sTest); + return signal_base::unbind(&sTest); } - - // Object method - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 - Slot10_method sTemp(p_object,p_member); + // make a temporary slot we can use to find a match in the list + slot10_method sTemp(p_object,p_member); // search and remove it - return unbind(&sTemp); + return signal_base::unbind(&sTemp); } }; -#endif // __Signal10_h__ +#endif // __signal10_h__ diff --git a/signal11.h b/signal11.h index 02a2d57..dbb446a 100644 --- a/signal11.h +++ b/signal11.h @@ -1,20 +1,21 @@ - -#ifndef __Signal11_h__ -#define __Signal11_h__ +#ifndef __signal11_h__ +#define __signal11_h__ #include "horrible_cast.h" #include "slot_base.h" #include "signal_base.h" -//========================================================================================================================================= -// Slot tempplate. -//========================================================================================================================================= -/** - * Abstract base class for Slots with 11 parameter(s). - */ + +// +// classes slot11, slot11_function, and slot11_method +// + +// +// Abstract base class for slots with 11 parameter(s). +// template -class Slot11 : public slot_base +class slot11 : public slot_base { public: /** @@ -25,23 +26,34 @@ class Slot11 : public slot_base virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10) const = 0; }; - // -// a concrete Slot class for a normal function +// A concrete slot class for a normal function. // template -class Slot11_function: public Slot11 +class slot11_function: public slot11 { public: - typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10); + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10); // convenience typedef - Slot11_function( const FUNCTION_POINTER func ) + /** + * Constructor. + * + * Converts a function pointer into raw data. + */ + slot11_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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10) const { // retrieve data from slot_base and convert back to a function pointer @@ -52,22 +64,33 @@ class Slot11_function: public Slot11 -class Slot11_method: public Slot11 +class slot11_method: public slot11 { public: - Slot11_method(const T_object* p_object, const T_member p_member) + /** + * Constructor. + * + * Converts an object and method pointer into raw data. + */ + slot11_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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10) const { // retrieve data from slot_base and convert back to an object pointer and member function pointer @@ -79,103 +102,113 @@ class Slot11_method: public Slot11 -class Signal11: public signal_base +class signal11: public signal_base { public: - //----------------------------------------------------------------------------------------------------------------------------------------- - // Execute the Signal: - // - Walk the list of Slot nodes. - //----------------------------------------------------------------------------------------------------------------------------------------- + /** + * 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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10) { - if( IsSignalEmitting( ) ) + // if we're already emitting, return (i.e. no re-entrancy allowed) + if( signal_base::emitting ) { #if defined( _DEBUG ) - printf("WARNING: Signal11<...> @ 0x%p recursive Emit attempt\n", this); + printf("WARNING: signal11<...> @ 0x%p recursive emit attempt\n", this); #endif return; } - BeginEmit( ); - - list_node* cur = GetFirstNode( ); + // set emitting flag + signal_base::emitting = true; // iterate through the list + signal_base::list_node* cur = signal_base::head; while( cur ) { - // make the slot_base pointer a Slot11 pointer - Slot11* s = static_cast*>(cur->slot); + // cast the slot_base pointer to a slot11 pointer (converts from raw memory to pointer again) + slot11* s = static_cast*>(cur->slot); - // call the Signal - (*s)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); + // call the signal as long as it's still valid + if ( !cur->deleted ) + { + (*s)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); + } - // move to next Slot in the list. + // move to next slot in the list. cur = cur->next; } - EndEmit( ); + // delete any pending slot deletions + signal_base::remove_pending_nodes( ); + + // clear emitting flag + signal_base::emitting = false; } - //========================================================================================================================================= - // Signal connections - //========================================================================================================================================= + + // + // 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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10); - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // connect to normal functions bool Connect( FUNCTION_POINTER func ) { - // make a copy of the Slot to store in our list - Slot11* sNewFunc = new Slot11_function( func ); + // make a copy of the slot to store in our list + slot11* sNewFunc = new slot11_function( func ); // add it to the end of our linked list - return bind(sNewFunc); + return signal_base::bind(sNewFunc); } - // Object methods - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 - Slot11* sNewMethod = new Slot11_method( p_object, p_member ); + // make a copy of the slot to store in our list + slot11* sNewMethod = new slot11_method( p_object, p_member ); // add it to the end of our linked list - return bind(sNewMethod); + return signal_base::bind(sNewMethod); } - //========================================================================================================================================= - // Signal Disconnections - //========================================================================================================================================= - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // + // 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 - Slot11_function sTest( func ); + // make a temporary slot we can use to find a match in the list + slot11_function sTest( func ); // search and remove it - return unbind(&sTest); + return signal_base::unbind(&sTest); } - - // Object method - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 - Slot11_method sTemp(p_object,p_member); + // make a temporary slot we can use to find a match in the list + slot11_method sTemp(p_object,p_member); // search and remove it - return unbind(&sTemp); + return signal_base::unbind(&sTemp); } }; -#endif // __Signal11_h__ +#endif // __signal11_h__ diff --git a/signal12.h b/signal12.h index e41aa3d..170f2d2 100644 --- a/signal12.h +++ b/signal12.h @@ -1,20 +1,21 @@ - -#ifndef __Signal12_h__ -#define __Signal12_h__ +#ifndef __signal12_h__ +#define __signal12_h__ #include "horrible_cast.h" #include "slot_base.h" #include "signal_base.h" -//========================================================================================================================================= -// Slot tempplate. -//========================================================================================================================================= -/** - * Abstract base class for Slots with 12 parameter(s). - */ + +// +// classes slot12, slot12_function, and slot12_method +// + +// +// Abstract base class for slots with 12 parameter(s). +// template -class Slot12 : public slot_base +class slot12 : public slot_base { public: /** @@ -25,23 +26,34 @@ class Slot12 : public slot_base virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11) const = 0; }; - // -// a concrete Slot class for a normal function +// A concrete slot class for a normal function. // template -class Slot12_function: public Slot12 +class slot12_function: public slot12 { public: - typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11); + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11); // convenience typedef - Slot12_function( const FUNCTION_POINTER func ) + /** + * Constructor. + * + * Converts a function pointer into raw data. + */ + slot12_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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11) const { // retrieve data from slot_base and convert back to a function pointer @@ -52,22 +64,33 @@ class Slot12_function: public Slot12 -class Slot12_method: public Slot12 +class slot12_method: public slot12 { public: - Slot12_method(const T_object* p_object, const T_member p_member) + /** + * Constructor. + * + * Converts an object and method pointer into raw data. + */ + slot12_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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11) const { // retrieve data from slot_base and convert back to an object pointer and member function pointer @@ -79,103 +102,113 @@ class Slot12_method: public Slot12 -class Signal12: public signal_base +class signal12: public signal_base { public: - //----------------------------------------------------------------------------------------------------------------------------------------- - // Execute the Signal: - // - Walk the list of Slot nodes. - //----------------------------------------------------------------------------------------------------------------------------------------- + /** + * 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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11) { - if( IsSignalEmitting( ) ) + // if we're already emitting, return (i.e. no re-entrancy allowed) + if( signal_base::emitting ) { #if defined( _DEBUG ) - printf("WARNING: Signal12<...> @ 0x%p recursive Emit attempt\n", this); + printf("WARNING: signal12<...> @ 0x%p recursive emit attempt\n", this); #endif return; } - BeginEmit( ); - - list_node* cur = GetFirstNode( ); + // set emitting flag + signal_base::emitting = true; // iterate through the list + signal_base::list_node* cur = signal_base::head; while( cur ) { - // make the slot_base pointer a Slot12 pointer - Slot12* s = static_cast*>(cur->slot); + // cast the slot_base pointer to a slot12 pointer (converts from raw memory to pointer again) + slot12* s = static_cast*>(cur->slot); - // call the Signal - (*s)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); + // call the signal as long as it's still valid + if ( !cur->deleted ) + { + (*s)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); + } - // move to next Slot in the list. + // move to next slot in the list. cur = cur->next; } - EndEmit( ); + // delete any pending slot deletions + signal_base::remove_pending_nodes( ); + + // clear emitting flag + signal_base::emitting = false; } - //========================================================================================================================================= - // Signal connections - //========================================================================================================================================= + + // + // 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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11); - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // connect to normal functions bool Connect( FUNCTION_POINTER func ) { - // make a copy of the Slot to store in our list - Slot12* sNewFunc = new Slot12_function( func ); + // make a copy of the slot to store in our list + slot12* sNewFunc = new slot12_function( func ); // add it to the end of our linked list - return bind(sNewFunc); + return signal_base::bind(sNewFunc); } - // Object methods - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 - Slot12* sNewMethod = new Slot12_method( p_object, p_member ); + // make a copy of the slot to store in our list + slot12* sNewMethod = new slot12_method( p_object, p_member ); // add it to the end of our linked list - return bind(sNewMethod); + return signal_base::bind(sNewMethod); } - //========================================================================================================================================= - // Signal Disconnections - //========================================================================================================================================= - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // + // 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 - Slot12_function sTest( func ); + // make a temporary slot we can use to find a match in the list + slot12_function sTest( func ); // search and remove it - return unbind(&sTest); + return signal_base::unbind(&sTest); } - - // Object method - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 - Slot12_method sTemp(p_object,p_member); + // make a temporary slot we can use to find a match in the list + slot12_method sTemp(p_object,p_member); // search and remove it - return unbind(&sTemp); + return signal_base::unbind(&sTemp); } }; -#endif // __Signal12_h__ +#endif // __signal12_h__ diff --git a/signal13.h b/signal13.h index a034cc4..5620fc1 100644 --- a/signal13.h +++ b/signal13.h @@ -1,20 +1,21 @@ - -#ifndef __Signal13_h__ -#define __Signal13_h__ +#ifndef __signal13_h__ +#define __signal13_h__ #include "horrible_cast.h" #include "slot_base.h" #include "signal_base.h" -//========================================================================================================================================= -// Slot tempplate. -//========================================================================================================================================= -/** - * Abstract base class for Slots with 13 parameter(s). - */ + +// +// classes slot13, slot13_function, and slot13_method +// + +// +// Abstract base class for slots with 13 parameter(s). +// template -class Slot13 : public slot_base +class slot13 : public slot_base { public: /** @@ -25,23 +26,34 @@ class Slot13 : public slot_base virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12) const = 0; }; - // -// a concrete Slot class for a normal function +// A concrete slot class for a normal function. // template -class Slot13_function: public Slot13 +class slot13_function: public slot13 { public: - typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12); + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12); // convenience typedef - Slot13_function( const FUNCTION_POINTER func ) + /** + * Constructor. + * + * Converts a function pointer into raw data. + */ + slot13_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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12) const { // retrieve data from slot_base and convert back to a function pointer @@ -52,22 +64,33 @@ class Slot13_function: public Slot13 -class Slot13_method: public Slot13 +class slot13_method: public slot13 { public: - Slot13_method(const T_object* p_object, const T_member p_member) + /** + * Constructor. + * + * Converts an object and method pointer into raw data. + */ + slot13_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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12) const { // retrieve data from slot_base and convert back to an object pointer and member function pointer @@ -79,103 +102,113 @@ class Slot13_method: public Slot13 -class Signal13: public signal_base +class signal13: public signal_base { public: - //----------------------------------------------------------------------------------------------------------------------------------------- - // Execute the Signal: - // - Walk the list of Slot nodes. - //----------------------------------------------------------------------------------------------------------------------------------------- + /** + * 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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12) { - if( IsSignalEmitting( ) ) + // if we're already emitting, return (i.e. no re-entrancy allowed) + if( signal_base::emitting ) { #if defined( _DEBUG ) - printf("WARNING: Signal13<...> @ 0x%p recursive Emit attempt\n", this); + printf("WARNING: signal13<...> @ 0x%p recursive emit attempt\n", this); #endif return; } - BeginEmit( ); - - list_node* cur = GetFirstNode( ); + // set emitting flag + signal_base::emitting = true; // iterate through the list + signal_base::list_node* cur = signal_base::head; while( cur ) { - // make the slot_base pointer a Slot13 pointer - Slot13* s = static_cast*>(cur->slot); + // cast the slot_base pointer to a slot13 pointer (converts from raw memory to pointer again) + slot13* s = static_cast*>(cur->slot); - // call the Signal - (*s)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); + // call the signal as long as it's still valid + if ( !cur->deleted ) + { + (*s)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); + } - // move to next Slot in the list. + // move to next slot in the list. cur = cur->next; } - EndEmit( ); + // delete any pending slot deletions + signal_base::remove_pending_nodes( ); + + // clear emitting flag + signal_base::emitting = false; } - //========================================================================================================================================= - // Signal connections - //========================================================================================================================================= + + // + // 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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12); - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // connect to normal functions bool Connect( FUNCTION_POINTER func ) { - // make a copy of the Slot to store in our list - Slot13* sNewFunc = new Slot13_function( func ); + // make a copy of the slot to store in our list + slot13* sNewFunc = new slot13_function( func ); // add it to the end of our linked list - return bind(sNewFunc); + return signal_base::bind(sNewFunc); } - // Object methods - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 - Slot13* sNewMethod = new Slot13_method( p_object, p_member ); + // make a copy of the slot to store in our list + slot13* sNewMethod = new slot13_method( p_object, p_member ); // add it to the end of our linked list - return bind(sNewMethod); + return signal_base::bind(sNewMethod); } - //========================================================================================================================================= - // Signal Disconnections - //========================================================================================================================================= - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // + // 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 - Slot13_function sTest( func ); + // make a temporary slot we can use to find a match in the list + slot13_function sTest( func ); // search and remove it - return unbind(&sTest); + return signal_base::unbind(&sTest); } - - // Object method - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 - Slot13_method sTemp(p_object,p_member); + // make a temporary slot we can use to find a match in the list + slot13_method sTemp(p_object,p_member); // search and remove it - return unbind(&sTemp); + return signal_base::unbind(&sTemp); } }; -#endif // __Signal13_h__ +#endif // __signal13_h__ diff --git a/signal14.h b/signal14.h index 1dc5785..1008664 100644 --- a/signal14.h +++ b/signal14.h @@ -1,20 +1,21 @@ - -#ifndef __Signal14_h__ -#define __Signal14_h__ +#ifndef __signal14_h__ +#define __signal14_h__ #include "horrible_cast.h" #include "slot_base.h" #include "signal_base.h" -//========================================================================================================================================= -// Slot tempplate. -//========================================================================================================================================= -/** - * Abstract base class for Slots with 14 parameter(s). - */ + +// +// classes slot14, slot14_function, and slot14_method +// + +// +// Abstract base class for slots with 14 parameter(s). +// template -class Slot14 : public slot_base +class slot14 : public slot_base { public: /** @@ -25,23 +26,34 @@ class Slot14 : public slot_base virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13) const = 0; }; - // -// a concrete Slot class for a normal function +// A concrete slot class for a normal function. // template -class Slot14_function: public Slot14 +class slot14_function: public slot14 { public: - typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13); + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13); // convenience typedef - Slot14_function( const FUNCTION_POINTER func ) + /** + * Constructor. + * + * Converts a function pointer into raw data. + */ + slot14_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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13) const { // retrieve data from slot_base and convert back to a function pointer @@ -52,22 +64,33 @@ class Slot14_function: public Slot14 -class Slot14_method: public Slot14 +class slot14_method: public slot14 { public: - Slot14_method(const T_object* p_object, const T_member p_member) + /** + * Constructor. + * + * Converts an object and method pointer into raw data. + */ + slot14_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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13) const { // retrieve data from slot_base and convert back to an object pointer and member function pointer @@ -79,103 +102,113 @@ class Slot14_method: public Slot14 -class Signal14: public signal_base +class signal14: public signal_base { public: - //----------------------------------------------------------------------------------------------------------------------------------------- - // Execute the Signal: - // - Walk the list of Slot nodes. - //----------------------------------------------------------------------------------------------------------------------------------------- + /** + * 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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13) { - if( IsSignalEmitting( ) ) + // if we're already emitting, return (i.e. no re-entrancy allowed) + if( signal_base::emitting ) { #if defined( _DEBUG ) - printf("WARNING: Signal14<...> @ 0x%p recursive Emit attempt\n", this); + printf("WARNING: signal14<...> @ 0x%p recursive emit attempt\n", this); #endif return; } - BeginEmit( ); - - list_node* cur = GetFirstNode( ); + // set emitting flag + signal_base::emitting = true; // iterate through the list + signal_base::list_node* cur = signal_base::head; while( cur ) { - // make the slot_base pointer a Slot14 pointer - Slot14* s = static_cast*>(cur->slot); + // cast the slot_base pointer to a slot14 pointer (converts from raw memory to pointer again) + slot14* s = static_cast*>(cur->slot); - // call the Signal - (*s)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); + // call the signal as long as it's still valid + if ( !cur->deleted ) + { + (*s)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); + } - // move to next Slot in the list. + // move to next slot in the list. cur = cur->next; } - EndEmit( ); + // delete any pending slot deletions + signal_base::remove_pending_nodes( ); + + // clear emitting flag + signal_base::emitting = false; } - //========================================================================================================================================= - // Signal connections - //========================================================================================================================================= + + // + // 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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13); - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // connect to normal functions bool Connect( FUNCTION_POINTER func ) { - // make a copy of the Slot to store in our list - Slot14* sNewFunc = new Slot14_function( func ); + // make a copy of the slot to store in our list + slot14* sNewFunc = new slot14_function( func ); // add it to the end of our linked list - return bind(sNewFunc); + return signal_base::bind(sNewFunc); } - // Object methods - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 - Slot14* sNewMethod = new Slot14_method( p_object, p_member ); + // make a copy of the slot to store in our list + slot14* sNewMethod = new slot14_method( p_object, p_member ); // add it to the end of our linked list - return bind(sNewMethod); + return signal_base::bind(sNewMethod); } - //========================================================================================================================================= - // Signal Disconnections - //========================================================================================================================================= - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // + // 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 - Slot14_function sTest( func ); + // make a temporary slot we can use to find a match in the list + slot14_function sTest( func ); // search and remove it - return unbind(&sTest); + return signal_base::unbind(&sTest); } - - // Object method - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 - Slot14_method sTemp(p_object,p_member); + // make a temporary slot we can use to find a match in the list + slot14_method sTemp(p_object,p_member); // search and remove it - return unbind(&sTemp); + return signal_base::unbind(&sTemp); } }; -#endif // __Signal14_h__ +#endif // __signal14_h__ diff --git a/signal15.h b/signal15.h index c65f40f..4d6b8ab 100644 --- a/signal15.h +++ b/signal15.h @@ -1,20 +1,21 @@ - -#ifndef __Signal15_h__ -#define __Signal15_h__ +#ifndef __signal15_h__ +#define __signal15_h__ #include "horrible_cast.h" #include "slot_base.h" #include "signal_base.h" -//========================================================================================================================================= -// Slot tempplate. -//========================================================================================================================================= -/** - * Abstract base class for Slots with 15 parameter(s). - */ + +// +// classes slot15, slot15_function, and slot15_method +// + +// +// Abstract base class for slots with 15 parameter(s). +// template -class Slot15 : public slot_base +class slot15 : public slot_base { public: /** @@ -25,23 +26,34 @@ class Slot15 : public slot_base virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13, T_arg14 a14) const = 0; }; - // -// a concrete Slot class for a normal function +// A concrete slot class for a normal function. // template -class Slot15_function: public Slot15 +class slot15_function: public slot15 { public: - typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13, T_arg14 a14); + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13, T_arg14 a14); // convenience typedef - Slot15_function( const FUNCTION_POINTER func ) + /** + * Constructor. + * + * Converts a function pointer into raw data. + */ + slot15_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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13, T_arg14 a14) const { // retrieve data from slot_base and convert back to a function pointer @@ -52,22 +64,33 @@ class Slot15_function: public Slot15 -class Slot15_method: public Slot15 +class slot15_method: public slot15 { public: - Slot15_method(const T_object* p_object, const T_member p_member) + /** + * Constructor. + * + * Converts an object and method pointer into raw data. + */ + slot15_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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13, T_arg14 a14) const { // retrieve data from slot_base and convert back to an object pointer and member function pointer @@ -79,103 +102,113 @@ class Slot15_method: public Slot15 -class Signal15: public signal_base +class signal15: public signal_base { public: - //----------------------------------------------------------------------------------------------------------------------------------------- - // Execute the Signal: - // - Walk the list of Slot nodes. - //----------------------------------------------------------------------------------------------------------------------------------------- + /** + * 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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13, T_arg14 a14) { - if( IsSignalEmitting( ) ) + // if we're already emitting, return (i.e. no re-entrancy allowed) + if( signal_base::emitting ) { #if defined( _DEBUG ) - printf("WARNING: Signal15<...> @ 0x%p recursive Emit attempt\n", this); + printf("WARNING: signal15<...> @ 0x%p recursive emit attempt\n", this); #endif return; } - BeginEmit( ); - - list_node* cur = GetFirstNode( ); + // set emitting flag + signal_base::emitting = true; // iterate through the list + signal_base::list_node* cur = signal_base::head; while( cur ) { - // make the slot_base pointer a Slot15 pointer - Slot15* s = static_cast*>(cur->slot); + // cast the slot_base pointer to a slot15 pointer (converts from raw memory to pointer again) + slot15* s = static_cast*>(cur->slot); - // call the Signal - (*s)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); + // call the signal as long as it's still valid + if ( !cur->deleted ) + { + (*s)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); + } - // move to next Slot in the list. + // move to next slot in the list. cur = cur->next; } - EndEmit( ); + // delete any pending slot deletions + signal_base::remove_pending_nodes( ); + + // clear emitting flag + signal_base::emitting = false; } - //========================================================================================================================================= - // Signal connections - //========================================================================================================================================= + + // + // 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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13, T_arg14 a14); - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // connect to normal functions bool Connect( FUNCTION_POINTER func ) { - // make a copy of the Slot to store in our list - Slot15* sNewFunc = new Slot15_function( func ); + // make a copy of the slot to store in our list + slot15* sNewFunc = new slot15_function( func ); // add it to the end of our linked list - return bind(sNewFunc); + return signal_base::bind(sNewFunc); } - // Object methods - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 - Slot15* sNewMethod = new Slot15_method( p_object, p_member ); + // make a copy of the slot to store in our list + slot15* sNewMethod = new slot15_method( p_object, p_member ); // add it to the end of our linked list - return bind(sNewMethod); + return signal_base::bind(sNewMethod); } - //========================================================================================================================================= - // Signal Disconnections - //========================================================================================================================================= - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // + // 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 - Slot15_function sTest( func ); + // make a temporary slot we can use to find a match in the list + slot15_function sTest( func ); // search and remove it - return unbind(&sTest); + return signal_base::unbind(&sTest); } - - // Object method - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 - Slot15_method sTemp(p_object,p_member); + // make a temporary slot we can use to find a match in the list + slot15_method sTemp(p_object,p_member); // search and remove it - return unbind(&sTemp); + return signal_base::unbind(&sTemp); } }; -#endif // __Signal15_h__ +#endif // __signal15_h__ diff --git a/signal16.h b/signal16.h index bec9829..f212354 100644 --- a/signal16.h +++ b/signal16.h @@ -1,20 +1,21 @@ - -#ifndef __Signal16_h__ -#define __Signal16_h__ +#ifndef __signal16_h__ +#define __signal16_h__ #include "horrible_cast.h" #include "slot_base.h" #include "signal_base.h" -//========================================================================================================================================= -// Slot tempplate. -//========================================================================================================================================= -/** - * Abstract base class for Slots with 16 parameter(s). - */ + +// +// classes slot16, slot16_function, and slot16_method +// + +// +// Abstract base class for slots with 16 parameter(s). +// template -class Slot16 : public slot_base +class slot16 : public slot_base { public: /** @@ -25,23 +26,34 @@ class Slot16 : public slot_base virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13, T_arg14 a14, T_arg15 a15) const = 0; }; - // -// a concrete Slot class for a normal function +// A concrete slot class for a normal function. // template -class Slot16_function: public Slot16 +class slot16_function: public slot16 { public: - typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13, T_arg14 a14, T_arg15 a15); + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13, T_arg14 a14, T_arg15 a15); // convenience typedef - Slot16_function( const FUNCTION_POINTER func ) + /** + * Constructor. + * + * Converts a function pointer into raw data. + */ + slot16_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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13, T_arg14 a14, T_arg15 a15) const { // retrieve data from slot_base and convert back to a function pointer @@ -52,22 +64,33 @@ class Slot16_function: public Slot16 -class Slot16_method: public Slot16 +class slot16_method: public slot16 { public: - Slot16_method(const T_object* p_object, const T_member p_member) + /** + * Constructor. + * + * Converts an object and method pointer into raw data. + */ + slot16_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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13, T_arg14 a14, T_arg15 a15) const { // retrieve data from slot_base and convert back to an object pointer and member function pointer @@ -79,103 +102,113 @@ class Slot16_method: public Slot16 -class Signal16: public signal_base +class signal16: public signal_base { public: - //----------------------------------------------------------------------------------------------------------------------------------------- - // Execute the Signal: - // - Walk the list of Slot nodes. - //----------------------------------------------------------------------------------------------------------------------------------------- + /** + * 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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13, T_arg14 a14, T_arg15 a15) { - if( IsSignalEmitting( ) ) + // if we're already emitting, return (i.e. no re-entrancy allowed) + if( signal_base::emitting ) { #if defined( _DEBUG ) - printf("WARNING: Signal16<...> @ 0x%p recursive Emit attempt\n", this); + printf("WARNING: signal16<...> @ 0x%p recursive emit attempt\n", this); #endif return; } - BeginEmit( ); - - list_node* cur = GetFirstNode( ); + // set emitting flag + signal_base::emitting = true; // iterate through the list + signal_base::list_node* cur = signal_base::head; while( cur ) { - // make the slot_base pointer a Slot16 pointer - Slot16* s = static_cast*>(cur->slot); + // cast the slot_base pointer to a slot16 pointer (converts from raw memory to pointer again) + slot16* s = static_cast*>(cur->slot); - // call the Signal - (*s)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); + // call the signal as long as it's still valid + if ( !cur->deleted ) + { + (*s)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); + } - // move to next Slot in the list. + // move to next slot in the list. cur = cur->next; } - EndEmit( ); + // delete any pending slot deletions + signal_base::remove_pending_nodes( ); + + // clear emitting flag + signal_base::emitting = false; } - //========================================================================================================================================= - // Signal connections - //========================================================================================================================================= + + // + // 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, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13, T_arg14 a14, T_arg15 a15); - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // connect to normal functions bool Connect( FUNCTION_POINTER func ) { - // make a copy of the Slot to store in our list - Slot16* sNewFunc = new Slot16_function( func ); + // make a copy of the slot to store in our list + slot16* sNewFunc = new slot16_function( func ); // add it to the end of our linked list - return bind(sNewFunc); + return signal_base::bind(sNewFunc); } - // Object methods - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 - Slot16* sNewMethod = new Slot16_method( p_object, p_member ); + // make a copy of the slot to store in our list + slot16* sNewMethod = new slot16_method( p_object, p_member ); // add it to the end of our linked list - return bind(sNewMethod); + return signal_base::bind(sNewMethod); } - //========================================================================================================================================= - // Signal Disconnections - //========================================================================================================================================= - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // + // 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 - Slot16_function sTest( func ); + // make a temporary slot we can use to find a match in the list + slot16_function sTest( func ); // search and remove it - return unbind(&sTest); + return signal_base::unbind(&sTest); } - - // Object method - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 - Slot16_method sTemp(p_object,p_member); + // make a temporary slot we can use to find a match in the list + slot16_method sTemp(p_object,p_member); // search and remove it - return unbind(&sTemp); + return signal_base::unbind(&sTemp); } }; -#endif // __Signal16_h__ +#endif // __signal16_h__ diff --git a/signal2.h b/signal2.h index 4b6f068..fd3254c 100644 --- a/signal2.h +++ b/signal2.h @@ -1,20 +1,21 @@ - -#ifndef __Signal2_h__ -#define __Signal2_h__ +#ifndef __signal2_h__ +#define __signal2_h__ #include "horrible_cast.h" #include "slot_base.h" #include "signal_base.h" -//========================================================================================================================================= -// Slot tempplate. -//========================================================================================================================================= -/** - * Abstract base class for Slots with 2 parameter(s). - */ + +// +// classes slot2, slot2_function, and slot2_method +// + +// +// Abstract base class for slots with 2 parameter(s). +// template -class Slot2 : public slot_base +class slot2 : public slot_base { public: /** @@ -25,23 +26,34 @@ class Slot2 : public slot_base virtual T_return operator() (T_arg0 a0, T_arg1 a1) const = 0; }; - // -// a concrete Slot class for a normal function +// A concrete slot class for a normal function. // template -class Slot2_function: public Slot2 +class slot2_function: public slot2 { public: - typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1); + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1); // convenience typedef - Slot2_function( const FUNCTION_POINTER func ) + /** + * 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 @@ -52,22 +64,33 @@ class Slot2_function: public Slot2 } }; - // -// a concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method') +// A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method'). // template -class Slot2_method: public Slot2 +class slot2_method: public slot2 { public: - Slot2_method(const T_object* p_object, const T_member p_member) + /** + * 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 @@ -79,103 +102,113 @@ class Slot2_method: public Slot2 } }; -//========================================================================================================================================= -// Signal tempplate. -//========================================================================================================================================= + + +// +// class signal2 +// template< typename T_return, typename T_arg0, typename T_arg1 > -class Signal2: public signal_base +class signal2: public signal_base { public: - //----------------------------------------------------------------------------------------------------------------------------------------- - // Execute the Signal: - // - Walk the list of Slot nodes. - //----------------------------------------------------------------------------------------------------------------------------------------- + /** + * Emit the signal. + * + * Iterate through the list of slots, and call each one. + */ void operator() (T_arg0 a0, T_arg1 a1) { - if( IsSignalEmitting( ) ) + // 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); + printf("WARNING: signal2<...> @ 0x%p recursive emit attempt\n", this); #endif return; } - BeginEmit( ); - - list_node* cur = GetFirstNode( ); + // set emitting flag + signal_base::emitting = true; // iterate through the list + signal_base::list_node* cur = signal_base::head; while( cur ) { - // make the slot_base pointer a Slot2 pointer - Slot2* s = static_cast*>(cur->slot); + // 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 - (*s)(a0, a1); + // call the signal as long as it's still valid + if ( !cur->deleted ) + { + (*s)(a0, a1); + } - // move to next Slot in the list. + // move to next slot in the list. cur = cur->next; } - EndEmit( ); + // delete any pending slot deletions + signal_base::remove_pending_nodes( ); + + // clear emitting flag + signal_base::emitting = false; } - //========================================================================================================================================= - // Signal connections - //========================================================================================================================================= + + // + // signal connections to slots + // + + // convenience typedef typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1); - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // 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 ); + // 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 bind(sNewFunc); + return signal_base::bind(sNewFunc); } - // Object methods - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 ); + // 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 bind(sNewMethod); + return signal_base::bind(sNewMethod); } - //========================================================================================================================================= - // Signal Disconnections - //========================================================================================================================================= - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // + // 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 ); + // make a temporary slot we can use to find a match in the list + slot2_function sTest( func ); // search and remove it - return unbind(&sTest); + return signal_base::unbind(&sTest); } - - // Object method - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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); + // 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 unbind(&sTemp); + return signal_base::unbind(&sTemp); } }; -#endif // __Signal2_h__ +#endif // __signal2_h__ diff --git a/signal3.h b/signal3.h index 154ece2..73a72d6 100644 --- a/signal3.h +++ b/signal3.h @@ -1,20 +1,21 @@ - -#ifndef __Signal3_h__ -#define __Signal3_h__ +#ifndef __signal3_h__ +#define __signal3_h__ #include "horrible_cast.h" #include "slot_base.h" #include "signal_base.h" -//========================================================================================================================================= -// Slot tempplate. -//========================================================================================================================================= -/** - * Abstract base class for Slots with 3 parameter(s). - */ + +// +// classes slot3, slot3_function, and slot3_method +// + +// +// Abstract base class for slots with 3 parameter(s). +// template -class Slot3 : public slot_base +class slot3 : public slot_base { public: /** @@ -25,23 +26,34 @@ class Slot3 : public slot_base virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2) const = 0; }; - // -// a concrete Slot class for a normal function +// A concrete slot class for a normal function. // template -class Slot3_function: public Slot3 +class slot3_function: public slot3 { public: - typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2); + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2); // convenience typedef - Slot3_function( const FUNCTION_POINTER func ) + /** + * 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 @@ -52,22 +64,33 @@ class Slot3_function: public Slot3 } }; - // -// a concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method') +// A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method'). // template -class Slot3_method: public Slot3 +class slot3_method: public slot3 { public: - Slot3_method(const T_object* p_object, const T_member p_member) + /** + * 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 @@ -79,103 +102,113 @@ class Slot3_method: public Slot3 } }; -//========================================================================================================================================= -// Signal tempplate. -//========================================================================================================================================= + + +// +// class signal3 +// template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2 > -class Signal3: public signal_base +class signal3: public signal_base { public: - //----------------------------------------------------------------------------------------------------------------------------------------- - // Execute the Signal: - // - Walk the list of Slot nodes. - //----------------------------------------------------------------------------------------------------------------------------------------- + /** + * 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( IsSignalEmitting( ) ) + // 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); + printf("WARNING: signal3<...> @ 0x%p recursive emit attempt\n", this); #endif return; } - BeginEmit( ); - - list_node* cur = GetFirstNode( ); + // set emitting flag + signal_base::emitting = true; // iterate through the list + signal_base::list_node* cur = signal_base::head; while( cur ) { - // make the slot_base pointer a Slot3 pointer - Slot3* s = static_cast*>(cur->slot); + // 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 - (*s)(a0, a1, a2); + // call the signal as long as it's still valid + if ( !cur->deleted ) + { + (*s)(a0, a1, a2); + } - // move to next Slot in the list. + // move to next slot in the list. cur = cur->next; } - EndEmit( ); + // delete any pending slot deletions + signal_base::remove_pending_nodes( ); + + // clear emitting flag + signal_base::emitting = false; } - //========================================================================================================================================= - // Signal connections - //========================================================================================================================================= + + // + // signal connections to slots + // + + // convenience typedef typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2); - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // 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 ); + // 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 bind(sNewFunc); + return signal_base::bind(sNewFunc); } - // Object methods - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 ); + // 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 bind(sNewMethod); + return signal_base::bind(sNewMethod); } - //========================================================================================================================================= - // Signal Disconnections - //========================================================================================================================================= - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // + // 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 ); + // make a temporary slot we can use to find a match in the list + slot3_function sTest( func ); // search and remove it - return unbind(&sTest); + return signal_base::unbind(&sTest); } - - // Object method - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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); + // 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 unbind(&sTemp); + return signal_base::unbind(&sTemp); } }; -#endif // __Signal3_h__ +#endif // __signal3_h__ diff --git a/signal4.h b/signal4.h index 76a1025..bed0dd6 100644 --- a/signal4.h +++ b/signal4.h @@ -1,20 +1,21 @@ - -#ifndef __Signal4_h__ -#define __Signal4_h__ +#ifndef __signal4_h__ +#define __signal4_h__ #include "horrible_cast.h" #include "slot_base.h" #include "signal_base.h" -//========================================================================================================================================= -// Slot tempplate. -//========================================================================================================================================= -/** - * Abstract base class for Slots with 4 parameter(s). - */ + +// +// classes slot4, slot4_function, and slot4_method +// + +// +// Abstract base class for slots with 4 parameter(s). +// template -class Slot4 : public slot_base +class slot4 : public slot_base { public: /** @@ -25,23 +26,34 @@ class Slot4 : public slot_base 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 +// A concrete slot class for a normal function. // template -class Slot4_function: public Slot4 +class slot4_function: public slot4 { public: - typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3); + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3); // convenience typedef - Slot4_function( const FUNCTION_POINTER func ) + /** + * 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 @@ -52,22 +64,33 @@ class Slot4_function: public Slot4 } }; - // -// a concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method') +// A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method'). // template -class Slot4_method: public Slot4 +class slot4_method: public slot4 { public: - Slot4_method(const T_object* p_object, const T_member p_member) + /** + * 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 @@ -79,103 +102,113 @@ class Slot4_method: public Slot4 } }; -//========================================================================================================================================= -// Signal tempplate. -//========================================================================================================================================= + + +// +// class signal4 +// template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2, typename T_arg3 > -class Signal4: public signal_base +class signal4: public signal_base { public: - //----------------------------------------------------------------------------------------------------------------------------------------- - // Execute the Signal: - // - Walk the list of Slot nodes. - //----------------------------------------------------------------------------------------------------------------------------------------- + /** + * 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( IsSignalEmitting( ) ) + // 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); + printf("WARNING: signal4<...> @ 0x%p recursive emit attempt\n", this); #endif return; } - BeginEmit( ); - - list_node* cur = GetFirstNode( ); + // set emitting flag + signal_base::emitting = true; // iterate through the list + signal_base::list_node* cur = signal_base::head; while( cur ) { - // make the slot_base pointer a Slot4 pointer - Slot4* s = static_cast*>(cur->slot); + // 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 - (*s)(a0, a1, a2, a3); + // 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. + // move to next slot in the list. cur = cur->next; } - EndEmit( ); + // delete any pending slot deletions + signal_base::remove_pending_nodes( ); + + // clear emitting flag + signal_base::emitting = false; } - //========================================================================================================================================= - // Signal connections - //========================================================================================================================================= + + // + // signal connections to slots + // + + // convenience typedef typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3); - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // 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 ); + // 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 bind(sNewFunc); + return signal_base::bind(sNewFunc); } - // Object methods - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 ); + // 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 bind(sNewMethod); + return signal_base::bind(sNewMethod); } - //========================================================================================================================================= - // Signal Disconnections - //========================================================================================================================================= - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // + // 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 ); + // make a temporary slot we can use to find a match in the list + slot4_function sTest( func ); // search and remove it - return unbind(&sTest); + return signal_base::unbind(&sTest); } - - // Object method - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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); + // 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 unbind(&sTemp); + return signal_base::unbind(&sTemp); } }; -#endif // __Signal4_h__ +#endif // __signal4_h__ diff --git a/signal5.h b/signal5.h index 6fd958b..61fa3bc 100644 --- a/signal5.h +++ b/signal5.h @@ -1,20 +1,21 @@ - -#ifndef __Signal5_h__ -#define __Signal5_h__ +#ifndef __signal5_h__ +#define __signal5_h__ #include "horrible_cast.h" #include "slot_base.h" #include "signal_base.h" -//========================================================================================================================================= -// Slot tempplate. -//========================================================================================================================================= -/** - * Abstract base class for Slots with 5 parameter(s). - */ + +// +// classes slot5, slot5_function, and slot5_method +// + +// +// Abstract base class for slots with 5 parameter(s). +// template -class Slot5 : public slot_base +class slot5 : public slot_base { public: /** @@ -25,23 +26,34 @@ class Slot5 : public slot_base 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 +// A concrete slot class for a normal function. // template -class Slot5_function: public Slot5 +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); + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4); // convenience typedef - Slot5_function( const FUNCTION_POINTER func ) + /** + * 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 @@ -52,22 +64,33 @@ class Slot5_function: public Slot5 -class Slot5_method: public Slot5 +class slot5_method: public slot5 { public: - Slot5_method(const T_object* p_object, const T_member p_member) + /** + * 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 @@ -79,103 +102,113 @@ class Slot5_method: public Slot5 -class Signal5: public signal_base +class signal5: public signal_base { public: - //----------------------------------------------------------------------------------------------------------------------------------------- - // Execute the Signal: - // - Walk the list of Slot nodes. - //----------------------------------------------------------------------------------------------------------------------------------------- + /** + * 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( IsSignalEmitting( ) ) + // 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); + printf("WARNING: signal5<...> @ 0x%p recursive emit attempt\n", this); #endif return; } - BeginEmit( ); - - list_node* cur = GetFirstNode( ); + // set emitting flag + signal_base::emitting = true; // iterate through the list + signal_base::list_node* cur = signal_base::head; while( cur ) { - // make the slot_base pointer a Slot5 pointer - Slot5* s = static_cast*>(cur->slot); + // 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 - (*s)(a0, a1, a2, a3, a4); + // 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. + // move to next slot in the list. cur = cur->next; } - EndEmit( ); + // delete any pending slot deletions + signal_base::remove_pending_nodes( ); + + // clear emitting flag + signal_base::emitting = false; } - //========================================================================================================================================= - // Signal connections - //========================================================================================================================================= + + // + // 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); - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // 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 ); + // 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 bind(sNewFunc); + return signal_base::bind(sNewFunc); } - // Object methods - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 ); + // 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 bind(sNewMethod); + return signal_base::bind(sNewMethod); } - //========================================================================================================================================= - // Signal Disconnections - //========================================================================================================================================= - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // + // 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 ); + // make a temporary slot we can use to find a match in the list + slot5_function sTest( func ); // search and remove it - return unbind(&sTest); + return signal_base::unbind(&sTest); } - - // Object method - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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); + // 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 unbind(&sTemp); + return signal_base::unbind(&sTemp); } }; -#endif // __Signal5_h__ +#endif // __signal5_h__ diff --git a/signal6.h b/signal6.h index 0537cb5..8eb23c2 100644 --- a/signal6.h +++ b/signal6.h @@ -1,20 +1,21 @@ - -#ifndef __Signal6_h__ -#define __Signal6_h__ +#ifndef __signal6_h__ +#define __signal6_h__ #include "horrible_cast.h" #include "slot_base.h" #include "signal_base.h" -//========================================================================================================================================= -// Slot tempplate. -//========================================================================================================================================= -/** - * Abstract base class for Slots with 6 parameter(s). - */ + +// +// classes slot6, slot6_function, and slot6_method +// + +// +// Abstract base class for slots with 6 parameter(s). +// template -class Slot6 : public slot_base +class slot6 : public slot_base { public: /** @@ -25,23 +26,34 @@ class Slot6 : public slot_base 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 +// A concrete slot class for a normal function. // template -class Slot6_function: public Slot6 +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); + 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 - Slot6_function( const FUNCTION_POINTER func ) + /** + * 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 @@ -52,22 +64,33 @@ class Slot6_function: public Slot6 -class Slot6_method: public Slot6 +class slot6_method: public slot6 { public: - Slot6_method(const T_object* p_object, const T_member p_member) + /** + * 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 @@ -79,103 +102,113 @@ class Slot6_method: public Slot6 -class Signal6: public signal_base +class signal6: public signal_base { public: - //----------------------------------------------------------------------------------------------------------------------------------------- - // Execute the Signal: - // - Walk the list of Slot nodes. - //----------------------------------------------------------------------------------------------------------------------------------------- + /** + * 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( IsSignalEmitting( ) ) + // 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); + printf("WARNING: signal6<...> @ 0x%p recursive emit attempt\n", this); #endif return; } - BeginEmit( ); - - list_node* cur = GetFirstNode( ); + // set emitting flag + signal_base::emitting = true; // iterate through the list + signal_base::list_node* cur = signal_base::head; while( cur ) { - // make the slot_base pointer a Slot6 pointer - Slot6* s = static_cast*>(cur->slot); + // 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 - (*s)(a0, a1, a2, a3, a4, a5); + // 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. + // move to next slot in the list. cur = cur->next; } - EndEmit( ); + // delete any pending slot deletions + signal_base::remove_pending_nodes( ); + + // clear emitting flag + signal_base::emitting = false; } - //========================================================================================================================================= - // Signal connections - //========================================================================================================================================= + + // + // 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); - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // 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 ); + // 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 bind(sNewFunc); + return signal_base::bind(sNewFunc); } - // Object methods - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 ); + // 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 bind(sNewMethod); + return signal_base::bind(sNewMethod); } - //========================================================================================================================================= - // Signal Disconnections - //========================================================================================================================================= - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // + // 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 ); + // make a temporary slot we can use to find a match in the list + slot6_function sTest( func ); // search and remove it - return unbind(&sTest); + return signal_base::unbind(&sTest); } - - // Object method - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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); + // 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 unbind(&sTemp); + return signal_base::unbind(&sTemp); } }; -#endif // __Signal6_h__ +#endif // __signal6_h__ diff --git a/signal7.h b/signal7.h index 3e76419..3574865 100644 --- a/signal7.h +++ b/signal7.h @@ -1,20 +1,21 @@ - -#ifndef __Signal7_h__ -#define __Signal7_h__ +#ifndef __signal7_h__ +#define __signal7_h__ #include "horrible_cast.h" #include "slot_base.h" #include "signal_base.h" -//========================================================================================================================================= -// Slot tempplate. -//========================================================================================================================================= -/** - * Abstract base class for Slots with 7 parameter(s). - */ + +// +// classes slot7, slot7_function, and slot7_method +// + +// +// Abstract base class for slots with 7 parameter(s). +// template -class Slot7 : public slot_base +class slot7 : public slot_base { public: /** @@ -25,23 +26,34 @@ class Slot7 : public slot_base virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6) const = 0; }; - // -// a concrete Slot class for a normal function +// A concrete slot class for a normal function. // template -class Slot7_function: public Slot7 +class slot7_function: public slot7 { public: - typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6); + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6); // convenience typedef - Slot7_function( const FUNCTION_POINTER func ) + /** + * Constructor. + * + * Converts a function pointer into raw data. + */ + slot7_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, T_arg6 a6) const { // retrieve data from slot_base and convert back to a function pointer @@ -52,22 +64,33 @@ class Slot7_function: public Slot7 -class Slot7_method: public Slot7 +class slot7_method: public slot7 { public: - Slot7_method(const T_object* p_object, const T_member p_member) + /** + * Constructor. + * + * Converts an object and method pointer into raw data. + */ + slot7_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, T_arg6 a6) const { // retrieve data from slot_base and convert back to an object pointer and member function pointer @@ -79,103 +102,113 @@ class Slot7_method: public Slot7 -class Signal7: public signal_base +class signal7: public signal_base { public: - //----------------------------------------------------------------------------------------------------------------------------------------- - // Execute the Signal: - // - Walk the list of Slot nodes. - //----------------------------------------------------------------------------------------------------------------------------------------- + /** + * 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, T_arg6 a6) { - if( IsSignalEmitting( ) ) + // if we're already emitting, return (i.e. no re-entrancy allowed) + if( signal_base::emitting ) { #if defined( _DEBUG ) - printf("WARNING: Signal7<...> @ 0x%p recursive Emit attempt\n", this); + printf("WARNING: signal7<...> @ 0x%p recursive emit attempt\n", this); #endif return; } - BeginEmit( ); - - list_node* cur = GetFirstNode( ); + // set emitting flag + signal_base::emitting = true; // iterate through the list + signal_base::list_node* cur = signal_base::head; while( cur ) { - // make the slot_base pointer a Slot7 pointer - Slot7* s = static_cast*>(cur->slot); + // cast the slot_base pointer to a slot7 pointer (converts from raw memory to pointer again) + slot7* s = static_cast*>(cur->slot); - // call the Signal - (*s)(a0, a1, a2, a3, a4, a5, a6); + // call the signal as long as it's still valid + if ( !cur->deleted ) + { + (*s)(a0, a1, a2, a3, a4, a5, a6); + } - // move to next Slot in the list. + // move to next slot in the list. cur = cur->next; } - EndEmit( ); + // delete any pending slot deletions + signal_base::remove_pending_nodes( ); + + // clear emitting flag + signal_base::emitting = false; } - //========================================================================================================================================= - // Signal connections - //========================================================================================================================================= + + // + // 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, T_arg6 a6); - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // connect to normal functions bool Connect( FUNCTION_POINTER func ) { - // make a copy of the Slot to store in our list - Slot7* sNewFunc = new Slot7_function( func ); + // make a copy of the slot to store in our list + slot7* sNewFunc = new slot7_function( func ); // add it to the end of our linked list - return bind(sNewFunc); + return signal_base::bind(sNewFunc); } - // Object methods - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 - Slot7* sNewMethod = new Slot7_method( p_object, p_member ); + // make a copy of the slot to store in our list + slot7* sNewMethod = new slot7_method( p_object, p_member ); // add it to the end of our linked list - return bind(sNewMethod); + return signal_base::bind(sNewMethod); } - //========================================================================================================================================= - // Signal Disconnections - //========================================================================================================================================= - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // + // 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 - Slot7_function sTest( func ); + // make a temporary slot we can use to find a match in the list + slot7_function sTest( func ); // search and remove it - return unbind(&sTest); + return signal_base::unbind(&sTest); } - - // Object method - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 - Slot7_method sTemp(p_object,p_member); + // make a temporary slot we can use to find a match in the list + slot7_method sTemp(p_object,p_member); // search and remove it - return unbind(&sTemp); + return signal_base::unbind(&sTemp); } }; -#endif // __Signal7_h__ +#endif // __signal7_h__ diff --git a/signal8.h b/signal8.h index 9cc81c6..7ec2a70 100644 --- a/signal8.h +++ b/signal8.h @@ -1,20 +1,21 @@ - -#ifndef __Signal8_h__ -#define __Signal8_h__ +#ifndef __signal8_h__ +#define __signal8_h__ #include "horrible_cast.h" #include "slot_base.h" #include "signal_base.h" -//========================================================================================================================================= -// Slot tempplate. -//========================================================================================================================================= -/** - * Abstract base class for Slots with 8 parameter(s). - */ + +// +// classes slot8, slot8_function, and slot8_method +// + +// +// Abstract base class for slots with 8 parameter(s). +// template -class Slot8 : public slot_base +class slot8 : public slot_base { public: /** @@ -25,23 +26,34 @@ class Slot8 : public slot_base virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7) const = 0; }; - // -// a concrete Slot class for a normal function +// A concrete slot class for a normal function. // template -class Slot8_function: public Slot8 +class slot8_function: public slot8 { public: - typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7); + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7); // convenience typedef - Slot8_function( const FUNCTION_POINTER func ) + /** + * Constructor. + * + * Converts a function pointer into raw data. + */ + slot8_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, T_arg6 a6, T_arg7 a7) const { // retrieve data from slot_base and convert back to a function pointer @@ -52,22 +64,33 @@ class Slot8_function: public Slot8 -class Slot8_method: public Slot8 +class slot8_method: public slot8 { public: - Slot8_method(const T_object* p_object, const T_member p_member) + /** + * Constructor. + * + * Converts an object and method pointer into raw data. + */ + slot8_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, T_arg6 a6, T_arg7 a7) const { // retrieve data from slot_base and convert back to an object pointer and member function pointer @@ -79,103 +102,113 @@ class Slot8_method: public Slot8 -class Signal8: public signal_base +class signal8: public signal_base { public: - //----------------------------------------------------------------------------------------------------------------------------------------- - // Execute the Signal: - // - Walk the list of Slot nodes. - //----------------------------------------------------------------------------------------------------------------------------------------- + /** + * 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, T_arg6 a6, T_arg7 a7) { - if( IsSignalEmitting( ) ) + // if we're already emitting, return (i.e. no re-entrancy allowed) + if( signal_base::emitting ) { #if defined( _DEBUG ) - printf("WARNING: Signal8<...> @ 0x%p recursive Emit attempt\n", this); + printf("WARNING: signal8<...> @ 0x%p recursive emit attempt\n", this); #endif return; } - BeginEmit( ); - - list_node* cur = GetFirstNode( ); + // set emitting flag + signal_base::emitting = true; // iterate through the list + signal_base::list_node* cur = signal_base::head; while( cur ) { - // make the slot_base pointer a Slot8 pointer - Slot8* s = static_cast*>(cur->slot); + // cast the slot_base pointer to a slot8 pointer (converts from raw memory to pointer again) + slot8* s = static_cast*>(cur->slot); - // call the Signal - (*s)(a0, a1, a2, a3, a4, a5, a6, a7); + // call the signal as long as it's still valid + if ( !cur->deleted ) + { + (*s)(a0, a1, a2, a3, a4, a5, a6, a7); + } - // move to next Slot in the list. + // move to next slot in the list. cur = cur->next; } - EndEmit( ); + // delete any pending slot deletions + signal_base::remove_pending_nodes( ); + + // clear emitting flag + signal_base::emitting = false; } - //========================================================================================================================================= - // Signal connections - //========================================================================================================================================= + + // + // 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, T_arg6 a6, T_arg7 a7); - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // connect to normal functions bool Connect( FUNCTION_POINTER func ) { - // make a copy of the Slot to store in our list - Slot8* sNewFunc = new Slot8_function( func ); + // make a copy of the slot to store in our list + slot8* sNewFunc = new slot8_function( func ); // add it to the end of our linked list - return bind(sNewFunc); + return signal_base::bind(sNewFunc); } - // Object methods - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 - Slot8* sNewMethod = new Slot8_method( p_object, p_member ); + // make a copy of the slot to store in our list + slot8* sNewMethod = new slot8_method( p_object, p_member ); // add it to the end of our linked list - return bind(sNewMethod); + return signal_base::bind(sNewMethod); } - //========================================================================================================================================= - // Signal Disconnections - //========================================================================================================================================= - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // + // 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 - Slot8_function sTest( func ); + // make a temporary slot we can use to find a match in the list + slot8_function sTest( func ); // search and remove it - return unbind(&sTest); + return signal_base::unbind(&sTest); } - - // Object method - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 - Slot8_method sTemp(p_object,p_member); + // make a temporary slot we can use to find a match in the list + slot8_method sTemp(p_object,p_member); // search and remove it - return unbind(&sTemp); + return signal_base::unbind(&sTemp); } }; -#endif // __Signal8_h__ +#endif // __signal8_h__ diff --git a/signal9.h b/signal9.h index b203d49..36dc174 100644 --- a/signal9.h +++ b/signal9.h @@ -1,20 +1,21 @@ - -#ifndef __Signal9_h__ -#define __Signal9_h__ +#ifndef __signal9_h__ +#define __signal9_h__ #include "horrible_cast.h" #include "slot_base.h" #include "signal_base.h" -//========================================================================================================================================= -// Slot tempplate. -//========================================================================================================================================= -/** - * Abstract base class for Slots with 9 parameter(s). - */ + +// +// classes slot9, slot9_function, and slot9_method +// + +// +// Abstract base class for slots with 9 parameter(s). +// template -class Slot9 : public slot_base +class slot9 : public slot_base { public: /** @@ -25,23 +26,34 @@ class Slot9 : public slot_base virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8) const = 0; }; - // -// a concrete Slot class for a normal function +// A concrete slot class for a normal function. // template -class Slot9_function: public Slot9 +class slot9_function: public slot9 { public: - typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8); + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8); // convenience typedef - Slot9_function( const FUNCTION_POINTER func ) + /** + * Constructor. + * + * Converts a function pointer into raw data. + */ + slot9_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, T_arg6 a6, T_arg7 a7, T_arg8 a8) const { // retrieve data from slot_base and convert back to a function pointer @@ -52,22 +64,33 @@ class Slot9_function: public Slot9 -class Slot9_method: public Slot9 +class slot9_method: public slot9 { public: - Slot9_method(const T_object* p_object, const T_member p_member) + /** + * Constructor. + * + * Converts an object and method pointer into raw data. + */ + slot9_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, T_arg6 a6, T_arg7 a7, T_arg8 a8) const { // retrieve data from slot_base and convert back to an object pointer and member function pointer @@ -79,103 +102,113 @@ class Slot9_method: public Slot9 -class Signal9: public signal_base +class signal9: public signal_base { public: - //----------------------------------------------------------------------------------------------------------------------------------------- - // Execute the Signal: - // - Walk the list of Slot nodes. - //----------------------------------------------------------------------------------------------------------------------------------------- + /** + * 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, T_arg6 a6, T_arg7 a7, T_arg8 a8) { - if( IsSignalEmitting( ) ) + // if we're already emitting, return (i.e. no re-entrancy allowed) + if( signal_base::emitting ) { #if defined( _DEBUG ) - printf("WARNING: Signal9<...> @ 0x%p recursive Emit attempt\n", this); + printf("WARNING: signal9<...> @ 0x%p recursive emit attempt\n", this); #endif return; } - BeginEmit( ); - - list_node* cur = GetFirstNode( ); + // set emitting flag + signal_base::emitting = true; // iterate through the list + signal_base::list_node* cur = signal_base::head; while( cur ) { - // make the slot_base pointer a Slot9 pointer - Slot9* s = static_cast*>(cur->slot); + // cast the slot_base pointer to a slot9 pointer (converts from raw memory to pointer again) + slot9* s = static_cast*>(cur->slot); - // call the Signal - (*s)(a0, a1, a2, a3, a4, a5, a6, a7, a8); + // call the signal as long as it's still valid + if ( !cur->deleted ) + { + (*s)(a0, a1, a2, a3, a4, a5, a6, a7, a8); + } - // move to next Slot in the list. + // move to next slot in the list. cur = cur->next; } - EndEmit( ); + // delete any pending slot deletions + signal_base::remove_pending_nodes( ); + + // clear emitting flag + signal_base::emitting = false; } - //========================================================================================================================================= - // Signal connections - //========================================================================================================================================= + + // + // 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, T_arg6 a6, T_arg7 a7, T_arg8 a8); - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // connect to normal functions bool Connect( FUNCTION_POINTER func ) { - // make a copy of the Slot to store in our list - Slot9* sNewFunc = new Slot9_function( func ); + // make a copy of the slot to store in our list + slot9* sNewFunc = new slot9_function( func ); // add it to the end of our linked list - return bind(sNewFunc); + return signal_base::bind(sNewFunc); } - // Object methods - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 - Slot9* sNewMethod = new Slot9_method( p_object, p_member ); + // make a copy of the slot to store in our list + slot9* sNewMethod = new slot9_method( p_object, p_member ); // add it to the end of our linked list - return bind(sNewMethod); + return signal_base::bind(sNewMethod); } - //========================================================================================================================================= - // Signal Disconnections - //========================================================================================================================================= - // Functions - //----------------------------------------------------------------------------------------------------------------------------------------- + // + // 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 - Slot9_function sTest( func ); + // make a temporary slot we can use to find a match in the list + slot9_function sTest( func ); // search and remove it - return unbind(&sTest); + return signal_base::unbind(&sTest); } - - // Object method - //----------------------------------------------------------------------------------------------------------------------------------------- - template + // 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 - Slot9_method sTemp(p_object,p_member); + // make a temporary slot we can use to find a match in the list + slot9_method sTemp(p_object,p_member); // search and remove it - return unbind(&sTemp); + return signal_base::unbind(&sTemp); } }; -#endif // __Signal9_h__ +#endif // __signal9_h__ diff --git a/signal_base.cpp b/signal_base.cpp index a310c31..26e9690 100644 --- a/signal_base.cpp +++ b/signal_base.cpp @@ -2,64 +2,56 @@ #include "signal_base.h" -//----------------------------------------------------------------------------------------------------------------------------------------- signal_base::signal_base() : head(0), tail(0), bEmitting(false) { // empty } - -//----------------------------------------------------------------------------------------------------------------------------------------- signal_base::~signal_base() { // clear the list clear_list(); } -//----------------------------------------------------------------------------------------------------------------------------------------- signal_base::signal_base( const signal_base& rSource ) : head(0), tail(0), bEmitting(false) { - // Set an assert to let the user know that we don't support construction of a signal by copying another one. - // There are too many places where the signals are directly connected to objects, where copying them would create a disconnect - // between the signal and the objects that want to react to the signal execution. + // Set an assert to let the user know that we don't support signal copying. + // There are too many places where the signals are directly connected to objects, + // where copying them would create a disconnect between the signal and the objects + // that want to react to the signal execution. assert( 0 ); } -//----------------------------------------------------------------------------------------------------------------------------------------- signal_base& signal_base::operator=( const signal_base& rSource ) { // Set an assert to let the user know that we don't support signal copying. - // There are too many places where the signals are directly connected to objects, where copying them would create a disconnect - // between the signal and the objects that want to react to the signal execution. + // There are too many places where the signals are directly connected to objects, + // where copying them would create a disconnect between the signal and the objects + // that want to react to the signal execution. assert( 0 ); return *this; } -//----------------------------------------------------------------------------------------------------------------------------------------- -int signal_base::Count( void ) +int signal_base::count( void ) { - int Count = 0; + int count = 0; + list_node* cur = head; - list_node* pIndex; - pIndex = head; - - while( pIndex ) + while( cur ) { - pIndex = pIndex->next; - Count++; + cur = cur->next; + count++; } - return Count; + return count; } -//----------------------------------------------------------------------------------------------------------------------------------------- bool signal_base::bind(slot_base* slot) { // add it to our signal list return add_to_list(slot); } -//----------------------------------------------------------------------------------------------------------------------------------------- bool signal_base::unbind(slot_base* slot) { // look for corresponding list_node in list @@ -69,7 +61,7 @@ bool signal_base::unbind(slot_base* slot) if( n ) { // If we are not processing a signal emit sequence, then release the node. - if( !IsSignalEmitting( ) ) + if( !emitting ) { // take it out of the linked list remove_from_list(n); @@ -80,7 +72,7 @@ bool signal_base::unbind(slot_base* slot) // Otherwise mark it for removal. else { - n->bDeleteRequested = true; + n->deleted = true; return true; } } @@ -89,16 +81,11 @@ bool signal_base::unbind(slot_base* slot) return false; } -//----------------------------------------------------------------------------------------------------------------------------------------- -signal_base::list_node::list_node(slot_base* s) : slot(s), - prev(0), - next(0), - bDeleteRequested(false) +signal_base::list_node::list_node(slot_base* s) : slot(s), prev(0), next(0), deleted(false) { // empty } -//----------------------------------------------------------------------------------------------------------------------------------------- signal_base::list_node::~list_node() { // release the slot @@ -106,13 +93,6 @@ signal_base::list_node::~list_node() } -//----------------------------------------------------------------------------------------------------------------------------------------- -signal_base::list_node* signal_base::GetFirstNode( void ) const -{ - return head; -} - -//----------------------------------------------------------------------------------------------------------------------------------------- void signal_base::clear_list() { // start at head @@ -135,7 +115,6 @@ void signal_base::clear_list() head = tail = 0; } -//----------------------------------------------------------------------------------------------------------------------------------------- signal_base::list_node* signal_base::find_in_list(slot_base* slot) const { // start search at head of list @@ -159,7 +138,6 @@ signal_base::list_node* signal_base::find_in_list(slot_base* slot) const return 0; } -//----------------------------------------------------------------------------------------------------------------------------------------- bool signal_base::add_to_list(slot_base* slot) { // a sanity check @@ -194,7 +172,6 @@ bool signal_base::add_to_list(slot_base* slot) return true; } -//----------------------------------------------------------------------------------------------------------------------------------------- void signal_base::remove_from_list(list_node* n) { // do a little sanity checking @@ -228,44 +205,24 @@ void signal_base::remove_from_list(list_node* n) delete n; } -//----------------------------------------------------------------------------------------------------------------------------------------- void signal_base::remove_pending_nodes( void ) { - list_node* pIndex; - list_node* pNext; + list_node* cur = head; + list_node* next; - pIndex = head; - - while( pIndex ) + while( cur ) { // Prepare the next link in the list the removal stage. - pNext = pIndex->next; + next = cur->next; // Do we need to remove this link. - if( pIndex->bDeleteRequested ) - remove_from_list( pIndex ); + if( cur->deleted ) + { + remove_from_list( cur ); + } // Go to the next item. - pIndex = pNext; + cur = next; } } -//----------------------------------------------------------------------------------------------------------------------------------------- -void signal_base::BeginEmit( void ) -{ - bEmitting = true; -} - -//----------------------------------------------------------------------------------------------------------------------------------------- -void signal_base::EndEmit( void ) -{ - bEmitting = false; - - remove_pending_nodes( ); -} - -//----------------------------------------------------------------------------------------------------------------------------------------- -bool signal_base::IsSignalEmitting( void ) const -{ - return bEmitting; -} diff --git a/signal_base.h b/signal_base.h index 736d385..992d1ed 100644 --- a/signal_base.h +++ b/signal_base.h @@ -47,7 +47,7 @@ class signal_base list_node* prev; list_node* next; - bool bDeleteRequested; + bool deleted; }; /** @@ -70,19 +70,11 @@ class signal_base */ bool unbind(slot_base* slot); - /** - * Used to obtain the first slot that is connected to this signal. Used for walking the list of slots when a signal is executed. - */ - list_node* GetFirstNode( void ) const; - /** * Functions used to maintain the status of a signal. When a signal is active it means that it is "Emitting". During the emitting * stage, we are walking the list of slots to allow each slot to react to the signal. There are special considerations that * must be made when walking the list, such as adding or removing slots during the emit stage. */ - void BeginEmit( void ); - void EndEmit( void ); - bool IsSignalEmitting( void ) const; private: /** @@ -114,7 +106,7 @@ class signal_base list_node* head; list_node* tail; - bool bEmitting; + bool emitting; }; #endif // __signal_base_h__ diff --git a/signal_template.h b/signal_template.h index 8d57034..cf36a59 100644 --- a/signal_template.h +++ b/signal_template.h @@ -8,14 +8,14 @@ // -// classes Slot===NARG===, Slot===NARG===_function, and Slot===NARG===_method +// classes slot===NARG===, slot===NARG===_function, and slot===NARG===_method // // -// Abstract base class for Slots with ===NARG=== parameter(s). +// Abstract base class for slots with ===NARG=== parameter(s). // template -class Slot===NARG=== : public slot_base +class slot===NARG=== : public slot_base { public: /** @@ -27,10 +27,10 @@ class Slot===NARG=== : public slot_base }; // -// A concrete Slot class for a normal function. +// A concrete slot class for a normal function. // template -class Slot===NARG===_function: public Slot===NARG=== +class slot===NARG===_function: public slot===NARG=== { public: @@ -41,10 +41,10 @@ class Slot===NARG===_function: public Slot===NARG=== * * Converts a function pointer into raw data. */ - Slot===NARG===_function( const FUNCTION_POINTER func ) + slot===NARG===_function( const FUNCTION_POINTER func ) { // convert and store function pointer in slot_base - this->data[0] = safe_horrible_cast(func); + this->data[0] = safe_horrible_cast(func); } /** @@ -65,10 +65,10 @@ class Slot===NARG===_function: public Slot===NARG=== }; // -// A concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method'). +// A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method'). // template -class Slot===NARG===_method: public Slot===NARG=== +class slot===NARG===_method: public slot===NARG=== { public: @@ -77,11 +77,11 @@ class Slot===NARG===_method: public Slot===NARG=== * * Converts an object and method pointer into raw data. */ - Slot===NARG===_method(const T_object* p_object, const T_member p_member) + slot===NARG===_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); + this->data[0] = safe_horrible_cast(p_object); + this->data[1] = safe_horrible_cast(p_member); } /** @@ -105,10 +105,10 @@ class Slot===NARG===_method: public Slot===NARG=== // -// class Signal ===NARG=== +// class signal===NARG=== // template< typename T_return===TEMPLATE_ARG_DECL=== > -class Signal===NARG===: public signal_base +class signal===NARG===: public signal_base { public: @@ -119,34 +119,40 @@ class Signal===NARG===: public signal_base */ void operator() (===FORMAL_ARG_DECL===) { - // if we're already emitting, return (i.e. no re-entrancy) - if( IsSignalEmitting() ) + // if we're already emitting, return (i.e. no re-entrancy allowed) + if( signal_base::emitting ) { #if defined( _DEBUG ) - printf("WARNING: Signal===NARG===<...> @ 0x%p recursive Emit attempt\n", this); + printf("WARNING: signal===NARG===<...> @ 0x%p recursive emit attempt\n", this); #endif return; } // set emitting flag - BeginEmit(); + signal_base::emitting = true; // iterate through the list - list_node* cur = GetFirstNode(); + signal_base::list_node* cur = signal_base::head; while( cur ) { - // make the slot_base pointer a Slot===NARG=== pointer - Slot===NARG===* s = static_cast*>(cur->slot); + // cast the slot_base pointer to a slot===NARG=== pointer (converts from raw memory to pointer again) + slot===NARG===* s = static_cast*>(cur->slot); - // call the Signal - (*s)(===FORMAL_ARG===); + // call the signal as long as it's still valid + if ( !cur->deleted ) + { + (*s)(===FORMAL_ARG===); + } - // move to next Slot in the list. + // move to next slot in the list. cur = cur->next; } + // delete any pending slot deletions + signal_base::remove_pending_nodes( ); + // clear emitting flag - EndEmit( ); + signal_base::emitting = false; } @@ -155,27 +161,27 @@ class Signal===NARG===: public signal_base // // convenience typedef - typedef T_return (*FUNCTION_POINTER)(===FORMAL_ARG_DECL===); + typedef T_return (*FUNCTION_POINTER)(===FORMAL_ARG_DECL===); // connect to normal functions bool Connect( FUNCTION_POINTER func ) { - // make a copy of the Slot to store in our list - Slot===NARG===* sNewFunc = new Slot===NARG===_function( func ); + // make a copy of the slot to store in our list + slot===NARG===* sNewFunc = new slot===NARG===_function( func ); // add it to the end of our linked list - return bind(sNewFunc); + 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 - Slot===NARG===* sNewMethod =new Slot===NARG===_method( p_object, p_member ); + // make a copy of the slot to store in our list + slot===NARG===* sNewMethod = new slot===NARG===_method( p_object, p_member ); // add it to the end of our linked list - return bind(sNewMethod); + return signal_base::bind(sNewMethod); } @@ -186,22 +192,22 @@ class Signal===NARG===: public signal_base // disconnect from a normal function bool Disconnect( FUNCTION_POINTER func ) { - // make a temporary Slot we can use to find a match in the list - Slot===NARG===_function sTest( func ); + // make a temporary slot we can use to find a match in the list + slot===NARG===_function sTest( func ); // search and remove it - return unbind(&sTest); + 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 - Slot===NARG===_method sTemp(p_object,p_member); + // make a temporary slot we can use to find a match in the list + slot===NARG===_method sTemp(p_object,p_member); // search and remove it - return unbind(&sTemp); + return signal_base::unbind(&sTemp); } };