Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fba319fe19
|
||
|
|
9889662529 | ||
|
|
c203ecc332 | ||
|
|
d43819f125 | ||
|
|
7f38b80fa8 | ||
|
|
889487107e | ||
|
|
4e90bc1163 | ||
|
|
334d028e7b | ||
|
|
6fd3ef36ab | ||
|
|
31380caccb |
No files matched your search
+11
@@ -0,0 +1,11 @@
|
||||
image: alpine/edge
|
||||
secrets:
|
||||
- 88cce185-d2ec-4573-9546-e33f36f79bbf
|
||||
sources:
|
||||
- git+ssh://git@git.sr.ht/~swaits/cpp-signal
|
||||
tasks:
|
||||
- mirror-to-github: |
|
||||
cd ~/cpp-signal
|
||||
ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
|
||||
git remote add github git@github.com:swaits/cpp-signal.git
|
||||
git push --mirror github
|
||||
@@ -0,0 +1,19 @@
|
||||
Copyright 2011 Stephen Waits <steve@waits.net>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the “Software”), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -4,16 +4,19 @@ cpp-signal
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This is a simple C++ callback library. It's conceptually similar to FastDelegate,
|
||||
with a primary goal of having an extremely simple, clean API. Secondary goals
|
||||
include low memory (low template bloat), zero external dependencies, and a high
|
||||
level of portability.
|
||||
This is a simple C++ callback library. It's conceptually similar to
|
||||
FastDelegate, Qt, and countless other "typesafe callbacks in C++" articles
|
||||
across the web.
|
||||
|
||||
Usage
|
||||
-----
|
||||
This library was developed with a primary goal of having an extremely simple,
|
||||
clean API. Secondary goals include low memory (low template bloat), zero
|
||||
external dependencies, and a high level of portability.
|
||||
|
||||
Using the library is incredibly simple. First, add the files to your project, Makefile,
|
||||
IDE, etc. Then, to use the library, simply include "signal.h".
|
||||
Quick Start
|
||||
-----------
|
||||
|
||||
Using the library is incredibly simple. First, add the files to your project,
|
||||
Makefile, IDE, etc. Then, to use the library, simply include "signal.h".
|
||||
|
||||
Here's a simple example:
|
||||
|
||||
@@ -43,6 +46,13 @@ Here's a simple example:
|
||||
}
|
||||
}
|
||||
|
||||
More thorough examples...
|
||||
-------------------------
|
||||
|
||||
Under the Hood
|
||||
--------------
|
||||
|
||||
|
||||
TO DO
|
||||
-----
|
||||
|
||||
@@ -0,0 +1,393 @@
|
||||
#LyX 1.5.0beta1 created this file. For more info see http://www.lyx.org/
|
||||
\lyxformat 262
|
||||
\begin_document
|
||||
\begin_header
|
||||
\textclass scrartcl
|
||||
\begin_preamble
|
||||
\usepackage{listings}
|
||||
\end_preamble
|
||||
\language english
|
||||
\inputencoding auto
|
||||
\font_roman times
|
||||
\font_sans helvet
|
||||
\font_typewriter courier
|
||||
\font_default_family default
|
||||
\font_sc false
|
||||
\font_osf false
|
||||
\font_sf_scale 100
|
||||
\font_tt_scale 100
|
||||
\graphics default
|
||||
\paperfontsize default
|
||||
\spacing single
|
||||
\papersize default
|
||||
\use_geometry false
|
||||
\use_amsmath 1
|
||||
\use_esint 1
|
||||
\cite_engine basic
|
||||
\use_bibtopic false
|
||||
\paperorientation portrait
|
||||
\secnumdepth 3
|
||||
\tocdepth 3
|
||||
\paragraph_separation indent
|
||||
\defskip medskip
|
||||
\quotes_language english
|
||||
\papercolumns 1
|
||||
\papersides 1
|
||||
\paperpagestyle default
|
||||
\tracking_changes false
|
||||
\output_changes false
|
||||
\author "swaits"
|
||||
\end_header
|
||||
|
||||
\begin_body
|
||||
|
||||
\begin_layout Title
|
||||
Signals and Slots
|
||||
\end_layout
|
||||
|
||||
\begin_layout Author
|
||||
Stephen Waits
|
||||
\end_layout
|
||||
|
||||
\begin_layout Date
|
||||
November 10, 2006
|
||||
\end_layout
|
||||
|
||||
\begin_layout Abstract
|
||||
This brief document provides an overview of the event and message handling
|
||||
system written for and used in the SCEA NBA PSP projects.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Section
|
||||
Goals
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
Basic synchronous messaging
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
Decouple game modules
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
Appropriate parameter handling (i.e.
|
||||
no blind parms, casting parms, etc.)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
Ease of use
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
Lightweight
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
Strive for elegant, clean, readable, and maintainable code
|
||||
\end_layout
|
||||
|
||||
\begin_layout Section
|
||||
History
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
When I started researching event messaging systems and libraries in early
|
||||
2004, I initially looked at what Qt and other similar libraries used.
|
||||
I ended up discovering libsigc++, which was my introduction to the signal/slot
|
||||
concept.
|
||||
Unfortunately, libsigc++, while fascinating, was much too big for my needs,
|
||||
so, I set out to write my own, simpler, lighter library.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
Once I got the library predominately functional, we integrated it into our
|
||||
codebase.
|
||||
I found that it took very little explanation to bring other programmers
|
||||
up to speed on the concepts and practical use of signals and slots.
|
||||
After using them for a bit, everyone on the team agreed that we had benefited
|
||||
greatly from adopting this simple concept throughout our code.
|
||||
The signals rocked for us.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
Today, I can confidently say that this single library alone bears great
|
||||
responsibility in the overall cleanliness and readability of our codebase.
|
||||
Without it, we'd have a giant pile of spaghetti by now.
|
||||
Instead, we have clear, simple, decoupled systems which all communicate
|
||||
via a common interface.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Section
|
||||
Usage
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
Signals are effectively emitters.
|
||||
Slots are effectively callback functions, methods, or functors.
|
||||
\end_layout
|
||||
|
||||
\begin_layout LyX-Code
|
||||
\begin_inset ERT
|
||||
status open
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
|
||||
\backslash
|
||||
lstset{language=C++}
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
|
||||
\backslash
|
||||
begin{lstlisting}
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
// create a signal
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
Signal< void, int /* x */, int /* y */ > OnClick;
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
// A function matching the signal's type
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
// (returns void, accepts 2 ints)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
void beep(int x, int y) { ...
|
||||
}
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
// A class method matching the signal's type
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
// (returns void, accepts 2 ints)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
struct Bark { void woof(int x, int y); }
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
Bark barker;
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
// connect a regular function
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
OnClick.Connect( beep ); // beep becomes a Slot<void,int,int>
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
// connect a member of a specific object
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
OnClick.Connect( &barker, &Bark::woof ); // woof is a Slot
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
// emit
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
OnClick(10,20); // calls beep(10,20) and barker.woof(10,20)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
// disconnect
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
OnClick.Disconnect( beep );
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
OnClick.Disconnect( &barker, &Bark::woof );
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
// note that this won't compile (type safety)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
void badbeep(int x, float y); // parameter mismatch
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
OnClick.Connect( badbeep ); // compile-time error!
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
||||
|
||||
\backslash
|
||||
end{lstlisting}
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
|
||||
\end_layout
|
||||
|
||||
\begin_layout Section
|
||||
In Practice
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
In our projects, we primarily use signals in two ways.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
First, we maintain a master list of global signals.
|
||||
These handle things such as a player stepping out of bounds, the ball hitting
|
||||
the backboard, a team calling timeout, and, basically everything that happens
|
||||
in basketball.
|
||||
This list of signals has grown quite large, but remains organized.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
Second, some classes include public signals.
|
||||
For example, class Clock might have a public signal named "Changed" which
|
||||
gets emitted any time its internal time is updated.
|
||||
The Clock object doesn't have to care if anyone connects - its responsibility
|
||||
ends at emission.
|
||||
Our UI system also makes heavy use of signals.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Section
|
||||
Summary
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsection
|
||||
Positives
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
Simple code is easy to use
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
Emitter/Subscriber model is rather nice to use and allows for massive decoupling
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
Synchronous emission
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
Static type safety (this is a huge plus!!!)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
Very easy to add to your project (it's almost entirely a template library)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsection
|
||||
Negatives
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
Current implementation does use some dynamic memory
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
Requires RTTI
|
||||
\begin_inset Foot
|
||||
status open
|
||||
|
||||
\begin_layout Standard
|
||||
RTTI is commonly thought to be the devil amongst uninformed game programmers;
|
||||
however, the only expense is one of a very slight size increase.
|
||||
Performance, possible slight caching consequences aside, generally remains
|
||||
the same.
|
||||
The convenience, in my opinion, vastly outweighs the cost.
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
; though only on Connect/Disconnect/IsConnected calls (normally infrequent)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
Not a negative to most, but does use some template-fu to keep things easy
|
||||
on the outside
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
Related to the template-fu, they can bloat; however, we've done our best
|
||||
to minimize this
|
||||
\end_layout
|
||||
|
||||
\begin_layout Itemize
|
||||
Return value heuristic never reached (i.e.
|
||||
what does the emitter return when calling multiple slots?)
|
||||
\end_layout
|
||||
|
||||
\end_body
|
||||
\end_document
|
||||
Binary file not shown.
+87
-7
@@ -1,10 +1,49 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
##############################################################
|
||||
# script to generate signal*.h files from signal_template.h
|
||||
# script to generate signal.h files from signalx.h.tpl, etc. #
|
||||
##############################################################
|
||||
|
||||
def make_header_file(nargs)
|
||||
#
|
||||
# configuration
|
||||
#
|
||||
|
||||
# maximum size signal/slot (in parameters) to generate
|
||||
MaxParameters = 6
|
||||
|
||||
#
|
||||
# some templates
|
||||
#
|
||||
Header = <<ENDSTR
|
||||
#ifndef __signal_h__
|
||||
#define __signal_h__
|
||||
|
||||
#include "horrible_cast.h"
|
||||
#include "slot_base.h"
|
||||
#include "signal_base.h"
|
||||
|
||||
|
||||
/*
|
||||
* Begin signal[X] definitions
|
||||
*/
|
||||
|
||||
ENDSTR
|
||||
|
||||
Middle = <<ENDSTR
|
||||
/*
|
||||
* Begin signal template definitions and specilizations
|
||||
*/
|
||||
|
||||
ENDSTR
|
||||
|
||||
Footer = <<ENDSTR
|
||||
#endif // __signal_h__
|
||||
ENDSTR
|
||||
|
||||
#
|
||||
# make signalX, slotX, and associated definitions from template file
|
||||
#
|
||||
def make_signal(nargs)
|
||||
# hash to store our substitutions in
|
||||
subs = {}
|
||||
|
||||
@@ -16,15 +55,56 @@ def make_header_file(nargs)
|
||||
subs["===FORMAL_ARG==="] = nargs.times.map { |i| "a#{i}" }.join(", ")
|
||||
|
||||
# load template file
|
||||
text = IO.read("signal_template.h")
|
||||
text = IO.read("signalx.h.tpl")
|
||||
|
||||
# do substitutions
|
||||
subs.each { |k,v| text.gsub!(k,v) }
|
||||
|
||||
# write output file
|
||||
File.open("signal#{nargs}.h","w") { |f| f.write(text) }
|
||||
# return result
|
||||
text
|
||||
end
|
||||
|
||||
# generate [signal0.h,signal16.h]
|
||||
(0..16).each { |i| make_header_file(i) }
|
||||
#
|
||||
# make the template for signal, pointing it to signalX
|
||||
#
|
||||
def make_template(nargs)
|
||||
text = ""
|
||||
|
||||
nargs.downto(0).each do |i|
|
||||
if i == nargs
|
||||
text += "struct nilarg;\n\n"
|
||||
default_arg = "=nilarg"
|
||||
else
|
||||
default_arg = ""
|
||||
end
|
||||
template_params = ( ["typename T_return"] + i.times.map { |i| "typename T_arg#{i}#{default_arg}" } ).join(", ")
|
||||
template_args = ( ["T_return" ] + i.times.map { |i| "T_arg#{i}" } ).join(", ")
|
||||
|
||||
if i == nargs
|
||||
text += "// full template for signal<> (signal<> inherits signal#{i}<>)\n"
|
||||
else
|
||||
text += "// partial specialization for signal<> with #{i} parameters (signal<> inherits signal#{i}<>)\n"
|
||||
end
|
||||
|
||||
text += "template <#{template_params}>\n"
|
||||
if i == nargs
|
||||
text += "class signal: public signal#{i}<#{template_args}> { /* empty class */ };\n"
|
||||
else
|
||||
text += "class signal<#{template_args}>: public signal#{i}<#{template_args}> { /* empty class */ };\n"
|
||||
end
|
||||
text += "\n"
|
||||
end
|
||||
text
|
||||
end
|
||||
|
||||
#
|
||||
# main program
|
||||
#
|
||||
File.open("signal.h","wt") do |f|
|
||||
f.puts Header
|
||||
(0..MaxParameters).each { |i| f.puts make_signal(i) }
|
||||
f.puts Middle
|
||||
f.puts make_template(MaxParameters)
|
||||
f.puts Footer
|
||||
end
|
||||
|
||||
@@ -1,214 +0,0 @@
|
||||
#ifndef __signal0_h__
|
||||
#define __signal0_h__
|
||||
|
||||
#include "horrible_cast.h"
|
||||
#include "slot_base.h"
|
||||
#include "signal_base.h"
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Method which performs the actual callback. Must be overridden.
|
||||
*
|
||||
* @return Returns an object of type T_return; the result of the user callback.
|
||||
*/
|
||||
virtual T_return operator() () const = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for a normal function.
|
||||
//
|
||||
template <typename T_return>
|
||||
class slot0_function: public slot0<T_return>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T_return (*FUNCTION_POINTER)(); // convenience typedef
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Converts a function pointer into raw data.
|
||||
*/
|
||||
slot0_function( const FUNCTION_POINTER func )
|
||||
{
|
||||
// convert and store function pointer in slot_base
|
||||
this->data[0] = safe_horrible_cast<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
|
||||
FUNCTION_POINTER func = dangerous_horrible_cast<FUNCTION_POINTER>(this->data[0]);
|
||||
|
||||
// call function
|
||||
return func();
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// 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>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Converts an object and method pointer into raw data.
|
||||
*/
|
||||
slot0_method(const T_object* p_object, const T_member p_member)
|
||||
{
|
||||
// convert and store object pointer and member function pointer in slot_base
|
||||
this->data[0] = safe_horrible_cast<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
|
||||
T_object* p_object = dangerous_horrible_cast<T_object*>(this->data[0]);
|
||||
T_member p_member = dangerous_horrible_cast<T_member> (this->data[1]);
|
||||
|
||||
// call member function
|
||||
return (p_object->*p_member)();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// class signal0
|
||||
//
|
||||
template< typename T_return >
|
||||
class signal0: public signal_base
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Emit the signal.
|
||||
*
|
||||
* Iterate through the list of slots, and call each one.
|
||||
*/
|
||||
void operator() ()
|
||||
{
|
||||
// if we're already emitting, return (i.e. no re-entrancy allowed)
|
||||
if( signal_base::emitting )
|
||||
{
|
||||
#if defined( _DEBUG )
|
||||
printf("WARNING: signal0<...> @ 0x%p recursive emit attempt\n", this);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// set emitting flag
|
||||
signal_base::emitting = true;
|
||||
|
||||
// iterate through the list
|
||||
signal_base::list_node* cur = signal_base::head;
|
||||
while( cur )
|
||||
{
|
||||
// cast the slot_base pointer to a slot0 pointer (converts from raw memory to pointer again)
|
||||
slot0<T_return>* s = static_cast<slot0<T_return>*>(cur->slot);
|
||||
|
||||
// call the signal as long as it's still valid
|
||||
if ( !cur->deleted )
|
||||
{
|
||||
(*s)();
|
||||
}
|
||||
|
||||
// move to next slot in the list.
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
// delete any pending slot deletions
|
||||
signal_base::remove_pending_nodes( );
|
||||
|
||||
// clear emitting flag
|
||||
signal_base::emitting = false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal connections to slots
|
||||
//
|
||||
|
||||
// convenience typedef
|
||||
typedef T_return (*FUNCTION_POINTER)();
|
||||
|
||||
// connect to normal functions
|
||||
bool connect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a copy of the slot to store in our list
|
||||
slot0<T_return>* sNewFunc = new slot0_function<T_return>( func );
|
||||
|
||||
// add it to the end of our linked list
|
||||
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
|
||||
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 signal_base::bind(sNewMethod);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal disconnections from slots
|
||||
//
|
||||
|
||||
// disconnect from a normal function
|
||||
bool disconnect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a temporary slot we can use to find a match in the list
|
||||
slot0_function<T_return> sTest( func );
|
||||
|
||||
// search and remove it
|
||||
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
|
||||
slot0_method<T_object,T_member,T_return> sTemp(p_object,p_member);
|
||||
|
||||
// search and remove it
|
||||
return signal_base::unbind(&sTemp);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __signal0_h__
|
||||
@@ -1,214 +0,0 @@
|
||||
#ifndef __signal1_h__
|
||||
#define __signal1_h__
|
||||
|
||||
#include "horrible_cast.h"
|
||||
#include "slot_base.h"
|
||||
#include "signal_base.h"
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Method which performs the actual callback. Must be overridden.
|
||||
*
|
||||
* @return Returns an object of type T_return; the result of the user callback.
|
||||
*/
|
||||
virtual T_return operator() (T_arg0 a0) const = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for a normal function.
|
||||
//
|
||||
template <typename T_return, typename T_arg0>
|
||||
class slot1_function: public slot1<T_return, T_arg0>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T_return (*FUNCTION_POINTER)(T_arg0 a0); // convenience typedef
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Converts a function pointer into raw data.
|
||||
*/
|
||||
slot1_function( const FUNCTION_POINTER func )
|
||||
{
|
||||
// convert and store function pointer in slot_base
|
||||
this->data[0] = safe_horrible_cast<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
|
||||
FUNCTION_POINTER func = dangerous_horrible_cast<FUNCTION_POINTER>(this->data[0]);
|
||||
|
||||
// call function
|
||||
return func(a0);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method').
|
||||
//
|
||||
template <class T_object, typename T_member, typename T_return, typename T_arg0>
|
||||
class slot1_method: public slot1<T_return, T_arg0>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Converts an object and method pointer into raw data.
|
||||
*/
|
||||
slot1_method(const T_object* p_object, const T_member p_member)
|
||||
{
|
||||
// convert and store object pointer and member function pointer in slot_base
|
||||
this->data[0] = safe_horrible_cast<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
|
||||
T_object* p_object = dangerous_horrible_cast<T_object*>(this->data[0]);
|
||||
T_member p_member = dangerous_horrible_cast<T_member> (this->data[1]);
|
||||
|
||||
// call member function
|
||||
return (p_object->*p_member)(a0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// class signal1
|
||||
//
|
||||
template< typename T_return, typename T_arg0 >
|
||||
class signal1: public signal_base
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Emit the signal.
|
||||
*
|
||||
* Iterate through the list of slots, and call each one.
|
||||
*/
|
||||
void operator() (T_arg0 a0)
|
||||
{
|
||||
// if we're already emitting, return (i.e. no re-entrancy allowed)
|
||||
if( signal_base::emitting )
|
||||
{
|
||||
#if defined( _DEBUG )
|
||||
printf("WARNING: signal1<...> @ 0x%p recursive emit attempt\n", this);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// set emitting flag
|
||||
signal_base::emitting = true;
|
||||
|
||||
// iterate through the list
|
||||
signal_base::list_node* cur = signal_base::head;
|
||||
while( cur )
|
||||
{
|
||||
// cast the slot_base pointer to a slot1 pointer (converts from raw memory to pointer again)
|
||||
slot1<T_return, T_arg0>* s = static_cast<slot1<T_return, T_arg0>*>(cur->slot);
|
||||
|
||||
// call the signal as long as it's still valid
|
||||
if ( !cur->deleted )
|
||||
{
|
||||
(*s)(a0);
|
||||
}
|
||||
|
||||
// move to next slot in the list.
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
// delete any pending slot deletions
|
||||
signal_base::remove_pending_nodes( );
|
||||
|
||||
// clear emitting flag
|
||||
signal_base::emitting = false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal connections to slots
|
||||
//
|
||||
|
||||
// convenience typedef
|
||||
typedef T_return (*FUNCTION_POINTER)(T_arg0 a0);
|
||||
|
||||
// connect to normal functions
|
||||
bool connect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a copy of the slot to store in our list
|
||||
slot1<T_return, T_arg0>* sNewFunc = new slot1_function<T_return, T_arg0>( func );
|
||||
|
||||
// add it to the end of our linked list
|
||||
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
|
||||
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 signal_base::bind(sNewMethod);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal disconnections from slots
|
||||
//
|
||||
|
||||
// disconnect from a normal function
|
||||
bool disconnect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a temporary slot we can use to find a match in the list
|
||||
slot1_function<T_return, T_arg0> sTest( func );
|
||||
|
||||
// search and remove it
|
||||
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
|
||||
slot1_method<T_object,T_member,T_return, T_arg0> sTemp(p_object,p_member);
|
||||
|
||||
// search and remove it
|
||||
return signal_base::unbind(&sTemp);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __signal1_h__
|
||||
-214
@@ -1,214 +0,0 @@
|
||||
#ifndef __signal10_h__
|
||||
#define __signal10_h__
|
||||
|
||||
#include "horrible_cast.h"
|
||||
#include "slot_base.h"
|
||||
#include "signal_base.h"
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Method which performs the actual callback. Must be overridden.
|
||||
*
|
||||
* @return Returns an object of type T_return; the result of the user callback.
|
||||
*/
|
||||
virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9) const = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for a normal function.
|
||||
//
|
||||
template <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>
|
||||
{
|
||||
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); // convenience typedef
|
||||
|
||||
/**
|
||||
* 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
|
||||
FUNCTION_POINTER func = dangerous_horrible_cast<FUNCTION_POINTER>(this->data[0]);
|
||||
|
||||
// call function
|
||||
return func(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method').
|
||||
//
|
||||
template <class 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>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* 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
|
||||
T_object* p_object = dangerous_horrible_cast<T_object*>(this->data[0]);
|
||||
T_member p_member = dangerous_horrible_cast<T_member> (this->data[1]);
|
||||
|
||||
// call member function
|
||||
return (p_object->*p_member)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Emit the signal.
|
||||
*
|
||||
* Iterate through the list of slots, and call each one.
|
||||
*/
|
||||
void operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9)
|
||||
{
|
||||
// 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);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// set emitting flag
|
||||
signal_base::emitting = true;
|
||||
|
||||
// iterate through the list
|
||||
signal_base::list_node* cur = signal_base::head;
|
||||
while( cur )
|
||||
{
|
||||
// cast the slot_base pointer to a 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 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.
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
// delete any pending slot deletions
|
||||
signal_base::remove_pending_nodes( );
|
||||
|
||||
// clear emitting flag
|
||||
signal_base::emitting = false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal connections to slots
|
||||
//
|
||||
|
||||
// convenience typedef
|
||||
typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9);
|
||||
|
||||
// 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 );
|
||||
|
||||
// add it to the end of our linked list
|
||||
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
|
||||
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 signal_base::bind(sNewMethod);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal disconnections from slots
|
||||
//
|
||||
|
||||
// disconnect from a normal function
|
||||
bool disconnect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a temporary slot we can use to find a match in the list
|
||||
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 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
|
||||
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 signal_base::unbind(&sTemp);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __signal10_h__
|
||||
-214
@@ -1,214 +0,0 @@
|
||||
#ifndef __signal11_h__
|
||||
#define __signal11_h__
|
||||
|
||||
#include "horrible_cast.h"
|
||||
#include "slot_base.h"
|
||||
#include "signal_base.h"
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Method which performs the actual callback. Must be overridden.
|
||||
*
|
||||
* @return Returns an object of type T_return; the result of the user callback.
|
||||
*/
|
||||
virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10) const = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for a normal function.
|
||||
//
|
||||
template <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>
|
||||
{
|
||||
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); // convenience typedef
|
||||
|
||||
/**
|
||||
* 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
|
||||
FUNCTION_POINTER func = dangerous_horrible_cast<FUNCTION_POINTER>(this->data[0]);
|
||||
|
||||
// call function
|
||||
return func(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method').
|
||||
//
|
||||
template <class 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>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* 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
|
||||
T_object* p_object = dangerous_horrible_cast<T_object*>(this->data[0]);
|
||||
T_member p_member = dangerous_horrible_cast<T_member> (this->data[1]);
|
||||
|
||||
// call member function
|
||||
return (p_object->*p_member)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Emit the signal.
|
||||
*
|
||||
* Iterate through the list of slots, and call each one.
|
||||
*/
|
||||
void operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10)
|
||||
{
|
||||
// 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);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// set emitting flag
|
||||
signal_base::emitting = true;
|
||||
|
||||
// iterate through the list
|
||||
signal_base::list_node* cur = signal_base::head;
|
||||
while( cur )
|
||||
{
|
||||
// cast the slot_base pointer to a 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 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.
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
// delete any pending slot deletions
|
||||
signal_base::remove_pending_nodes( );
|
||||
|
||||
// clear emitting flag
|
||||
signal_base::emitting = false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal connections to slots
|
||||
//
|
||||
|
||||
// convenience typedef
|
||||
typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10);
|
||||
|
||||
// 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 );
|
||||
|
||||
// add it to the end of our linked list
|
||||
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
|
||||
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 signal_base::bind(sNewMethod);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal disconnections from slots
|
||||
//
|
||||
|
||||
// disconnect from a normal function
|
||||
bool disconnect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a temporary slot we can use to find a match in the list
|
||||
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 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
|
||||
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 signal_base::unbind(&sTemp);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __signal11_h__
|
||||
-214
@@ -1,214 +0,0 @@
|
||||
#ifndef __signal12_h__
|
||||
#define __signal12_h__
|
||||
|
||||
#include "horrible_cast.h"
|
||||
#include "slot_base.h"
|
||||
#include "signal_base.h"
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Method which performs the actual callback. Must be overridden.
|
||||
*
|
||||
* @return Returns an object of type T_return; the result of the user callback.
|
||||
*/
|
||||
virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11) const = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for a normal function.
|
||||
//
|
||||
template <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>
|
||||
{
|
||||
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); // convenience typedef
|
||||
|
||||
/**
|
||||
* 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
|
||||
FUNCTION_POINTER func = dangerous_horrible_cast<FUNCTION_POINTER>(this->data[0]);
|
||||
|
||||
// call function
|
||||
return func(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method').
|
||||
//
|
||||
template <class 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>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* 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
|
||||
T_object* p_object = dangerous_horrible_cast<T_object*>(this->data[0]);
|
||||
T_member p_member = dangerous_horrible_cast<T_member> (this->data[1]);
|
||||
|
||||
// call member function
|
||||
return (p_object->*p_member)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Emit the signal.
|
||||
*
|
||||
* Iterate through the list of slots, and call each one.
|
||||
*/
|
||||
void operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11)
|
||||
{
|
||||
// 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);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// set emitting flag
|
||||
signal_base::emitting = true;
|
||||
|
||||
// iterate through the list
|
||||
signal_base::list_node* cur = signal_base::head;
|
||||
while( cur )
|
||||
{
|
||||
// cast the slot_base pointer to a 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 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.
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
// delete any pending slot deletions
|
||||
signal_base::remove_pending_nodes( );
|
||||
|
||||
// clear emitting flag
|
||||
signal_base::emitting = false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal connections to slots
|
||||
//
|
||||
|
||||
// convenience typedef
|
||||
typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11);
|
||||
|
||||
// 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 );
|
||||
|
||||
// add it to the end of our linked list
|
||||
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
|
||||
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 signal_base::bind(sNewMethod);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal disconnections from slots
|
||||
//
|
||||
|
||||
// disconnect from a normal function
|
||||
bool disconnect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a temporary slot we can use to find a match in the list
|
||||
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 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
|
||||
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 signal_base::unbind(&sTemp);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __signal12_h__
|
||||
-214
@@ -1,214 +0,0 @@
|
||||
#ifndef __signal13_h__
|
||||
#define __signal13_h__
|
||||
|
||||
#include "horrible_cast.h"
|
||||
#include "slot_base.h"
|
||||
#include "signal_base.h"
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Method which performs the actual callback. Must be overridden.
|
||||
*
|
||||
* @return Returns an object of type T_return; the result of the user callback.
|
||||
*/
|
||||
virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12) const = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for a normal function.
|
||||
//
|
||||
template <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>
|
||||
{
|
||||
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); // convenience typedef
|
||||
|
||||
/**
|
||||
* 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
|
||||
FUNCTION_POINTER func = dangerous_horrible_cast<FUNCTION_POINTER>(this->data[0]);
|
||||
|
||||
// call function
|
||||
return func(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method').
|
||||
//
|
||||
template <class 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>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* 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
|
||||
T_object* p_object = dangerous_horrible_cast<T_object*>(this->data[0]);
|
||||
T_member p_member = dangerous_horrible_cast<T_member> (this->data[1]);
|
||||
|
||||
// call member function
|
||||
return (p_object->*p_member)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Emit the signal.
|
||||
*
|
||||
* Iterate through the list of slots, and call each one.
|
||||
*/
|
||||
void operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12)
|
||||
{
|
||||
// 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);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// set emitting flag
|
||||
signal_base::emitting = true;
|
||||
|
||||
// iterate through the list
|
||||
signal_base::list_node* cur = signal_base::head;
|
||||
while( cur )
|
||||
{
|
||||
// cast the slot_base pointer to a 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 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.
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
// delete any pending slot deletions
|
||||
signal_base::remove_pending_nodes( );
|
||||
|
||||
// clear emitting flag
|
||||
signal_base::emitting = false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal connections to slots
|
||||
//
|
||||
|
||||
// convenience typedef
|
||||
typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12);
|
||||
|
||||
// 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 );
|
||||
|
||||
// add it to the end of our linked list
|
||||
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
|
||||
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 signal_base::bind(sNewMethod);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal disconnections from slots
|
||||
//
|
||||
|
||||
// disconnect from a normal function
|
||||
bool disconnect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a temporary slot we can use to find a match in the list
|
||||
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 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
|
||||
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 signal_base::unbind(&sTemp);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __signal13_h__
|
||||
-214
@@ -1,214 +0,0 @@
|
||||
#ifndef __signal14_h__
|
||||
#define __signal14_h__
|
||||
|
||||
#include "horrible_cast.h"
|
||||
#include "slot_base.h"
|
||||
#include "signal_base.h"
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Method which performs the actual callback. Must be overridden.
|
||||
*
|
||||
* @return Returns an object of type T_return; the result of the user callback.
|
||||
*/
|
||||
virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13) const = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for a normal function.
|
||||
//
|
||||
template <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>
|
||||
{
|
||||
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); // convenience typedef
|
||||
|
||||
/**
|
||||
* 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
|
||||
FUNCTION_POINTER func = dangerous_horrible_cast<FUNCTION_POINTER>(this->data[0]);
|
||||
|
||||
// call function
|
||||
return func(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method').
|
||||
//
|
||||
template <class 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>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* 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
|
||||
T_object* p_object = dangerous_horrible_cast<T_object*>(this->data[0]);
|
||||
T_member p_member = dangerous_horrible_cast<T_member> (this->data[1]);
|
||||
|
||||
// call member function
|
||||
return (p_object->*p_member)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Emit the signal.
|
||||
*
|
||||
* Iterate through the list of slots, and call each one.
|
||||
*/
|
||||
void operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, 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 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);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// set emitting flag
|
||||
signal_base::emitting = true;
|
||||
|
||||
// iterate through the list
|
||||
signal_base::list_node* cur = signal_base::head;
|
||||
while( cur )
|
||||
{
|
||||
// cast the slot_base pointer to a 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 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.
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
// delete any pending slot deletions
|
||||
signal_base::remove_pending_nodes( );
|
||||
|
||||
// clear emitting flag
|
||||
signal_base::emitting = false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal connections to slots
|
||||
//
|
||||
|
||||
// convenience typedef
|
||||
typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13);
|
||||
|
||||
// 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 );
|
||||
|
||||
// add it to the end of our linked list
|
||||
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
|
||||
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 signal_base::bind(sNewMethod);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal disconnections from slots
|
||||
//
|
||||
|
||||
// disconnect from a normal function
|
||||
bool disconnect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a temporary slot we can use to find a match in the list
|
||||
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 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
|
||||
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 signal_base::unbind(&sTemp);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __signal14_h__
|
||||
-214
@@ -1,214 +0,0 @@
|
||||
#ifndef __signal15_h__
|
||||
#define __signal15_h__
|
||||
|
||||
#include "horrible_cast.h"
|
||||
#include "slot_base.h"
|
||||
#include "signal_base.h"
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Method which performs the actual callback. Must be overridden.
|
||||
*
|
||||
* @return Returns an object of type T_return; the result of the user callback.
|
||||
*/
|
||||
virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13, T_arg14 a14) const = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for a normal function.
|
||||
//
|
||||
template <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>
|
||||
{
|
||||
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); // convenience typedef
|
||||
|
||||
/**
|
||||
* 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
|
||||
FUNCTION_POINTER func = dangerous_horrible_cast<FUNCTION_POINTER>(this->data[0]);
|
||||
|
||||
// call function
|
||||
return func(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method').
|
||||
//
|
||||
template <class 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>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* 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
|
||||
T_object* p_object = dangerous_horrible_cast<T_object*>(this->data[0]);
|
||||
T_member p_member = dangerous_horrible_cast<T_member> (this->data[1]);
|
||||
|
||||
// call member function
|
||||
return (p_object->*p_member)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Emit the signal.
|
||||
*
|
||||
* Iterate through the list of slots, and call each one.
|
||||
*/
|
||||
void operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, 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 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);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// set emitting flag
|
||||
signal_base::emitting = true;
|
||||
|
||||
// iterate through the list
|
||||
signal_base::list_node* cur = signal_base::head;
|
||||
while( cur )
|
||||
{
|
||||
// cast the slot_base pointer to a 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 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.
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
// delete any pending slot deletions
|
||||
signal_base::remove_pending_nodes( );
|
||||
|
||||
// clear emitting flag
|
||||
signal_base::emitting = false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal connections to slots
|
||||
//
|
||||
|
||||
// convenience typedef
|
||||
typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, 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);
|
||||
|
||||
// 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 );
|
||||
|
||||
// add it to the end of our linked list
|
||||
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
|
||||
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 signal_base::bind(sNewMethod);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal disconnections from slots
|
||||
//
|
||||
|
||||
// disconnect from a normal function
|
||||
bool disconnect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a temporary slot we can use to find a match in the list
|
||||
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 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
|
||||
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 signal_base::unbind(&sTemp);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __signal15_h__
|
||||
-214
@@ -1,214 +0,0 @@
|
||||
#ifndef __signal16_h__
|
||||
#define __signal16_h__
|
||||
|
||||
#include "horrible_cast.h"
|
||||
#include "slot_base.h"
|
||||
#include "signal_base.h"
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Method which performs the actual callback. Must be overridden.
|
||||
*
|
||||
* @return Returns an object of type T_return; the result of the user callback.
|
||||
*/
|
||||
virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8, T_arg9 a9, T_arg10 a10, T_arg11 a11, T_arg12 a12, T_arg13 a13, T_arg14 a14, T_arg15 a15) const = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for a normal function.
|
||||
//
|
||||
template <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>
|
||||
{
|
||||
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); // convenience typedef
|
||||
|
||||
/**
|
||||
* 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
|
||||
FUNCTION_POINTER func = dangerous_horrible_cast<FUNCTION_POINTER>(this->data[0]);
|
||||
|
||||
// call function
|
||||
return func(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method').
|
||||
//
|
||||
template <class 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>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* 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
|
||||
T_object* p_object = dangerous_horrible_cast<T_object*>(this->data[0]);
|
||||
T_member p_member = dangerous_horrible_cast<T_member> (this->data[1]);
|
||||
|
||||
// call member function
|
||||
return (p_object->*p_member)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Emit the signal.
|
||||
*
|
||||
* Iterate through the list of slots, and call each one.
|
||||
*/
|
||||
void operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, 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 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);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// set emitting flag
|
||||
signal_base::emitting = true;
|
||||
|
||||
// iterate through the list
|
||||
signal_base::list_node* cur = signal_base::head;
|
||||
while( cur )
|
||||
{
|
||||
// cast the slot_base pointer to a 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 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.
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
// delete any pending slot deletions
|
||||
signal_base::remove_pending_nodes( );
|
||||
|
||||
// clear emitting flag
|
||||
signal_base::emitting = false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal connections to slots
|
||||
//
|
||||
|
||||
// convenience typedef
|
||||
typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, 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);
|
||||
|
||||
// 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 );
|
||||
|
||||
// add it to the end of our linked list
|
||||
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
|
||||
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 signal_base::bind(sNewMethod);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal disconnections from slots
|
||||
//
|
||||
|
||||
// disconnect from a normal function
|
||||
bool disconnect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a temporary slot we can use to find a match in the list
|
||||
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 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
|
||||
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 signal_base::unbind(&sTemp);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __signal16_h__
|
||||
@@ -1,214 +0,0 @@
|
||||
#ifndef __signal2_h__
|
||||
#define __signal2_h__
|
||||
|
||||
#include "horrible_cast.h"
|
||||
#include "slot_base.h"
|
||||
#include "signal_base.h"
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Method which performs the actual callback. Must be overridden.
|
||||
*
|
||||
* @return Returns an object of type T_return; the result of the user callback.
|
||||
*/
|
||||
virtual T_return operator() (T_arg0 a0, T_arg1 a1) const = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for a normal function.
|
||||
//
|
||||
template <typename T_return, typename T_arg0, typename 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); // convenience typedef
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Converts a function pointer into raw data.
|
||||
*/
|
||||
slot2_function( const FUNCTION_POINTER func )
|
||||
{
|
||||
// convert and store function pointer in slot_base
|
||||
this->data[0] = safe_horrible_cast<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
|
||||
FUNCTION_POINTER func = dangerous_horrible_cast<FUNCTION_POINTER>(this->data[0]);
|
||||
|
||||
// call function
|
||||
return func(a0, a1);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method').
|
||||
//
|
||||
template <class 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>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Converts an object and method pointer into raw data.
|
||||
*/
|
||||
slot2_method(const T_object* p_object, const T_member p_member)
|
||||
{
|
||||
// convert and store object pointer and member function pointer in slot_base
|
||||
this->data[0] = safe_horrible_cast<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
|
||||
T_object* p_object = dangerous_horrible_cast<T_object*>(this->data[0]);
|
||||
T_member p_member = dangerous_horrible_cast<T_member> (this->data[1]);
|
||||
|
||||
// call member function
|
||||
return (p_object->*p_member)(a0, a1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// class signal2
|
||||
//
|
||||
template< typename T_return, typename T_arg0, typename T_arg1 >
|
||||
class signal2: public signal_base
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Emit the signal.
|
||||
*
|
||||
* Iterate through the list of slots, and call each one.
|
||||
*/
|
||||
void operator() (T_arg0 a0, T_arg1 a1)
|
||||
{
|
||||
// if we're already emitting, return (i.e. no re-entrancy allowed)
|
||||
if( signal_base::emitting )
|
||||
{
|
||||
#if defined( _DEBUG )
|
||||
printf("WARNING: signal2<...> @ 0x%p recursive emit attempt\n", this);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// set emitting flag
|
||||
signal_base::emitting = true;
|
||||
|
||||
// iterate through the list
|
||||
signal_base::list_node* cur = signal_base::head;
|
||||
while( cur )
|
||||
{
|
||||
// cast the slot_base pointer to a slot2 pointer (converts from raw memory to pointer again)
|
||||
slot2<T_return, T_arg0, T_arg1>* s = static_cast<slot2<T_return, T_arg0, T_arg1>*>(cur->slot);
|
||||
|
||||
// call the signal as long as it's still valid
|
||||
if ( !cur->deleted )
|
||||
{
|
||||
(*s)(a0, a1);
|
||||
}
|
||||
|
||||
// move to next slot in the list.
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
// delete any pending slot deletions
|
||||
signal_base::remove_pending_nodes( );
|
||||
|
||||
// clear emitting flag
|
||||
signal_base::emitting = false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal connections to slots
|
||||
//
|
||||
|
||||
// convenience typedef
|
||||
typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1);
|
||||
|
||||
// connect to normal functions
|
||||
bool connect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a copy of the slot to store in our list
|
||||
slot2<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 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
|
||||
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 signal_base::bind(sNewMethod);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal disconnections from slots
|
||||
//
|
||||
|
||||
// disconnect from a normal function
|
||||
bool disconnect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a temporary slot we can use to find a match in the list
|
||||
slot2_function<T_return, T_arg0, T_arg1> sTest( func );
|
||||
|
||||
// search and remove it
|
||||
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
|
||||
slot2_method<T_object,T_member,T_return, T_arg0, T_arg1> sTemp(p_object,p_member);
|
||||
|
||||
// search and remove it
|
||||
return signal_base::unbind(&sTemp);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __signal2_h__
|
||||
@@ -1,214 +0,0 @@
|
||||
#ifndef __signal3_h__
|
||||
#define __signal3_h__
|
||||
|
||||
#include "horrible_cast.h"
|
||||
#include "slot_base.h"
|
||||
#include "signal_base.h"
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Method which performs the actual callback. Must be overridden.
|
||||
*
|
||||
* @return Returns an object of type T_return; the result of the user callback.
|
||||
*/
|
||||
virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2) const = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for a normal function.
|
||||
//
|
||||
template <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>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2); // convenience typedef
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Converts a function pointer into raw data.
|
||||
*/
|
||||
slot3_function( const FUNCTION_POINTER func )
|
||||
{
|
||||
// convert and store function pointer in slot_base
|
||||
this->data[0] = safe_horrible_cast<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
|
||||
FUNCTION_POINTER func = dangerous_horrible_cast<FUNCTION_POINTER>(this->data[0]);
|
||||
|
||||
// call function
|
||||
return func(a0, a1, a2);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method').
|
||||
//
|
||||
template <class 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>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Converts an object and method pointer into raw data.
|
||||
*/
|
||||
slot3_method(const T_object* p_object, const T_member p_member)
|
||||
{
|
||||
// convert and store object pointer and member function pointer in slot_base
|
||||
this->data[0] = safe_horrible_cast<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
|
||||
T_object* p_object = dangerous_horrible_cast<T_object*>(this->data[0]);
|
||||
T_member p_member = dangerous_horrible_cast<T_member> (this->data[1]);
|
||||
|
||||
// call member function
|
||||
return (p_object->*p_member)(a0, a1, a2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// class signal3
|
||||
//
|
||||
template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2 >
|
||||
class signal3: public signal_base
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Emit the signal.
|
||||
*
|
||||
* Iterate through the list of slots, and call each one.
|
||||
*/
|
||||
void operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2)
|
||||
{
|
||||
// if we're already emitting, return (i.e. no re-entrancy allowed)
|
||||
if( signal_base::emitting )
|
||||
{
|
||||
#if defined( _DEBUG )
|
||||
printf("WARNING: signal3<...> @ 0x%p recursive emit attempt\n", this);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// set emitting flag
|
||||
signal_base::emitting = true;
|
||||
|
||||
// iterate through the list
|
||||
signal_base::list_node* cur = signal_base::head;
|
||||
while( cur )
|
||||
{
|
||||
// cast the slot_base pointer to a slot3 pointer (converts from raw memory to pointer again)
|
||||
slot3<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 as long as it's still valid
|
||||
if ( !cur->deleted )
|
||||
{
|
||||
(*s)(a0, a1, a2);
|
||||
}
|
||||
|
||||
// move to next slot in the list.
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
// delete any pending slot deletions
|
||||
signal_base::remove_pending_nodes( );
|
||||
|
||||
// clear emitting flag
|
||||
signal_base::emitting = false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal connections to slots
|
||||
//
|
||||
|
||||
// convenience typedef
|
||||
typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2);
|
||||
|
||||
// connect to normal functions
|
||||
bool connect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a copy of the slot to store in our list
|
||||
slot3<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 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
|
||||
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 signal_base::bind(sNewMethod);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal disconnections from slots
|
||||
//
|
||||
|
||||
// disconnect from a normal function
|
||||
bool disconnect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a temporary slot we can use to find a match in the list
|
||||
slot3_function<T_return, T_arg0, T_arg1, T_arg2> sTest( func );
|
||||
|
||||
// search and remove it
|
||||
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
|
||||
slot3_method<T_object,T_member,T_return, T_arg0, T_arg1, T_arg2> sTemp(p_object,p_member);
|
||||
|
||||
// search and remove it
|
||||
return signal_base::unbind(&sTemp);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __signal3_h__
|
||||
@@ -1,214 +0,0 @@
|
||||
#ifndef __signal4_h__
|
||||
#define __signal4_h__
|
||||
|
||||
#include "horrible_cast.h"
|
||||
#include "slot_base.h"
|
||||
#include "signal_base.h"
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Method which performs the actual callback. Must be overridden.
|
||||
*
|
||||
* @return Returns an object of type T_return; the result of the user callback.
|
||||
*/
|
||||
virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3) const = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for a normal function.
|
||||
//
|
||||
template <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>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3); // convenience typedef
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Converts a function pointer into raw data.
|
||||
*/
|
||||
slot4_function( const FUNCTION_POINTER func )
|
||||
{
|
||||
// convert and store function pointer in slot_base
|
||||
this->data[0] = safe_horrible_cast<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
|
||||
FUNCTION_POINTER func = dangerous_horrible_cast<FUNCTION_POINTER>(this->data[0]);
|
||||
|
||||
// call function
|
||||
return func(a0, a1, a2, a3);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method').
|
||||
//
|
||||
template <class 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>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Converts an object and method pointer into raw data.
|
||||
*/
|
||||
slot4_method(const T_object* p_object, const T_member p_member)
|
||||
{
|
||||
// convert and store object pointer and member function pointer in slot_base
|
||||
this->data[0] = safe_horrible_cast<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
|
||||
T_object* p_object = dangerous_horrible_cast<T_object*>(this->data[0]);
|
||||
T_member p_member = dangerous_horrible_cast<T_member> (this->data[1]);
|
||||
|
||||
// call member function
|
||||
return (p_object->*p_member)(a0, a1, a2, a3);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// class signal4
|
||||
//
|
||||
template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2, typename T_arg3 >
|
||||
class signal4: public signal_base
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Emit the signal.
|
||||
*
|
||||
* Iterate through the list of slots, and call each one.
|
||||
*/
|
||||
void operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3)
|
||||
{
|
||||
// if we're already emitting, return (i.e. no re-entrancy allowed)
|
||||
if( signal_base::emitting )
|
||||
{
|
||||
#if defined( _DEBUG )
|
||||
printf("WARNING: signal4<...> @ 0x%p recursive emit attempt\n", this);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// set emitting flag
|
||||
signal_base::emitting = true;
|
||||
|
||||
// iterate through the list
|
||||
signal_base::list_node* cur = signal_base::head;
|
||||
while( cur )
|
||||
{
|
||||
// cast the slot_base pointer to a slot4 pointer (converts from raw memory to pointer again)
|
||||
slot4<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 as long as it's still valid
|
||||
if ( !cur->deleted )
|
||||
{
|
||||
(*s)(a0, a1, a2, a3);
|
||||
}
|
||||
|
||||
// move to next slot in the list.
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
// delete any pending slot deletions
|
||||
signal_base::remove_pending_nodes( );
|
||||
|
||||
// clear emitting flag
|
||||
signal_base::emitting = false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal connections to slots
|
||||
//
|
||||
|
||||
// convenience typedef
|
||||
typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3);
|
||||
|
||||
// connect to normal functions
|
||||
bool connect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a copy of the slot to store in our list
|
||||
slot4<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 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
|
||||
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 signal_base::bind(sNewMethod);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal disconnections from slots
|
||||
//
|
||||
|
||||
// disconnect from a normal function
|
||||
bool disconnect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a temporary slot we can use to find a match in the list
|
||||
slot4_function<T_return, T_arg0, T_arg1, T_arg2, T_arg3> sTest( func );
|
||||
|
||||
// search and remove it
|
||||
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
|
||||
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 signal_base::unbind(&sTemp);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __signal4_h__
|
||||
@@ -1,214 +0,0 @@
|
||||
#ifndef __signal5_h__
|
||||
#define __signal5_h__
|
||||
|
||||
#include "horrible_cast.h"
|
||||
#include "slot_base.h"
|
||||
#include "signal_base.h"
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Method which performs the actual callback. Must be overridden.
|
||||
*
|
||||
* @return Returns an object of type T_return; the result of the user callback.
|
||||
*/
|
||||
virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4) const = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for a normal function.
|
||||
//
|
||||
template <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>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4); // convenience typedef
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Converts a function pointer into raw data.
|
||||
*/
|
||||
slot5_function( const FUNCTION_POINTER func )
|
||||
{
|
||||
// convert and store function pointer in slot_base
|
||||
this->data[0] = safe_horrible_cast<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
|
||||
FUNCTION_POINTER func = dangerous_horrible_cast<FUNCTION_POINTER>(this->data[0]);
|
||||
|
||||
// call function
|
||||
return func(a0, a1, a2, a3, a4);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method').
|
||||
//
|
||||
template <class 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>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Converts an object and method pointer into raw data.
|
||||
*/
|
||||
slot5_method(const T_object* p_object, const T_member p_member)
|
||||
{
|
||||
// convert and store object pointer and member function pointer in slot_base
|
||||
this->data[0] = safe_horrible_cast<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
|
||||
T_object* p_object = dangerous_horrible_cast<T_object*>(this->data[0]);
|
||||
T_member p_member = dangerous_horrible_cast<T_member> (this->data[1]);
|
||||
|
||||
// call member function
|
||||
return (p_object->*p_member)(a0, a1, a2, a3, a4);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// class signal5
|
||||
//
|
||||
template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2, typename T_arg3, typename T_arg4 >
|
||||
class signal5: public signal_base
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Emit the signal.
|
||||
*
|
||||
* Iterate through the list of slots, and call each one.
|
||||
*/
|
||||
void operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4)
|
||||
{
|
||||
// if we're already emitting, return (i.e. no re-entrancy allowed)
|
||||
if( signal_base::emitting )
|
||||
{
|
||||
#if defined( _DEBUG )
|
||||
printf("WARNING: signal5<...> @ 0x%p recursive emit attempt\n", this);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// set emitting flag
|
||||
signal_base::emitting = true;
|
||||
|
||||
// iterate through the list
|
||||
signal_base::list_node* cur = signal_base::head;
|
||||
while( cur )
|
||||
{
|
||||
// cast the slot_base pointer to a slot5 pointer (converts from raw memory to pointer again)
|
||||
slot5<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 as long as it's still valid
|
||||
if ( !cur->deleted )
|
||||
{
|
||||
(*s)(a0, a1, a2, a3, a4);
|
||||
}
|
||||
|
||||
// move to next slot in the list.
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
// delete any pending slot deletions
|
||||
signal_base::remove_pending_nodes( );
|
||||
|
||||
// clear emitting flag
|
||||
signal_base::emitting = false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal connections to slots
|
||||
//
|
||||
|
||||
// convenience typedef
|
||||
typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4);
|
||||
|
||||
// connect to normal functions
|
||||
bool connect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a copy of the slot to store in our list
|
||||
slot5<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 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
|
||||
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 signal_base::bind(sNewMethod);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal disconnections from slots
|
||||
//
|
||||
|
||||
// disconnect from a normal function
|
||||
bool disconnect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a temporary slot we can use to find a match in the list
|
||||
slot5_function<T_return, T_arg0, T_arg1, T_arg2, T_arg3, T_arg4> sTest( func );
|
||||
|
||||
// search and remove it
|
||||
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
|
||||
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 signal_base::unbind(&sTemp);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __signal5_h__
|
||||
@@ -1,214 +0,0 @@
|
||||
#ifndef __signal6_h__
|
||||
#define __signal6_h__
|
||||
|
||||
#include "horrible_cast.h"
|
||||
#include "slot_base.h"
|
||||
#include "signal_base.h"
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Method which performs the actual callback. Must be overridden.
|
||||
*
|
||||
* @return Returns an object of type T_return; the result of the user callback.
|
||||
*/
|
||||
virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5) const = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for a normal function.
|
||||
//
|
||||
template <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>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5); // convenience typedef
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Converts a function pointer into raw data.
|
||||
*/
|
||||
slot6_function( const FUNCTION_POINTER func )
|
||||
{
|
||||
// convert and store function pointer in slot_base
|
||||
this->data[0] = safe_horrible_cast<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
|
||||
FUNCTION_POINTER func = dangerous_horrible_cast<FUNCTION_POINTER>(this->data[0]);
|
||||
|
||||
// call function
|
||||
return func(a0, a1, a2, a3, a4, a5);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method').
|
||||
//
|
||||
template <class 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>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Converts an object and method pointer into raw data.
|
||||
*/
|
||||
slot6_method(const T_object* p_object, const T_member p_member)
|
||||
{
|
||||
// convert and store object pointer and member function pointer in slot_base
|
||||
this->data[0] = safe_horrible_cast<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
|
||||
T_object* p_object = dangerous_horrible_cast<T_object*>(this->data[0]);
|
||||
T_member p_member = dangerous_horrible_cast<T_member> (this->data[1]);
|
||||
|
||||
// call member function
|
||||
return (p_object->*p_member)(a0, a1, a2, a3, a4, a5);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// class signal6
|
||||
//
|
||||
template< typename T_return, typename T_arg0, typename T_arg1, typename T_arg2, typename T_arg3, typename T_arg4, typename T_arg5 >
|
||||
class signal6: public signal_base
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Emit the signal.
|
||||
*
|
||||
* Iterate through the list of slots, and call each one.
|
||||
*/
|
||||
void operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5)
|
||||
{
|
||||
// if we're already emitting, return (i.e. no re-entrancy allowed)
|
||||
if( signal_base::emitting )
|
||||
{
|
||||
#if defined( _DEBUG )
|
||||
printf("WARNING: signal6<...> @ 0x%p recursive emit attempt\n", this);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// set emitting flag
|
||||
signal_base::emitting = true;
|
||||
|
||||
// iterate through the list
|
||||
signal_base::list_node* cur = signal_base::head;
|
||||
while( cur )
|
||||
{
|
||||
// cast the slot_base pointer to a slot6 pointer (converts from raw memory to pointer again)
|
||||
slot6<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 as long as it's still valid
|
||||
if ( !cur->deleted )
|
||||
{
|
||||
(*s)(a0, a1, a2, a3, a4, a5);
|
||||
}
|
||||
|
||||
// move to next slot in the list.
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
// delete any pending slot deletions
|
||||
signal_base::remove_pending_nodes( );
|
||||
|
||||
// clear emitting flag
|
||||
signal_base::emitting = false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal connections to slots
|
||||
//
|
||||
|
||||
// convenience typedef
|
||||
typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5);
|
||||
|
||||
// connect to normal functions
|
||||
bool connect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a copy of the slot to store in our list
|
||||
slot6<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 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
|
||||
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 signal_base::bind(sNewMethod);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal disconnections from slots
|
||||
//
|
||||
|
||||
// disconnect from a normal function
|
||||
bool disconnect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a temporary slot we can use to find a match in the list
|
||||
slot6_function<T_return, T_arg0, T_arg1, T_arg2, T_arg3, T_arg4, T_arg5> sTest( func );
|
||||
|
||||
// search and remove it
|
||||
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
|
||||
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 signal_base::unbind(&sTemp);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __signal6_h__
|
||||
@@ -1,214 +0,0 @@
|
||||
#ifndef __signal7_h__
|
||||
#define __signal7_h__
|
||||
|
||||
#include "horrible_cast.h"
|
||||
#include "slot_base.h"
|
||||
#include "signal_base.h"
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Method which performs the actual callback. Must be overridden.
|
||||
*
|
||||
* @return Returns an object of type T_return; the result of the user callback.
|
||||
*/
|
||||
virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6) const = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for a normal function.
|
||||
//
|
||||
template <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>
|
||||
{
|
||||
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); // convenience typedef
|
||||
|
||||
/**
|
||||
* 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
|
||||
FUNCTION_POINTER func = dangerous_horrible_cast<FUNCTION_POINTER>(this->data[0]);
|
||||
|
||||
// call function
|
||||
return func(a0, a1, a2, a3, a4, a5, a6);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method').
|
||||
//
|
||||
template <class 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>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* 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
|
||||
T_object* p_object = dangerous_horrible_cast<T_object*>(this->data[0]);
|
||||
T_member p_member = dangerous_horrible_cast<T_member> (this->data[1]);
|
||||
|
||||
// call member function
|
||||
return (p_object->*p_member)(a0, a1, a2, a3, a4, a5, a6);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Emit the signal.
|
||||
*
|
||||
* Iterate through the list of slots, and call each one.
|
||||
*/
|
||||
void operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6)
|
||||
{
|
||||
// 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);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// set emitting flag
|
||||
signal_base::emitting = true;
|
||||
|
||||
// iterate through the list
|
||||
signal_base::list_node* cur = signal_base::head;
|
||||
while( cur )
|
||||
{
|
||||
// cast the slot_base pointer to a 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 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.
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
// delete any pending slot deletions
|
||||
signal_base::remove_pending_nodes( );
|
||||
|
||||
// clear emitting flag
|
||||
signal_base::emitting = false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal connections to slots
|
||||
//
|
||||
|
||||
// convenience typedef
|
||||
typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6);
|
||||
|
||||
// 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 );
|
||||
|
||||
// add it to the end of our linked list
|
||||
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
|
||||
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 signal_base::bind(sNewMethod);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal disconnections from slots
|
||||
//
|
||||
|
||||
// disconnect from a normal function
|
||||
bool disconnect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a temporary slot we can use to find a match in the list
|
||||
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 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
|
||||
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 signal_base::unbind(&sTemp);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __signal7_h__
|
||||
@@ -1,214 +0,0 @@
|
||||
#ifndef __signal8_h__
|
||||
#define __signal8_h__
|
||||
|
||||
#include "horrible_cast.h"
|
||||
#include "slot_base.h"
|
||||
#include "signal_base.h"
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Method which performs the actual callback. Must be overridden.
|
||||
*
|
||||
* @return Returns an object of type T_return; the result of the user callback.
|
||||
*/
|
||||
virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7) const = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for a normal function.
|
||||
//
|
||||
template <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>
|
||||
{
|
||||
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); // convenience typedef
|
||||
|
||||
/**
|
||||
* 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
|
||||
FUNCTION_POINTER func = dangerous_horrible_cast<FUNCTION_POINTER>(this->data[0]);
|
||||
|
||||
// call function
|
||||
return func(a0, a1, a2, a3, a4, a5, a6, a7);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method').
|
||||
//
|
||||
template <class 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>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* 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
|
||||
T_object* p_object = dangerous_horrible_cast<T_object*>(this->data[0]);
|
||||
T_member p_member = dangerous_horrible_cast<T_member> (this->data[1]);
|
||||
|
||||
// call member function
|
||||
return (p_object->*p_member)(a0, a1, a2, a3, a4, a5, a6, a7);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Emit the signal.
|
||||
*
|
||||
* Iterate through the list of slots, and call each one.
|
||||
*/
|
||||
void operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7)
|
||||
{
|
||||
// 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);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// set emitting flag
|
||||
signal_base::emitting = true;
|
||||
|
||||
// iterate through the list
|
||||
signal_base::list_node* cur = signal_base::head;
|
||||
while( cur )
|
||||
{
|
||||
// cast the slot_base pointer to a 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 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.
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
// delete any pending slot deletions
|
||||
signal_base::remove_pending_nodes( );
|
||||
|
||||
// clear emitting flag
|
||||
signal_base::emitting = false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal connections to slots
|
||||
//
|
||||
|
||||
// convenience typedef
|
||||
typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7);
|
||||
|
||||
// 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 );
|
||||
|
||||
// add it to the end of our linked list
|
||||
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
|
||||
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 signal_base::bind(sNewMethod);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal disconnections from slots
|
||||
//
|
||||
|
||||
// disconnect from a normal function
|
||||
bool disconnect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a temporary slot we can use to find a match in the list
|
||||
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 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
|
||||
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 signal_base::unbind(&sTemp);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __signal8_h__
|
||||
@@ -1,214 +0,0 @@
|
||||
#ifndef __signal9_h__
|
||||
#define __signal9_h__
|
||||
|
||||
#include "horrible_cast.h"
|
||||
#include "slot_base.h"
|
||||
#include "signal_base.h"
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Method which performs the actual callback. Must be overridden.
|
||||
*
|
||||
* @return Returns an object of type T_return; the result of the user callback.
|
||||
*/
|
||||
virtual T_return operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8) const = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for a normal function.
|
||||
//
|
||||
template <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>
|
||||
{
|
||||
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); // convenience typedef
|
||||
|
||||
/**
|
||||
* 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
|
||||
FUNCTION_POINTER func = dangerous_horrible_cast<FUNCTION_POINTER>(this->data[0]);
|
||||
|
||||
// call function
|
||||
return func(a0, a1, a2, a3, a4, a5, a6, a7, a8);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// A concrete slot class for an object pointer and method (usually 'this' and 'Class::Method').
|
||||
//
|
||||
template <class 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>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* 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
|
||||
T_object* p_object = dangerous_horrible_cast<T_object*>(this->data[0]);
|
||||
T_member p_member = dangerous_horrible_cast<T_member> (this->data[1]);
|
||||
|
||||
// call member function
|
||||
return (p_object->*p_member)(a0, a1, a2, a3, a4, a5, a6, a7, a8);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Emit the signal.
|
||||
*
|
||||
* Iterate through the list of slots, and call each one.
|
||||
*/
|
||||
void operator() (T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8)
|
||||
{
|
||||
// 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);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// set emitting flag
|
||||
signal_base::emitting = true;
|
||||
|
||||
// iterate through the list
|
||||
signal_base::list_node* cur = signal_base::head;
|
||||
while( cur )
|
||||
{
|
||||
// cast the slot_base pointer to a 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 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.
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
// delete any pending slot deletions
|
||||
signal_base::remove_pending_nodes( );
|
||||
|
||||
// clear emitting flag
|
||||
signal_base::emitting = false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal connections to slots
|
||||
//
|
||||
|
||||
// convenience typedef
|
||||
typedef T_return (*FUNCTION_POINTER)(T_arg0 a0, T_arg1 a1, T_arg2 a2, T_arg3 a3, T_arg4 a4, T_arg5 a5, T_arg6 a6, T_arg7 a7, T_arg8 a8);
|
||||
|
||||
// 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 );
|
||||
|
||||
// add it to the end of our linked list
|
||||
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
|
||||
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 signal_base::bind(sNewMethod);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// signal disconnections from slots
|
||||
//
|
||||
|
||||
// disconnect from a normal function
|
||||
bool disconnect( FUNCTION_POINTER func )
|
||||
{
|
||||
// make a temporary slot we can use to find a match in the list
|
||||
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 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
|
||||
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 signal_base::unbind(&sTemp);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __signal9_h__
|
||||
@@ -1,12 +1,7 @@
|
||||
|
||||
#ifndef __signal===NARG===_h__
|
||||
#define __signal===NARG===_h__
|
||||
|
||||
#include "horrible_cast.h"
|
||||
#include "slot_base.h"
|
||||
#include "signal_base.h"
|
||||
|
||||
|
||||
|
||||
//
|
||||
// classes slot===NARG===, slot===NARG===_function, and slot===NARG===_method
|
||||
//
|
||||
@@ -212,3 +207,4 @@ class signal===NARG===: public signal_base
|
||||
};
|
||||
|
||||
#endif // __signal===NARG===_h__
|
||||
|
||||
Reference in new issue
Block a user