From c7d43807e37672ffb9d0360d459951ac9bbd483f Mon Sep 17 00:00:00 2001 From: Stephen Waits Date: Mon, 4 Oct 2010 11:08:27 -0700 Subject: [PATCH] updated to latest signals. some cleanup & refactoring begun. --- horrible_cast.h | 2 +- signal.cpp | 0 signal.h | 134 ++++++++++++++ signal.pl | 103 +++++++++++ signal0.h | 217 ++++++++++++++++++---- signal0.inl | 0 signal1.h | 181 +++++++++++++++++++ signal10.h | 181 +++++++++++++++++++ signal11.h | 181 +++++++++++++++++++ signal12.h | 181 +++++++++++++++++++ signal13.h | 181 +++++++++++++++++++ signal14.h | 181 +++++++++++++++++++ signal15.h | 181 +++++++++++++++++++ signal16.h | 181 +++++++++++++++++++ signal2.h | 181 +++++++++++++++++++ signal3.h | 181 +++++++++++++++++++ signal4.h | 181 +++++++++++++++++++ signal5.h | 181 +++++++++++++++++++ signal6.h | 181 +++++++++++++++++++ signal7.h | 181 +++++++++++++++++++ signal8.h | 181 +++++++++++++++++++ signal9.h | 181 +++++++++++++++++++ signal_base.cpp | 422 +++++++++++++++++++++++++++---------------- signal_base.h | 159 ++++++++++++---- signal_template.h | 179 ++++++++++++++++++ slot_base.cpp | 5 +- slot_base.h | 10 +- main.cpp => test.cpp | 0 28 files changed, 3892 insertions(+), 235 deletions(-) delete mode 100644 signal.cpp create mode 100644 signal.pl delete mode 100644 signal0.inl create mode 100644 signal1.h create mode 100644 signal10.h create mode 100644 signal11.h create mode 100644 signal12.h create mode 100644 signal13.h create mode 100644 signal14.h create mode 100644 signal15.h create mode 100644 signal16.h create mode 100644 signal2.h create mode 100644 signal3.h create mode 100644 signal4.h create mode 100644 signal5.h create mode 100644 signal6.h create mode 100644 signal7.h create mode 100644 signal8.h create mode 100644 signal9.h create mode 100644 signal_template.h rename main.cpp => test.cpp (100%) diff --git a/horrible_cast.h b/horrible_cast.h index 7f44922..b24e42e 100644 --- a/horrible_cast.h +++ b/horrible_cast.h @@ -2,7 +2,7 @@ #define __horrible_cast_h__ -// horrible_union is used by {safe|dangerous}_horrible_cast to copy one arbitrary type to another +//horrible_union is used by {safe|dangerous}_horrible_cast to copy one arbitrary type to another template union horrible_union { diff --git a/signal.cpp b/signal.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/signal.h b/signal.h index e69de29..4870dd1 100644 --- a/signal.h +++ b/signal.h @@ -0,0 +1,134 @@ +#ifndef __Signal_h__ +#define __Signal_h__ + + + +#include "signal0.h" +#include "signal1.h" +#include "signal2.h" +#include "signal3.h" +#include "signal4.h" +#include "signal5.h" +#include "signal6.h" +#include "signal7.h" +#include "signal8.h" +#include "signal9.h" +#include "signal10.h" +#include "signal11.h" +#include "signal12.h" +#include "signal13.h" +#include "signal14.h" +#include "signal15.h" +#include "signal16.h" + + + +struct nilarg; + +template +class Signal : + public Signal16 +{ +}; + +template +class Signal : + public Signal15 +{ +}; + +template +class Signal : + public Signal14 +{ +}; + +template +class Signal : + public Signal13 +{ +}; + +template +class Signal : + public Signal12 +{ +}; + +template +class Signal : + public Signal11 +{ +}; + +template +class Signal : + public Signal10 +{ +}; + +template +class Signal : + public Signal9 +{ +}; + +template +class Signal : + public Signal8 +{ +}; + +template +class Signal : + public Signal7 +{ +}; + +template +class Signal : + public Signal6 +{ +}; + +template +class Signal : + public Signal5 +{ +}; + +template +class Signal : + public Signal4 +{ +}; + +template +class Signal : + public Signal3 +{ +}; + +template +class Signal : + public Signal2 +{ +}; + +template +class Signal : + public Signal1 +{ +}; + +template +class Signal : + public Signal0 +{ +}; + + +#include "signal/FixedArgSlot.h" + + +#endif // __Signal_h__ diff --git a/signal.pl b/signal.pl new file mode 100644 index 0000000..7714241 --- /dev/null +++ b/signal.pl @@ -0,0 +1,103 @@ +#!/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 ca15ee5..ec66e33 100644 --- a/signal0.h +++ b/signal0.h @@ -1,36 +1,181 @@ -#ifndef __signal0_h__ -#define __signal0_h__ - -#include "signal_base.h" -#include "slot.h" - -class signal0: public signal_base -{ - public: - /* - signal0(); - virtual ~signal0(); -*/ - - void operator() () const - { - // TODO: need a way to iterate the bound signal_base list ... - list_node* cur = head; - while(cur) - { - (cur->slot)(); - cur = cur->next; - } - } - - template - void connect(T_object* p_object, T_member p_member) - { - bind( slot0_method(p_object,p_member) ); - } -}; - -#include "signal0.inl" - -#endif // __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). + */ +template +class Slot0 : public slot_base +{ + public: + /** + * Method which performs the actual callback. Must be overridden. + * + * @return Returns an object of type T_return; the result of the user callback. + */ + virtual T_return operator() () const = 0; +}; + + +// +// a concrete Slot class for a normal function +// +template +class Slot0_function: public Slot0 +{ + public: + + typedef T_return (*FUNCTION_POINTER)(); + + Slot0_function( const FUNCTION_POINTER func ) + { + // convert and store function pointer in slot_base + this->data[0] = safe_horrible_cast(func); + } + + T_return operator() () const + { + // retrieve data from slot_base and convert back to a function pointer + FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); + + // call function + return func(); + } +}; + + +// +// a concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method') +// +template +class Slot0_method: public Slot0 +{ + public: + + 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); + } + + T_return operator() () const + { + // retrieve data from slot_base and convert back to an object pointer and member function pointer + T_object* p_object = dangerous_horrible_cast(this->data[0]); + T_member p_member = dangerous_horrible_cast (this->data[1]); + + // call member function + return (p_object->*p_member)(); + } +}; + +//========================================================================================================================================= +// Signal tempplate. +//========================================================================================================================================= +template< typename T_return > +class Signal0: public signal_base +{ + public: + + //----------------------------------------------------------------------------------------------------------------------------------------- + // Execute the Signal: + // - Walk the list of Slot nodes. + //----------------------------------------------------------------------------------------------------------------------------------------- + void operator() () + { + if( IsSignalEmitting( ) ) + { +#if defined( _DEBUG ) + printf("WARNING: Signal0<...> @ 0x%p recursive Emit attempt\n", this); +#endif + return; + } + + BeginEmit( ); + + list_node* cur = GetFirstNode( ); + + // iterate through the list + while( cur ) + { + // make the slot_base pointer a Slot0 pointer + Slot0* s = static_cast*>(cur->slot); + + // call the Signal + (*s)(); + + // move to next Slot in the list. + cur = cur->next; + } + + EndEmit( ); + } + + //========================================================================================================================================= + // Signal connections + //========================================================================================================================================= + typedef T_return (*FUNCTION_POINTER)(); + + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Connect( FUNCTION_POINTER func ) + { + // make a copy of the Slot to store in our list + Slot0* sNewFunc = new Slot0_function( func ); + + // add it to the end of our linked list + return bind(sNewFunc); + } + + // Object methods + //----------------------------------------------------------------------------------------------------------------------------------------- + template + bool Connect(T_object* p_object, T_member p_member) + { + // make a copy of the Slot to store in our list + Slot0* sNewMethod = new Slot0_method( p_object, p_member ); + + // add it to the end of our linked list + return bind(sNewMethod); + } + + + //========================================================================================================================================= + // Signal Disconnections + //========================================================================================================================================= + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Disconnect( FUNCTION_POINTER func ) + { + // make a temporary Slot we can use to find a match in the list + Slot0_function sTest( func ); + + // search and remove it + return unbind(&sTest); + } + + + // Object method + //----------------------------------------------------------------------------------------------------------------------------------------- + template + bool Disconnect(T_object* p_object, T_member p_member) + { + // make a temporary Slot we can use to find a match in the list + Slot0_method sTemp(p_object,p_member); + + // search and remove it + return unbind(&sTemp); + } +}; + +#endif // __Signal0_h__ diff --git a/signal0.inl b/signal0.inl deleted file mode 100644 index e69de29..0000000 diff --git a/signal1.h b/signal1.h new file mode 100644 index 0000000..dbab0b3 --- /dev/null +++ b/signal1.h @@ -0,0 +1,181 @@ + +#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). + */ +template +class Slot1 : public slot_base +{ + public: + /** + * Method which performs the actual callback. Must be overridden. + * + * @return Returns an object of type T_return; the result of the user callback. + */ + virtual T_return operator() (T_arg0 a0) const = 0; +}; + + +// +// a concrete Slot class for a normal function +// +template +class Slot1_function: public Slot1 +{ + public: + + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0); + + Slot1_function( const FUNCTION_POINTER func ) + { + // convert and store function pointer in slot_base + this->data[0] = safe_horrible_cast(func); + } + + T_return operator() (T_arg0 a0) const + { + // retrieve data from slot_base and convert back to a function pointer + FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); + + // call function + return func(a0); + } +}; + + +// +// a concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method') +// +template +class Slot1_method: public Slot1 +{ + public: + + 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); + } + + T_return operator() (T_arg0 a0) const + { + // retrieve data from slot_base and convert back to an object pointer and member function pointer + T_object* p_object = dangerous_horrible_cast(this->data[0]); + T_member p_member = dangerous_horrible_cast (this->data[1]); + + // call member function + return (p_object->*p_member)(a0); + } +}; + +//========================================================================================================================================= +// Signal tempplate. +//========================================================================================================================================= +template< typename T_return, typename T_arg0 > +class Signal1: public signal_base +{ + public: + + //----------------------------------------------------------------------------------------------------------------------------------------- + // Execute the Signal: + // - Walk the list of Slot nodes. + //----------------------------------------------------------------------------------------------------------------------------------------- + void operator() (T_arg0 a0) + { + if( IsSignalEmitting( ) ) + { +#if defined( _DEBUG ) + printf("WARNING: Signal1<...> @ 0x%p recursive Emit attempt\n", this); +#endif + return; + } + + BeginEmit( ); + + list_node* cur = GetFirstNode( ); + + // iterate through the list + while( cur ) + { + // make the slot_base pointer a Slot1 pointer + Slot1* s = static_cast*>(cur->slot); + + // call the Signal + (*s)(a0); + + // move to next Slot in the list. + cur = cur->next; + } + + EndEmit( ); + } + + //========================================================================================================================================= + // Signal connections + //========================================================================================================================================= + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0); + + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Connect( FUNCTION_POINTER func ) + { + // make a copy of the Slot to store in our list + Slot1* sNewFunc = new Slot1_function( func ); + + // add it to the end of our linked list + return bind(sNewFunc); + } + + // Object methods + //----------------------------------------------------------------------------------------------------------------------------------------- + template + bool Connect(T_object* p_object, T_member p_member) + { + // make a copy of the Slot to store in our list + Slot1* sNewMethod = new Slot1_method( p_object, p_member ); + + // add it to the end of our linked list + return bind(sNewMethod); + } + + + //========================================================================================================================================= + // Signal Disconnections + //========================================================================================================================================= + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Disconnect( FUNCTION_POINTER func ) + { + // make a temporary Slot we can use to find a match in the list + Slot1_function sTest( func ); + + // search and remove it + return unbind(&sTest); + } + + + // Object method + //----------------------------------------------------------------------------------------------------------------------------------------- + template + bool Disconnect(T_object* p_object, T_member p_member) + { + // make a temporary Slot we can use to find a match in the list + Slot1_method sTemp(p_object,p_member); + + // search and remove it + return unbind(&sTemp); + } +}; + +#endif // __Signal1_h__ diff --git a/signal10.h b/signal10.h new file mode 100644 index 0000000..239251f --- /dev/null +++ b/signal10.h @@ -0,0 +1,181 @@ + +#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). + */ +template +class Slot10 : public slot_base +{ + public: + /** + * Method which performs the actual callback. Must be overridden. + * + * @return Returns an object of type T_return; the result of the user callback. + */ + virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9) const = 0; +}; + + +// +// a concrete Slot class for a normal function +// +template +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); + + Slot10_function( const FUNCTION_POINTER func ) + { + // convert and store function pointer in slot_base + this->data[0] = safe_horrible_cast(func); + } + + 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 + FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); + + // call function + return func(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); + } +}; + + +// +// a concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method') +// +template +class Slot10_method: public Slot10 +{ + public: + + 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); + } + + 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 + T_object* p_object = dangerous_horrible_cast(this->data[0]); + T_member p_member = dangerous_horrible_cast (this->data[1]); + + // call member function + return (p_object->*p_member)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); + } +}; + +//========================================================================================================================================= +// Signal tempplate. +//========================================================================================================================================= +template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2, typename T_arg3, typename T_arg4, typename T_arg5, typename T_arg6, typename T_arg7, typename T_arg8, typename T_arg9 > +class Signal10: public signal_base +{ + public: + + //----------------------------------------------------------------------------------------------------------------------------------------- + // Execute the Signal: + // - Walk the list of Slot nodes. + //----------------------------------------------------------------------------------------------------------------------------------------- + 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 defined( _DEBUG ) + printf("WARNING: Signal10<...> @ 0x%p recursive Emit attempt\n", this); +#endif + return; + } + + BeginEmit( ); + + list_node* cur = GetFirstNode( ); + + // iterate through the list + while( cur ) + { + // make the slot_base pointer a Slot10 pointer + Slot10* s = static_cast*>(cur->slot); + + // call the Signal + (*s)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); + + // move to next Slot in the list. + cur = cur->next; + } + + EndEmit( ); + } + + //========================================================================================================================================= + // Signal connections + //========================================================================================================================================= + 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 + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Connect( FUNCTION_POINTER 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); + } + + // Object methods + //----------------------------------------------------------------------------------------------------------------------------------------- + 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 ); + + // add it to the end of our linked list + return bind(sNewMethod); + } + + + //========================================================================================================================================= + // Signal Disconnections + //========================================================================================================================================= + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Disconnect( FUNCTION_POINTER 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); + } + + + // Object 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); + + // search and remove it + return unbind(&sTemp); + } +}; + +#endif // __Signal10_h__ diff --git a/signal11.h b/signal11.h new file mode 100644 index 0000000..02a2d57 --- /dev/null +++ b/signal11.h @@ -0,0 +1,181 @@ + +#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). + */ +template +class Slot11 : public slot_base +{ + public: + /** + * Method which performs the actual callback. Must be overridden. + * + * @return Returns an object of type T_return; the result of the user callback. + */ + virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, 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 +// +template +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); + + Slot11_function( const FUNCTION_POINTER func ) + { + // convert and store function pointer in slot_base + this->data[0] = safe_horrible_cast(func); + } + + 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 + FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); + + // call function + return func(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); + } +}; + + +// +// a concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method') +// +template +class Slot11_method: public Slot11 +{ + public: + + 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); + } + + 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 + T_object* p_object = dangerous_horrible_cast(this->data[0]); + T_member p_member = dangerous_horrible_cast (this->data[1]); + + // call member function + return (p_object->*p_member)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); + } +}; + +//========================================================================================================================================= +// Signal tempplate. +//========================================================================================================================================= +template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2, typename T_arg3, typename T_arg4, typename T_arg5, typename T_arg6, typename T_arg7, typename T_arg8, typename T_arg9, typename T_arg10 > +class Signal11: public signal_base +{ + public: + + //----------------------------------------------------------------------------------------------------------------------------------------- + // Execute the Signal: + // - Walk the list of Slot nodes. + //----------------------------------------------------------------------------------------------------------------------------------------- + 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 defined( _DEBUG ) + printf("WARNING: Signal11<...> @ 0x%p recursive Emit attempt\n", this); +#endif + return; + } + + BeginEmit( ); + + list_node* cur = GetFirstNode( ); + + // iterate through the list + while( cur ) + { + // make the slot_base pointer a Slot11 pointer + Slot11* s = static_cast*>(cur->slot); + + // call the Signal + (*s)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); + + // move to next Slot in the list. + cur = cur->next; + } + + EndEmit( ); + } + + //========================================================================================================================================= + // Signal connections + //========================================================================================================================================= + 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 + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Connect( FUNCTION_POINTER 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); + } + + // Object methods + //----------------------------------------------------------------------------------------------------------------------------------------- + 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 ); + + // add it to the end of our linked list + return bind(sNewMethod); + } + + + //========================================================================================================================================= + // Signal Disconnections + //========================================================================================================================================= + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Disconnect( FUNCTION_POINTER 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); + } + + + // Object 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); + + // search and remove it + return unbind(&sTemp); + } +}; + +#endif // __Signal11_h__ diff --git a/signal12.h b/signal12.h new file mode 100644 index 0000000..e41aa3d --- /dev/null +++ b/signal12.h @@ -0,0 +1,181 @@ + +#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). + */ +template +class Slot12 : public slot_base +{ + public: + /** + * Method which performs the actual callback. Must be overridden. + * + * @return Returns an object of type T_return; the result of the user callback. + */ + virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, 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 +// +template +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); + + Slot12_function( const FUNCTION_POINTER func ) + { + // convert and store function pointer in slot_base + this->data[0] = safe_horrible_cast(func); + } + + 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 + FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); + + // call function + return func(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); + } +}; + + +// +// a concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method') +// +template +class Slot12_method: public Slot12 +{ + public: + + 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); + } + + 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 + T_object* p_object = dangerous_horrible_cast(this->data[0]); + T_member p_member = dangerous_horrible_cast (this->data[1]); + + // call member function + return (p_object->*p_member)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); + } +}; + +//========================================================================================================================================= +// Signal tempplate. +//========================================================================================================================================= +template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2, typename T_arg3, typename T_arg4, typename T_arg5, typename T_arg6, typename T_arg7, typename T_arg8, typename T_arg9, typename T_arg10, typename T_arg11 > +class Signal12: public signal_base +{ + public: + + //----------------------------------------------------------------------------------------------------------------------------------------- + // Execute the Signal: + // - Walk the list of Slot nodes. + //----------------------------------------------------------------------------------------------------------------------------------------- + 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 defined( _DEBUG ) + printf("WARNING: Signal12<...> @ 0x%p recursive Emit attempt\n", this); +#endif + return; + } + + BeginEmit( ); + + list_node* cur = GetFirstNode( ); + + // iterate through the list + while( cur ) + { + // make the slot_base pointer a Slot12 pointer + Slot12* s = static_cast*>(cur->slot); + + // call the Signal + (*s)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); + + // move to next Slot in the list. + cur = cur->next; + } + + EndEmit( ); + } + + //========================================================================================================================================= + // Signal connections + //========================================================================================================================================= + 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 + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Connect( FUNCTION_POINTER 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); + } + + // Object methods + //----------------------------------------------------------------------------------------------------------------------------------------- + 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 ); + + // add it to the end of our linked list + return bind(sNewMethod); + } + + + //========================================================================================================================================= + // Signal Disconnections + //========================================================================================================================================= + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Disconnect( FUNCTION_POINTER 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); + } + + + // Object 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); + + // search and remove it + return unbind(&sTemp); + } +}; + +#endif // __Signal12_h__ diff --git a/signal13.h b/signal13.h new file mode 100644 index 0000000..a034cc4 --- /dev/null +++ b/signal13.h @@ -0,0 +1,181 @@ + +#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). + */ +template +class Slot13 : public slot_base +{ + public: + /** + * Method which performs the actual callback. Must be overridden. + * + * @return Returns an object of type T_return; the result of the user callback. + */ + virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, 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 +// +template +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); + + Slot13_function( const FUNCTION_POINTER func ) + { + // convert and store function pointer in slot_base + this->data[0] = safe_horrible_cast(func); + } + + 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 + FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); + + // call function + return func(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); + } +}; + + +// +// a concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method') +// +template +class Slot13_method: public Slot13 +{ + public: + + 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); + } + + 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 + T_object* p_object = dangerous_horrible_cast(this->data[0]); + T_member p_member = dangerous_horrible_cast (this->data[1]); + + // call member function + return (p_object->*p_member)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); + } +}; + +//========================================================================================================================================= +// Signal tempplate. +//========================================================================================================================================= +template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2, typename T_arg3, typename T_arg4, typename T_arg5, typename T_arg6, typename T_arg7, typename T_arg8, typename T_arg9, typename T_arg10, typename T_arg11, typename T_arg12 > +class Signal13: public signal_base +{ + public: + + //----------------------------------------------------------------------------------------------------------------------------------------- + // Execute the Signal: + // - Walk the list of Slot nodes. + //----------------------------------------------------------------------------------------------------------------------------------------- + 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 defined( _DEBUG ) + printf("WARNING: Signal13<...> @ 0x%p recursive Emit attempt\n", this); +#endif + return; + } + + BeginEmit( ); + + list_node* cur = GetFirstNode( ); + + // iterate through the list + while( cur ) + { + // make the slot_base pointer a Slot13 pointer + Slot13* s = static_cast*>(cur->slot); + + // call the Signal + (*s)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); + + // move to next Slot in the list. + cur = cur->next; + } + + EndEmit( ); + } + + //========================================================================================================================================= + // Signal connections + //========================================================================================================================================= + 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 + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Connect( FUNCTION_POINTER 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); + } + + // Object methods + //----------------------------------------------------------------------------------------------------------------------------------------- + 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 ); + + // add it to the end of our linked list + return bind(sNewMethod); + } + + + //========================================================================================================================================= + // Signal Disconnections + //========================================================================================================================================= + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Disconnect( FUNCTION_POINTER 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); + } + + + // Object 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); + + // search and remove it + return unbind(&sTemp); + } +}; + +#endif // __Signal13_h__ diff --git a/signal14.h b/signal14.h new file mode 100644 index 0000000..1dc5785 --- /dev/null +++ b/signal14.h @@ -0,0 +1,181 @@ + +#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). + */ +template +class Slot14 : public slot_base +{ + public: + /** + * Method which performs the actual callback. Must be overridden. + * + * @return Returns an object of type T_return; the result of the user callback. + */ + virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, 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 +// +template +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); + + Slot14_function( const FUNCTION_POINTER func ) + { + // convert and store function pointer in slot_base + this->data[0] = safe_horrible_cast(func); + } + + 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 + FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); + + // call function + return func(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); + } +}; + + +// +// a concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method') +// +template +class Slot14_method: public Slot14 +{ + public: + + 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); + } + + 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 + T_object* p_object = dangerous_horrible_cast(this->data[0]); + T_member p_member = dangerous_horrible_cast (this->data[1]); + + // call member function + return (p_object->*p_member)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); + } +}; + +//========================================================================================================================================= +// Signal tempplate. +//========================================================================================================================================= +template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2, typename T_arg3, typename T_arg4, typename T_arg5, typename T_arg6, typename T_arg7, typename T_arg8, typename T_arg9, typename T_arg10, typename T_arg11, typename T_arg12, typename T_arg13 > +class Signal14: public signal_base +{ + public: + + //----------------------------------------------------------------------------------------------------------------------------------------- + // Execute the Signal: + // - Walk the list of Slot nodes. + //----------------------------------------------------------------------------------------------------------------------------------------- + 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 defined( _DEBUG ) + printf("WARNING: Signal14<...> @ 0x%p recursive Emit attempt\n", this); +#endif + return; + } + + BeginEmit( ); + + list_node* cur = GetFirstNode( ); + + // iterate through the list + while( cur ) + { + // make the slot_base pointer a Slot14 pointer + Slot14* s = static_cast*>(cur->slot); + + // call the Signal + (*s)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); + + // move to next Slot in the list. + cur = cur->next; + } + + EndEmit( ); + } + + //========================================================================================================================================= + // Signal connections + //========================================================================================================================================= + 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 + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Connect( FUNCTION_POINTER 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); + } + + // Object methods + //----------------------------------------------------------------------------------------------------------------------------------------- + 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 ); + + // add it to the end of our linked list + return bind(sNewMethod); + } + + + //========================================================================================================================================= + // Signal Disconnections + //========================================================================================================================================= + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Disconnect( FUNCTION_POINTER 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); + } + + + // Object 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); + + // search and remove it + return unbind(&sTemp); + } +}; + +#endif // __Signal14_h__ diff --git a/signal15.h b/signal15.h new file mode 100644 index 0000000..c65f40f --- /dev/null +++ b/signal15.h @@ -0,0 +1,181 @@ + +#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). + */ +template +class Slot15 : public slot_base +{ + public: + /** + * Method which performs the actual callback. Must be overridden. + * + * @return Returns an object of type T_return; the result of the user callback. + */ + virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, 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 +// +template +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); + + Slot15_function( const FUNCTION_POINTER func ) + { + // convert and store function pointer in slot_base + this->data[0] = safe_horrible_cast(func); + } + + 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 + FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); + + // call function + return func(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); + } +}; + + +// +// a concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method') +// +template +class Slot15_method: public Slot15 +{ + public: + + 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); + } + + 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 + T_object* p_object = dangerous_horrible_cast(this->data[0]); + T_member p_member = dangerous_horrible_cast (this->data[1]); + + // call member function + return (p_object->*p_member)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); + } +}; + +//========================================================================================================================================= +// Signal tempplate. +//========================================================================================================================================= +template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2, typename T_arg3, typename T_arg4, typename T_arg5, typename T_arg6, typename T_arg7, typename T_arg8, typename T_arg9, typename T_arg10, typename T_arg11, typename T_arg12, typename T_arg13, typename T_arg14 > +class Signal15: public signal_base +{ + public: + + //----------------------------------------------------------------------------------------------------------------------------------------- + // Execute the Signal: + // - Walk the list of Slot nodes. + //----------------------------------------------------------------------------------------------------------------------------------------- + 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 defined( _DEBUG ) + printf("WARNING: Signal15<...> @ 0x%p recursive Emit attempt\n", this); +#endif + return; + } + + BeginEmit( ); + + list_node* cur = GetFirstNode( ); + + // iterate through the list + while( cur ) + { + // make the slot_base pointer a Slot15 pointer + 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); + + // move to next Slot in the list. + cur = cur->next; + } + + EndEmit( ); + } + + //========================================================================================================================================= + // Signal connections + //========================================================================================================================================= + 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 + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Connect( FUNCTION_POINTER 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); + } + + // Object methods + //----------------------------------------------------------------------------------------------------------------------------------------- + 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 ); + + // add it to the end of our linked list + return bind(sNewMethod); + } + + + //========================================================================================================================================= + // Signal Disconnections + //========================================================================================================================================= + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Disconnect( FUNCTION_POINTER 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); + } + + + // Object 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); + + // search and remove it + return unbind(&sTemp); + } +}; + +#endif // __Signal15_h__ diff --git a/signal16.h b/signal16.h new file mode 100644 index 0000000..bec9829 --- /dev/null +++ b/signal16.h @@ -0,0 +1,181 @@ + +#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). + */ +template +class Slot16 : public slot_base +{ + public: + /** + * Method which performs the actual callback. Must be overridden. + * + * @return Returns an object of type T_return; the result of the user callback. + */ + virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, 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 +// +template +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); + + Slot16_function( const FUNCTION_POINTER func ) + { + // convert and store function pointer in slot_base + this->data[0] = safe_horrible_cast(func); + } + + 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 + FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); + + // call function + return func(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); + } +}; + + +// +// a concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method') +// +template +class Slot16_method: public Slot16 +{ + public: + + 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); + } + + 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 + T_object* p_object = dangerous_horrible_cast(this->data[0]); + T_member p_member = dangerous_horrible_cast (this->data[1]); + + // call member function + return (p_object->*p_member)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); + } +}; + +//========================================================================================================================================= +// Signal tempplate. +//========================================================================================================================================= +template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2, typename T_arg3, typename T_arg4, typename T_arg5, typename T_arg6, typename T_arg7, typename T_arg8, typename T_arg9, typename T_arg10, typename T_arg11, typename T_arg12, typename T_arg13, typename T_arg14, typename T_arg15 > +class Signal16: public signal_base +{ + public: + + //----------------------------------------------------------------------------------------------------------------------------------------- + // Execute the Signal: + // - Walk the list of Slot nodes. + //----------------------------------------------------------------------------------------------------------------------------------------- + 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 defined( _DEBUG ) + printf("WARNING: Signal16<...> @ 0x%p recursive Emit attempt\n", this); +#endif + return; + } + + BeginEmit( ); + + list_node* cur = GetFirstNode( ); + + // iterate through the list + while( cur ) + { + // make the slot_base pointer a Slot16 pointer + 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); + + // move to next Slot in the list. + cur = cur->next; + } + + EndEmit( ); + } + + //========================================================================================================================================= + // Signal connections + //========================================================================================================================================= + 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 + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Connect( FUNCTION_POINTER 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); + } + + // Object methods + //----------------------------------------------------------------------------------------------------------------------------------------- + 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 ); + + // add it to the end of our linked list + return bind(sNewMethod); + } + + + //========================================================================================================================================= + // Signal Disconnections + //========================================================================================================================================= + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Disconnect( FUNCTION_POINTER 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); + } + + + // Object 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); + + // search and remove it + return unbind(&sTemp); + } +}; + +#endif // __Signal16_h__ diff --git a/signal2.h b/signal2.h new file mode 100644 index 0000000..4b6f068 --- /dev/null +++ b/signal2.h @@ -0,0 +1,181 @@ + +#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). + */ +template +class Slot2 : public slot_base +{ + public: + /** + * Method which performs the actual callback. Must be overridden. + * + * @return Returns an object of type T_return; the result of the user callback. + */ + virtual T_return operator() (T_arg0 a0, T_arg1 a1) const = 0; +}; + + +// +// a concrete Slot class for a normal function +// +template +class Slot2_function: public Slot2 +{ + public: + + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1); + + Slot2_function( const FUNCTION_POINTER func ) + { + // convert and store function pointer in slot_base + this->data[0] = safe_horrible_cast(func); + } + + T_return operator() (T_arg0 a0, T_arg1 a1) const + { + // retrieve data from slot_base and convert back to a function pointer + FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); + + // call function + return func(a0, a1); + } +}; + + +// +// a concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method') +// +template +class Slot2_method: public Slot2 +{ + public: + + 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); + } + + T_return operator() (T_arg0 a0, T_arg1 a1) const + { + // retrieve data from slot_base and convert back to an object pointer and member function pointer + T_object* p_object = dangerous_horrible_cast(this->data[0]); + T_member p_member = dangerous_horrible_cast (this->data[1]); + + // call member function + return (p_object->*p_member)(a0, a1); + } +}; + +//========================================================================================================================================= +// Signal tempplate. +//========================================================================================================================================= +template< typename T_return, typename T_arg0, typename T_arg1 > +class Signal2: public signal_base +{ + public: + + //----------------------------------------------------------------------------------------------------------------------------------------- + // Execute the Signal: + // - Walk the list of Slot nodes. + //----------------------------------------------------------------------------------------------------------------------------------------- + void operator() (T_arg0 a0, T_arg1 a1) + { + if( IsSignalEmitting( ) ) + { +#if defined( _DEBUG ) + printf("WARNING: Signal2<...> @ 0x%p recursive Emit attempt\n", this); +#endif + return; + } + + BeginEmit( ); + + list_node* cur = GetFirstNode( ); + + // iterate through the list + while( cur ) + { + // make the slot_base pointer a Slot2 pointer + Slot2* s = static_cast*>(cur->slot); + + // call the Signal + (*s)(a0, a1); + + // move to next Slot in the list. + cur = cur->next; + } + + EndEmit( ); + } + + //========================================================================================================================================= + // Signal connections + //========================================================================================================================================= + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1); + + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Connect( FUNCTION_POINTER func ) + { + // make a copy of the Slot to store in our list + Slot2* sNewFunc = new Slot2_function( func ); + + // add it to the end of our linked list + return bind(sNewFunc); + } + + // Object methods + //----------------------------------------------------------------------------------------------------------------------------------------- + template + bool Connect(T_object* p_object, T_member p_member) + { + // make a copy of the Slot to store in our list + Slot2* sNewMethod = new Slot2_method( p_object, p_member ); + + // add it to the end of our linked list + return bind(sNewMethod); + } + + + //========================================================================================================================================= + // Signal Disconnections + //========================================================================================================================================= + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Disconnect( FUNCTION_POINTER func ) + { + // make a temporary Slot we can use to find a match in the list + Slot2_function sTest( func ); + + // search and remove it + return unbind(&sTest); + } + + + // Object method + //----------------------------------------------------------------------------------------------------------------------------------------- + template + bool Disconnect(T_object* p_object, T_member p_member) + { + // make a temporary Slot we can use to find a match in the list + Slot2_method sTemp(p_object,p_member); + + // search and remove it + return unbind(&sTemp); + } +}; + +#endif // __Signal2_h__ diff --git a/signal3.h b/signal3.h new file mode 100644 index 0000000..154ece2 --- /dev/null +++ b/signal3.h @@ -0,0 +1,181 @@ + +#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). + */ +template +class Slot3 : public slot_base +{ + public: + /** + * Method which performs the actual callback. Must be overridden. + * + * @return Returns an object of type T_return; the result of the user callback. + */ + virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2) const = 0; +}; + + +// +// a concrete Slot class for a normal function +// +template +class Slot3_function: public Slot3 +{ + public: + + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2); + + Slot3_function( const FUNCTION_POINTER func ) + { + // convert and store function pointer in slot_base + this->data[0] = safe_horrible_cast(func); + } + + T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2) const + { + // retrieve data from slot_base and convert back to a function pointer + FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); + + // call function + return func(a0, a1, a2); + } +}; + + +// +// a concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method') +// +template +class Slot3_method: public Slot3 +{ + public: + + 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); + } + + T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2) const + { + // retrieve data from slot_base and convert back to an object pointer and member function pointer + T_object* p_object = dangerous_horrible_cast(this->data[0]); + T_member p_member = dangerous_horrible_cast (this->data[1]); + + // call member function + return (p_object->*p_member)(a0, a1, a2); + } +}; + +//========================================================================================================================================= +// Signal tempplate. +//========================================================================================================================================= +template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2 > +class Signal3: public signal_base +{ + public: + + //----------------------------------------------------------------------------------------------------------------------------------------- + // Execute the Signal: + // - Walk the list of Slot nodes. + //----------------------------------------------------------------------------------------------------------------------------------------- + void operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2) + { + if( IsSignalEmitting( ) ) + { +#if defined( _DEBUG ) + printf("WARNING: Signal3<...> @ 0x%p recursive Emit attempt\n", this); +#endif + return; + } + + BeginEmit( ); + + list_node* cur = GetFirstNode( ); + + // iterate through the list + while( cur ) + { + // make the slot_base pointer a Slot3 pointer + Slot3* s = static_cast*>(cur->slot); + + // call the Signal + (*s)(a0, a1, a2); + + // move to next Slot in the list. + cur = cur->next; + } + + EndEmit( ); + } + + //========================================================================================================================================= + // Signal connections + //========================================================================================================================================= + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2); + + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Connect( FUNCTION_POINTER func ) + { + // make a copy of the Slot to store in our list + Slot3* sNewFunc = new Slot3_function( func ); + + // add it to the end of our linked list + return bind(sNewFunc); + } + + // Object methods + //----------------------------------------------------------------------------------------------------------------------------------------- + template + bool Connect(T_object* p_object, T_member p_member) + { + // make a copy of the Slot to store in our list + Slot3* sNewMethod = new Slot3_method( p_object, p_member ); + + // add it to the end of our linked list + return bind(sNewMethod); + } + + + //========================================================================================================================================= + // Signal Disconnections + //========================================================================================================================================= + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Disconnect( FUNCTION_POINTER func ) + { + // make a temporary Slot we can use to find a match in the list + Slot3_function sTest( func ); + + // search and remove it + return unbind(&sTest); + } + + + // Object method + //----------------------------------------------------------------------------------------------------------------------------------------- + template + bool Disconnect(T_object* p_object, T_member p_member) + { + // make a temporary Slot we can use to find a match in the list + Slot3_method sTemp(p_object,p_member); + + // search and remove it + return unbind(&sTemp); + } +}; + +#endif // __Signal3_h__ diff --git a/signal4.h b/signal4.h new file mode 100644 index 0000000..76a1025 --- /dev/null +++ b/signal4.h @@ -0,0 +1,181 @@ + +#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). + */ +template +class Slot4 : public slot_base +{ + public: + /** + * Method which performs the actual callback. Must be overridden. + * + * @return Returns an object of type T_return; the result of the user callback. + */ + virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3) const = 0; +}; + + +// +// a concrete Slot class for a normal function +// +template +class Slot4_function: public Slot4 +{ + public: + + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3); + + Slot4_function( const FUNCTION_POINTER func ) + { + // convert and store function pointer in slot_base + this->data[0] = safe_horrible_cast(func); + } + + T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3) const + { + // retrieve data from slot_base and convert back to a function pointer + FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); + + // call function + return func(a0, a1, a2, a3); + } +}; + + +// +// a concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method') +// +template +class Slot4_method: public Slot4 +{ + public: + + 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); + } + + T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3) const + { + // retrieve data from slot_base and convert back to an object pointer and member function pointer + T_object* p_object = dangerous_horrible_cast(this->data[0]); + T_member p_member = dangerous_horrible_cast (this->data[1]); + + // call member function + return (p_object->*p_member)(a0, a1, a2, a3); + } +}; + +//========================================================================================================================================= +// Signal tempplate. +//========================================================================================================================================= +template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2, typename T_arg3 > +class Signal4: public signal_base +{ + public: + + //----------------------------------------------------------------------------------------------------------------------------------------- + // Execute the Signal: + // - Walk the list of Slot nodes. + //----------------------------------------------------------------------------------------------------------------------------------------- + void operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3) + { + if( IsSignalEmitting( ) ) + { +#if defined( _DEBUG ) + printf("WARNING: Signal4<...> @ 0x%p recursive Emit attempt\n", this); +#endif + return; + } + + BeginEmit( ); + + list_node* cur = GetFirstNode( ); + + // iterate through the list + while( cur ) + { + // make the slot_base pointer a Slot4 pointer + Slot4* s = static_cast*>(cur->slot); + + // call the Signal + (*s)(a0, a1, a2, a3); + + // move to next Slot in the list. + cur = cur->next; + } + + EndEmit( ); + } + + //========================================================================================================================================= + // Signal connections + //========================================================================================================================================= + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3); + + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Connect( FUNCTION_POINTER func ) + { + // make a copy of the Slot to store in our list + Slot4* sNewFunc = new Slot4_function( func ); + + // add it to the end of our linked list + return bind(sNewFunc); + } + + // Object methods + //----------------------------------------------------------------------------------------------------------------------------------------- + template + bool Connect(T_object* p_object, T_member p_member) + { + // make a copy of the Slot to store in our list + Slot4* sNewMethod = new Slot4_method( p_object, p_member ); + + // add it to the end of our linked list + return bind(sNewMethod); + } + + + //========================================================================================================================================= + // Signal Disconnections + //========================================================================================================================================= + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Disconnect( FUNCTION_POINTER func ) + { + // make a temporary Slot we can use to find a match in the list + Slot4_function sTest( func ); + + // search and remove it + return unbind(&sTest); + } + + + // Object method + //----------------------------------------------------------------------------------------------------------------------------------------- + template + bool Disconnect(T_object* p_object, T_member p_member) + { + // make a temporary Slot we can use to find a match in the list + Slot4_method sTemp(p_object,p_member); + + // search and remove it + return unbind(&sTemp); + } +}; + +#endif // __Signal4_h__ diff --git a/signal5.h b/signal5.h new file mode 100644 index 0000000..6fd958b --- /dev/null +++ b/signal5.h @@ -0,0 +1,181 @@ + +#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). + */ +template +class Slot5 : public slot_base +{ + public: + /** + * Method which performs the actual callback. Must be overridden. + * + * @return Returns an object of type T_return; the result of the user callback. + */ + virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4) const = 0; +}; + + +// +// a concrete Slot class for a normal function +// +template +class Slot5_function: public Slot5 +{ + public: + + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4); + + Slot5_function( const FUNCTION_POINTER func ) + { + // convert and store function pointer in slot_base + this->data[0] = safe_horrible_cast(func); + } + + T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4) const + { + // retrieve data from slot_base and convert back to a function pointer + FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); + + // call function + return func(a0, a1, a2, a3, a4); + } +}; + + +// +// a concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method') +// +template +class Slot5_method: public Slot5 +{ + public: + + 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); + } + + T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4) const + { + // retrieve data from slot_base and convert back to an object pointer and member function pointer + T_object* p_object = dangerous_horrible_cast(this->data[0]); + T_member p_member = dangerous_horrible_cast (this->data[1]); + + // call member function + return (p_object->*p_member)(a0, a1, a2, a3, a4); + } +}; + +//========================================================================================================================================= +// Signal tempplate. +//========================================================================================================================================= +template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2, typename T_arg3, typename T_arg4 > +class Signal5: public signal_base +{ + public: + + //----------------------------------------------------------------------------------------------------------------------------------------- + // Execute the Signal: + // - Walk the list of Slot nodes. + //----------------------------------------------------------------------------------------------------------------------------------------- + void operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4) + { + if( IsSignalEmitting( ) ) + { +#if defined( _DEBUG ) + printf("WARNING: Signal5<...> @ 0x%p recursive Emit attempt\n", this); +#endif + return; + } + + BeginEmit( ); + + list_node* cur = GetFirstNode( ); + + // iterate through the list + while( cur ) + { + // make the slot_base pointer a Slot5 pointer + Slot5* s = static_cast*>(cur->slot); + + // call the Signal + (*s)(a0, a1, a2, a3, a4); + + // move to next Slot in the list. + cur = cur->next; + } + + EndEmit( ); + } + + //========================================================================================================================================= + // Signal connections + //========================================================================================================================================= + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4); + + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Connect( FUNCTION_POINTER func ) + { + // make a copy of the Slot to store in our list + Slot5* sNewFunc = new Slot5_function( func ); + + // add it to the end of our linked list + return bind(sNewFunc); + } + + // Object methods + //----------------------------------------------------------------------------------------------------------------------------------------- + template + bool Connect(T_object* p_object, T_member p_member) + { + // make a copy of the Slot to store in our list + Slot5* sNewMethod = new Slot5_method( p_object, p_member ); + + // add it to the end of our linked list + return bind(sNewMethod); + } + + + //========================================================================================================================================= + // Signal Disconnections + //========================================================================================================================================= + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Disconnect( FUNCTION_POINTER func ) + { + // make a temporary Slot we can use to find a match in the list + Slot5_function sTest( func ); + + // search and remove it + return unbind(&sTest); + } + + + // Object method + //----------------------------------------------------------------------------------------------------------------------------------------- + template + bool Disconnect(T_object* p_object, T_member p_member) + { + // make a temporary Slot we can use to find a match in the list + Slot5_method sTemp(p_object,p_member); + + // search and remove it + return unbind(&sTemp); + } +}; + +#endif // __Signal5_h__ diff --git a/signal6.h b/signal6.h new file mode 100644 index 0000000..0537cb5 --- /dev/null +++ b/signal6.h @@ -0,0 +1,181 @@ + +#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). + */ +template +class Slot6 : public slot_base +{ + public: + /** + * Method which performs the actual callback. Must be overridden. + * + * @return Returns an object of type T_return; the result of the user callback. + */ + virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5) const = 0; +}; + + +// +// a concrete Slot class for a normal function +// +template +class Slot6_function: public Slot6 +{ + public: + + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5); + + Slot6_function( const FUNCTION_POINTER func ) + { + // convert and store function pointer in slot_base + this->data[0] = safe_horrible_cast(func); + } + + T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5) const + { + // retrieve data from slot_base and convert back to a function pointer + FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); + + // call function + return func(a0, a1, a2, a3, a4, a5); + } +}; + + +// +// a concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method') +// +template +class Slot6_method: public Slot6 +{ + public: + + 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); + } + + T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5) const + { + // retrieve data from slot_base and convert back to an object pointer and member function pointer + T_object* p_object = dangerous_horrible_cast(this->data[0]); + T_member p_member = dangerous_horrible_cast (this->data[1]); + + // call member function + return (p_object->*p_member)(a0, a1, a2, a3, a4, a5); + } +}; + +//========================================================================================================================================= +// Signal tempplate. +//========================================================================================================================================= +template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2, typename T_arg3, typename T_arg4, typename T_arg5 > +class Signal6: public signal_base +{ + public: + + //----------------------------------------------------------------------------------------------------------------------------------------- + // Execute the Signal: + // - Walk the list of Slot nodes. + //----------------------------------------------------------------------------------------------------------------------------------------- + void operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5) + { + if( IsSignalEmitting( ) ) + { +#if defined( _DEBUG ) + printf("WARNING: Signal6<...> @ 0x%p recursive Emit attempt\n", this); +#endif + return; + } + + BeginEmit( ); + + list_node* cur = GetFirstNode( ); + + // iterate through the list + while( cur ) + { + // make the slot_base pointer a Slot6 pointer + Slot6* s = static_cast*>(cur->slot); + + // call the Signal + (*s)(a0, a1, a2, a3, a4, a5); + + // move to next Slot in the list. + cur = cur->next; + } + + EndEmit( ); + } + + //========================================================================================================================================= + // Signal connections + //========================================================================================================================================= + typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5); + + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Connect( FUNCTION_POINTER func ) + { + // make a copy of the Slot to store in our list + Slot6* sNewFunc = new Slot6_function( func ); + + // add it to the end of our linked list + return bind(sNewFunc); + } + + // Object methods + //----------------------------------------------------------------------------------------------------------------------------------------- + template + bool Connect(T_object* p_object, T_member p_member) + { + // make a copy of the Slot to store in our list + Slot6* sNewMethod = new Slot6_method( p_object, p_member ); + + // add it to the end of our linked list + return bind(sNewMethod); + } + + + //========================================================================================================================================= + // Signal Disconnections + //========================================================================================================================================= + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Disconnect( FUNCTION_POINTER func ) + { + // make a temporary Slot we can use to find a match in the list + Slot6_function sTest( func ); + + // search and remove it + return unbind(&sTest); + } + + + // Object method + //----------------------------------------------------------------------------------------------------------------------------------------- + template + bool Disconnect(T_object* p_object, T_member p_member) + { + // make a temporary Slot we can use to find a match in the list + Slot6_method sTemp(p_object,p_member); + + // search and remove it + return unbind(&sTemp); + } +}; + +#endif // __Signal6_h__ diff --git a/signal7.h b/signal7.h new file mode 100644 index 0000000..3e76419 --- /dev/null +++ b/signal7.h @@ -0,0 +1,181 @@ + +#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). + */ +template +class Slot7 : public slot_base +{ + public: + /** + * Method which performs the actual callback. Must be overridden. + * + * @return Returns an object of type T_return; the result of the user callback. + */ + virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6) const = 0; +}; + + +// +// a concrete Slot class for a normal function +// +template +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); + + Slot7_function( const FUNCTION_POINTER func ) + { + // convert and store function pointer in slot_base + this->data[0] = safe_horrible_cast(func); + } + + 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 + FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); + + // call function + return func(a0, a1, a2, a3, a4, a5, a6); + } +}; + + +// +// a concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method') +// +template +class Slot7_method: public Slot7 +{ + public: + + 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); + } + + 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 + T_object* p_object = dangerous_horrible_cast(this->data[0]); + T_member p_member = dangerous_horrible_cast (this->data[1]); + + // call member function + return (p_object->*p_member)(a0, a1, a2, a3, a4, a5, a6); + } +}; + +//========================================================================================================================================= +// Signal tempplate. +//========================================================================================================================================= +template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2, typename T_arg3, typename T_arg4, typename T_arg5, typename T_arg6 > +class Signal7: public signal_base +{ + public: + + //----------------------------------------------------------------------------------------------------------------------------------------- + // Execute the Signal: + // - Walk the list of Slot nodes. + //----------------------------------------------------------------------------------------------------------------------------------------- + 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 defined( _DEBUG ) + printf("WARNING: Signal7<...> @ 0x%p recursive Emit attempt\n", this); +#endif + return; + } + + BeginEmit( ); + + list_node* cur = GetFirstNode( ); + + // iterate through the list + while( cur ) + { + // make the slot_base pointer a Slot7 pointer + Slot7* s = static_cast*>(cur->slot); + + // call the Signal + (*s)(a0, a1, a2, a3, a4, a5, a6); + + // move to next Slot in the list. + cur = cur->next; + } + + EndEmit( ); + } + + //========================================================================================================================================= + // Signal connections + //========================================================================================================================================= + 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 + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Connect( FUNCTION_POINTER 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); + } + + // Object methods + //----------------------------------------------------------------------------------------------------------------------------------------- + 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 ); + + // add it to the end of our linked list + return bind(sNewMethod); + } + + + //========================================================================================================================================= + // Signal Disconnections + //========================================================================================================================================= + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Disconnect( FUNCTION_POINTER 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); + } + + + // Object 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); + + // search and remove it + return unbind(&sTemp); + } +}; + +#endif // __Signal7_h__ diff --git a/signal8.h b/signal8.h new file mode 100644 index 0000000..9cc81c6 --- /dev/null +++ b/signal8.h @@ -0,0 +1,181 @@ + +#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). + */ +template +class Slot8 : public slot_base +{ + public: + /** + * Method which performs the actual callback. Must be overridden. + * + * @return Returns an object of type T_return; the result of the user callback. + */ + virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7) const = 0; +}; + + +// +// a concrete Slot class for a normal function +// +template +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); + + Slot8_function( const FUNCTION_POINTER func ) + { + // convert and store function pointer in slot_base + this->data[0] = safe_horrible_cast(func); + } + + 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 + FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); + + // call function + return func(a0, a1, a2, a3, a4, a5, a6, a7); + } +}; + + +// +// a concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method') +// +template +class Slot8_method: public Slot8 +{ + public: + + 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); + } + + 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 + T_object* p_object = dangerous_horrible_cast(this->data[0]); + T_member p_member = dangerous_horrible_cast (this->data[1]); + + // call member function + return (p_object->*p_member)(a0, a1, a2, a3, a4, a5, a6, a7); + } +}; + +//========================================================================================================================================= +// Signal tempplate. +//========================================================================================================================================= +template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2, typename T_arg3, typename T_arg4, typename T_arg5, typename T_arg6, typename T_arg7 > +class Signal8: public signal_base +{ + public: + + //----------------------------------------------------------------------------------------------------------------------------------------- + // Execute the Signal: + // - Walk the list of Slot nodes. + //----------------------------------------------------------------------------------------------------------------------------------------- + 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 defined( _DEBUG ) + printf("WARNING: Signal8<...> @ 0x%p recursive Emit attempt\n", this); +#endif + return; + } + + BeginEmit( ); + + list_node* cur = GetFirstNode( ); + + // iterate through the list + while( cur ) + { + // make the slot_base pointer a Slot8 pointer + Slot8* s = static_cast*>(cur->slot); + + // call the Signal + (*s)(a0, a1, a2, a3, a4, a5, a6, a7); + + // move to next Slot in the list. + cur = cur->next; + } + + EndEmit( ); + } + + //========================================================================================================================================= + // Signal connections + //========================================================================================================================================= + 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 + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Connect( FUNCTION_POINTER 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); + } + + // Object methods + //----------------------------------------------------------------------------------------------------------------------------------------- + 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 ); + + // add it to the end of our linked list + return bind(sNewMethod); + } + + + //========================================================================================================================================= + // Signal Disconnections + //========================================================================================================================================= + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Disconnect( FUNCTION_POINTER 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); + } + + + // Object 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); + + // search and remove it + return unbind(&sTemp); + } +}; + +#endif // __Signal8_h__ diff --git a/signal9.h b/signal9.h new file mode 100644 index 0000000..b203d49 --- /dev/null +++ b/signal9.h @@ -0,0 +1,181 @@ + +#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). + */ +template +class Slot9 : public slot_base +{ + public: + /** + * Method which performs the actual callback. Must be overridden. + * + * @return Returns an object of type T_return; the result of the user callback. + */ + virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8) const = 0; +}; + + +// +// a concrete Slot class for a normal function +// +template +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); + + Slot9_function( const FUNCTION_POINTER func ) + { + // convert and store function pointer in slot_base + this->data[0] = safe_horrible_cast(func); + } + + 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 + FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); + + // call function + return func(a0, a1, a2, a3, a4, a5, a6, a7, a8); + } +}; + + +// +// a concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method') +// +template +class Slot9_method: public Slot9 +{ + public: + + 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); + } + + 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 + T_object* p_object = dangerous_horrible_cast(this->data[0]); + T_member p_member = dangerous_horrible_cast (this->data[1]); + + // call member function + return (p_object->*p_member)(a0, a1, a2, a3, a4, a5, a6, a7, a8); + } +}; + +//========================================================================================================================================= +// Signal tempplate. +//========================================================================================================================================= +template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2, typename T_arg3, typename T_arg4, typename T_arg5, typename T_arg6, typename T_arg7, typename T_arg8 > +class Signal9: public signal_base +{ + public: + + //----------------------------------------------------------------------------------------------------------------------------------------- + // Execute the Signal: + // - Walk the list of Slot nodes. + //----------------------------------------------------------------------------------------------------------------------------------------- + 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 defined( _DEBUG ) + printf("WARNING: Signal9<...> @ 0x%p recursive Emit attempt\n", this); +#endif + return; + } + + BeginEmit( ); + + list_node* cur = GetFirstNode( ); + + // iterate through the list + while( cur ) + { + // make the slot_base pointer a Slot9 pointer + Slot9* s = static_cast*>(cur->slot); + + // call the Signal + (*s)(a0, a1, a2, a3, a4, a5, a6, a7, a8); + + // move to next Slot in the list. + cur = cur->next; + } + + EndEmit( ); + } + + //========================================================================================================================================= + // Signal connections + //========================================================================================================================================= + 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 + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Connect( FUNCTION_POINTER 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); + } + + // Object methods + //----------------------------------------------------------------------------------------------------------------------------------------- + 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 ); + + // add it to the end of our linked list + return bind(sNewMethod); + } + + + //========================================================================================================================================= + // Signal Disconnections + //========================================================================================================================================= + // Functions + //----------------------------------------------------------------------------------------------------------------------------------------- + bool Disconnect( FUNCTION_POINTER 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); + } + + + // Object 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); + + // search and remove it + return unbind(&sTemp); + } +}; + +#endif // __Signal9_h__ diff --git a/signal_base.cpp b/signal_base.cpp index 38a0a76..a310c31 100644 --- a/signal_base.cpp +++ b/signal_base.cpp @@ -1,151 +1,271 @@ -#include -#include "signal_base.h" - -signal_base::signal_base() : head(0), tail(0) -{ - // empty -} - -signal_base::~signal_base() -{ - // clear the list - clear_list(); -} - -bool signal_base::bind(const slot_base& slot) -{ - // add it to our signal list - return add_to_list(slot); -} - -bool signal_base::unbind(const slot_base& slot) -{ - // look for corresponding list_node in list - list_node* n = find_in_list(slot); - - // see if we found a match - if ( !n ) - { - return false; // no match found - } - - // take it out of the linked list - remove_from_list(n); - - // free it - delete n; - - // found a match, success - return true; -} - -void signal_base::clear_list() -{ - // start at head - list_node* cur = head; - - // iterate - while ( cur ) - { - // save off next so we can safely delete - list_node* next = cur->next; - - // free - delete cur; - - // advance - cur = next; - } - - // reset head & tail - head = tail = 0; -} - -signal_base::list_node* signal_base::find_in_list(const slot_base& slot) const -{ - // start search at head of list - list_node* cur = head; - - // search list for slot - while ( cur ) - { - // see if this is a match - if ( cur->slot == slot ) - { - // we have a match, return it - return cur; - } - - // advance to next in list - cur = cur->next; - } - - // no match - return 0; -} - -bool signal_base::add_to_list(const slot_base& slot) -{ - // a sanity check - assert((head && tail) || (!head && !tail)); - - // make a new list_node to hold this slot in the list - list_node* n = new list_node; - if ( !n ) - { - return false; - } - - // initialize new list_node - n->slot = slot; // copy slot into list_node - n->prev = tail; // prev is tail because we'll put this list_node behind it (i.e. the new tail) - n->next = 0; // next is 0 because we'll put this list_node on the tail - - // add to tail - if ( tail ) - { - // tail exists, just append - tail->next = n; // insert item after current tail - tail = n; // now have a new tail - } - else - { - // list is currently empty, add this new list_node - head = tail = n; // now have a single list_node, which is also both the head and tail - } - - return true; -} - -void signal_base::remove_from_list(list_node* n) -{ - // do a little sanity checking - assert((head && tail) || (!head && !tail)); - assert(n->prev == 0 || n->prev->next == n); - assert(n->next == 0 || n->next->prev == n); - - // if this is the head, set the new head - if ( n == head ) - { - head = n->next; - } - - // if this is the tail, set the new tail - if ( n == tail ) - { - tail = n->prev; - } - - // set list to skip over this list_node - if ( n->prev ) - { - n->prev->next = n->next; - } - if ( n->next ) - { - n->next->prev = n->prev; - } -} - - - +#include +#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. + 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. + assert( 0 ); + return *this; +} + +//----------------------------------------------------------------------------------------------------------------------------------------- +int signal_base::Count( void ) +{ + int Count = 0; + + list_node* pIndex; + pIndex = head; + + while( pIndex ) + { + pIndex = pIndex->next; + 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 + list_node* n = find_in_list(slot); + + // see if we found a match + if( n ) + { + // If we are not processing a signal emit sequence, then release the node. + if( !IsSignalEmitting( ) ) + { + // take it out of the linked list + remove_from_list(n); + + // found a match, return success + return true; + } + // Otherwise mark it for removal. + else + { + n->bDeleteRequested = true; + return true; + } + } + + // no match + return false; +} + +//----------------------------------------------------------------------------------------------------------------------------------------- +signal_base::list_node::list_node(slot_base* s) : slot(s), + prev(0), + next(0), + bDeleteRequested(false) +{ + // empty +} + +//----------------------------------------------------------------------------------------------------------------------------------------- +signal_base::list_node::~list_node() +{ + // release the slot + delete slot; +} + + +//----------------------------------------------------------------------------------------------------------------------------------------- +signal_base::list_node* signal_base::GetFirstNode( void ) const +{ + return head; +} + +//----------------------------------------------------------------------------------------------------------------------------------------- +void signal_base::clear_list() +{ + // start at head + list_node* cur = head; + + // iterate + while ( cur ) + { + // save off next so we can safely delete + list_node* next = cur->next; + + // free + delete cur; + + // advance + cur = next; + } + + // reset head & tail + head = tail = 0; +} + +//----------------------------------------------------------------------------------------------------------------------------------------- +signal_base::list_node* signal_base::find_in_list(slot_base* slot) const +{ + // start search at head of list + list_node* cur = head; + + // search list for slot + while ( cur ) + { + // see if this is a match + if ( *(cur->slot) == *(slot) ) // note comparing values, not addresses !!! + { + // we have a match, return it + return cur; + } + + // advance to next in list + cur = cur->next; + } + + // no match + return 0; +} + +//----------------------------------------------------------------------------------------------------------------------------------------- +bool signal_base::add_to_list(slot_base* slot) +{ + // a sanity check + assert((head && tail) || (!head && !tail)); + + // make a new list_node to hold this slot in the list + // and initialize with this slot pointer + list_node* node = new list_node(slot); + assert(node); + if ( !node ) + { + return false; + } + + // setup new list_node + node->prev = tail; // prev is tail because we'll put this list_node behind it (i.e. the new tail) + node->next = 0; // next is 0 because we'll put this list_node on the tail + + // add to tail + if ( tail ) + { + // tail exists, just append + tail->next = node; // insert item after current tail + tail = node; // now have a new tail + } + else + { + // list is currently empty, add this new list_node + head = tail = node; // now have a single list_node, which is also both the head and tail + } + + return true; +} + +//----------------------------------------------------------------------------------------------------------------------------------------- +void signal_base::remove_from_list(list_node* n) +{ + // do a little sanity checking + assert((head && tail) || (!head && !tail)); + assert(n->prev == 0 || n->prev->next == n); + assert(n->next == 0 || n->next->prev == n); + + // if this is the head, set the new head + if ( n == head ) + { + head = n->next; + } + + // if this is the tail, set the new tail + if ( n == tail ) + { + tail = n->prev; + } + + // set list to skip over this list_node + if ( n->prev ) + { + n->prev->next = n->next; + } + if ( n->next ) + { + n->next->prev = n->prev; + } + + // finally, destroy the node + delete n; +} + +//----------------------------------------------------------------------------------------------------------------------------------------- +void signal_base::remove_pending_nodes( void ) +{ + list_node* pIndex; + list_node* pNext; + + pIndex = head; + + while( pIndex ) + { + // Prepare the next link in the list the removal stage. + pNext = pIndex->next; + + // Do we need to remove this link. + if( pIndex->bDeleteRequested ) + remove_from_list( pIndex ); + + // Go to the next item. + pIndex = pNext; + } +} + +//----------------------------------------------------------------------------------------------------------------------------------------- +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 d032bad..736d385 100644 --- a/signal_base.h +++ b/signal_base.h @@ -1,38 +1,121 @@ -#ifndef __signal_base_h__ -#define __signal_base_h__ - -#include "slot_base.h" - -class signal_base -{ - public: - - signal_base(); - virtual ~signal_base(); - - protected: - - bool bind(const slot_base& slot); - bool unbind(const slot_base& slot); - -// TEMP HACK private: - - // linked list data structure - struct list_node - { - slot_base slot; - list_node* prev; - list_node* next; - }; - list_node* head; - list_node* tail; - - // linked list manipulation - void clear_list(); - list_node* find_in_list(const slot_base& slot) const; - bool add_to_list(const slot_base& slot); - void remove_from_list(list_node* n); -}; - -#endif // __signal_base_h__ - +#ifndef __signal_base_h__ +#define __signal_base_h__ + +#include "slot_base.h" + + +/** + * ----------------------------------------------------------------------------------------------------------------------------------------- + * Signals - An elegant system of that manages software events and the callbacks that respond to them. + * ----------------------------------------------------------------------------------------------------------------------------------------- + * + * Each discrete signal represents a moment within your application that might require some reaction. A signal might represent a + * basketball going through the basket, or hitting the ground. Another signal might identify when a bullet was fired out of a gun. + * There is no limit to what the signal represents. + * + * The reactions that need to be processed through the signal system are called "Slots". Slots are nothing more than a common interface + * that the Signal can use to call many variations of callbacks with a single interface. Some have labelled slots as "Delegates" as they are + * not the actual code that performs the reaction, but instead are used to translate the common reaction request into the actual callback that + * is desired. Please see slot_base.h for more information. + * + */ +class signal_base +{ + public: + + signal_base(); + virtual ~signal_base(); + + signal_base( const signal_base& rSource ); + signal_base& operator=( const signal_base& rSource ); + + /** + * Determines the number of slots that are connected to the signal. + */ + int Count( void ); + + protected: + // linked list data structure + // used to maintain a list of pointers to slot_base.. no memory management is + // performed on the slot_base data - derived class should take care of this. + struct list_node + { + list_node(slot_base* s); + ~list_node(); + + slot_base* slot; + list_node* prev; + list_node* next; + + bool bDeleteRequested; + }; + + /** + * Request to add a slot to the signals reaction list that is processed when a signal is executed. + * + * @param slot A pointer to a slot base class that contains the required callback mechanism. + * + * @return true if the signal is able to add the slot. + * false if the signal could NOT add the slot. + */ + bool bind(slot_base* slot); + + /** + * Request to remove a slot from the signals reaction list. + * + * @param slot A pointer to a slot base class that contains the required callback mechanism. + * + * @return true if the signal is able to remove the slot. + * false if the signal could NOT remove the slot. + */ + 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: + /** + * Removes all slots that are connected to the signal + */ + void clear_list( ); + + /** + * Searches the slot list to find a slot that contains the same components. The location within the list is returned. + */ + list_node* find_in_list(slot_base* slot) const; + + /** + * Performs the actual operation of adding the slot to signal's internal list. + */ + bool add_to_list(slot_base* slot); + + /** + * Performs the actual operation of removing the slot from the signal's internal list. + */ + void remove_from_list(list_node* n); + + /** + * Removes any nodes that were tagged for deletion during the signal emit sequence + */ + void remove_pending_nodes( void ); + + //----------------------------------------------------------------------------------------------------------------------------------------- + list_node* head; + list_node* tail; + + bool bEmitting; +}; + +#endif // __signal_base_h__ + diff --git a/signal_template.h b/signal_template.h new file mode 100644 index 0000000..b214c5e --- /dev/null +++ b/signal_template.h @@ -0,0 +1,179 @@ +#ifndef __signal===NARG===_h__ +#define __signal===NARG===_h__ + +#include "horrible_cast.h" +#include "slot_base.h" +#include "signal_base.h" + + + +// +// Slot ===NARG=== +// + +// +// Abstract base class for Slots with ===NARG=== parameter(s). +// +template +class Slot===NARG=== : public slot_base +{ + public: + /** + * Method which performs the actual callback. Must be overridden. + * + * @return Returns an object of type T_return; the result of the user callback. + */ + virtual T_return operator() (===FORMAL_ARG_DECL===) const = 0; +}; + + +// +// A concrete Slot class for a normal function. +// +template +class Slot===NARG===_function: public Slot===NARG=== +{ + public: + + typedef T_return (*FUNCTION_POINTER)(===FORMAL_ARG_DECL===); + + Slot===NARG===_function( const FUNCTION_POINTER func ) + { + // convert and store function pointer in slot_base + this->data[0] = safe_horrible_cast(func); + } + + T_return operator() (===FORMAL_ARG_DECL===) const + { + // retrieve data from slot_base and convert back to a function pointer + FUNCTION_POINTER func = dangerous_horrible_cast(this->data[0]); + + // call function + return func(===FORMAL_ARG===); + } +}; + +// +// A concrete Slot class for an object pointer and method (usually 'this' and 'Class::Method'). +// +template +class Slot===NARG===_method: public Slot===NARG=== +{ + public: + + 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); + } + + T_return operator() (===FORMAL_ARG_DECL===) const + { + // retrieve data from slot_base and convert back to an object pointer and member function pointer + T_object* p_object = dangerous_horrible_cast(this->data[0]); + T_member p_member = dangerous_horrible_cast (this->data[1]); + + // call member function + return (p_object->*p_member)(===FORMAL_ARG===); + } +}; + + + +// +// Signal ===NARG=== +// +template< typename T_return===TEMPLATE_ARG_DECL=== > +class Signal===NARG===: public signal_base +{ + public: + + // Emit the signal. Iterate through the list of slots, and call each one. + void operator() (===FORMAL_ARG_DECL===) + { + // if we're already emitting, return (i.e. no re-entrancy) + if( IsSignalEmitting() ) + { +#if defined( _DEBUG ) + printf("WARNING: Signal===NARG===<...> @ 0x%p recursive Emit attempt\n", this); +#endif + return; + } + + // set emitting flag + BeginEmit(); + + // iterate through the list + list_node* cur = GetFirstNode(); + while( cur ) + { + // make the slot_base pointer a Slot===NARG=== pointer + Slot===NARG===* s = static_cast*>(cur->slot); + + // call the Signal + (*s)(===FORMAL_ARG===); + + // move to next Slot in the list. + cur = cur->next; + } + + // clear emitting flag + EndEmit( ); + } + + + // + // Signal connections + // + + // connect to normal functions + typedef T_return (*FUNCTION_POINTER)(===FORMAL_ARG_DECL===); // helper typedef + bool Connect( FUNCTION_POINTER 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); + } + + // 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 ); + + // add it to the end of our linked list + return bind(sNewMethod); + } + + + // + // signal disconnections + // + + // 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 ); + + // search and remove it + return 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); + + // search and remove it + return unbind(&sTemp); + } +}; + +#endif // __signal===NARG===_h__ diff --git a/slot_base.cpp b/slot_base.cpp index f6ab378..ed28cf9 100644 --- a/slot_base.cpp +++ b/slot_base.cpp @@ -3,9 +3,7 @@ bool slot_base::data_container::operator== (const slot_base::data_container& other) const { - // TODO: should use memcmp or equivalent - - // do a bytewise comparison + // do a wordwise comparison for (int i=0;idata[i] != other.data[i] ) @@ -27,7 +25,6 @@ void slot_base::data_container::zero() } } - slot_base::slot_base () { for (int i=0;i