quite a bit of refactoring. mostly formatting and renaming, slight amount of cleanup.

This commit is contained in:
swaits committed 2010-10-04 14:52:55 -07:00
1 parent 3b66e243ae
commit 9043e38ef2
23 files changed
+1856 -1416

No files matched your search

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