Here is the source code: http://c-sigslot.googlecode.com/files/sigslot.zip,
include the /boost/preprocessor which is used for macro definition.
(it is needed to specify the head files searching path to include the
source's root directory when compile the sources)
I wrote some words to explains how it works, but it is written in
Chinese. For my poor English I won't translate it in near future. If
you are interested in, please refer this thread:
http://groups.google.com/group/pongba/browse_thread/thread/883521543073ef8b,
some codes inside it maybe help to learn. Also there are some comments
in the source code released.
I said it is lambda-styled, that means, the slot/call-back codes is
written in common statements block. To create a signal-slot
connection, code will be:
SIGNAL_CONNECT(signal_ptr,
, (initialization statements; ...)
, (signal processing statements; ...)
, (finalization statements; ...)
);
SIGNAL_CONNECT is the macro interface, and signal_ptr is the address
of a signal.
The initialization statements will run in normal flow, around the
connection creation, and the signal processing statements will run
when the signal is emitted. At last, when the connection is
disconnected, the finalization statements will be invoked, so you can
free any resources allocated before then. You can refer any local/
global variables inside them.
For example, define a signal with two parameters, the type of first
one is int, and the second is float, then connect and emit it:
int main(int argc, char *argv[])
{
SLOT *slot;
SIGNAL2(int, float) signal;
SIGNAL_INIT(&signal);
slot = SIGNAL_CONNECT(&signal
, (
/* SLOT_SET_STACK_FRAME_SIZE(500); */
)
, (
printf("int=%d, float=%f\n", signal._1, signal._2);
)
, (
)
);
SIGNAL2_EMIT(5, 10.0);
SLOT_FREE(slot);
return 0;
}
the output will be: int=5, float=10.00000, or any equivalent.
you need append the 2 which specify the number of parameters behind
the SIGNAL symbol for macro limitation. and _1, _2 stand for the value
of parameters, to name it like place holder in boost/signal.
If refer the local variables of host function inside slot, but the
function will return before the signal is emitted, same as the
situation in concurrent code segment, you may use a macro inside the
initialization statements block: SLOT_FETCH_HOST_VAR[N](var1, var2...,
varN), the N suffix is also needed. For example continued:
void connect(struct __Signal *signal)
{
int i = 5;
float j = 10.0;
SIGNAL_CONNECT(signal
, (
/* SLOT_SET_STACK_FRAME_SIZE(180); */
SLOT_FETCH_HOST_VAR2(i, j);
)
, (
printf("int=%d, float=%f\n", i, j);
)
, (
)
);
}
int main(int argc, char *argv[])
{
SLOT *slot;
SIGNAL2(int, float) signal;
SIGNAL_INIT(&signal);
connect((struct __Signal *)&signal);
slot = SIGNAL_CONNECT(&signal
, (
)
, (
printf("int=%d, float=%f\n", signal._1, signal._2);
)
, (
)
);
SIGNAL2_EMIT(&signal, 5, 10);
SIGNAL2_EMIT(&signal, 50, 100);
SLOT_FREE(slot);
SIGNAL_FREE(&signal);
return 0;
}
so, the printf() call of the slot inside connect function will print
the last value of it is local variables: i, and j, the output will
always be: int=5, float=10.00000.
For those platform which don't has a proper dynamic stack allocation
operation though C99 VLA or alloca(),(see the SLOT_USE_C99_VLA or
SLOT_USE_ALLOCA boolean macros). you need specify the
SLOT_STACK_FRAME_SIZE macro before include directive. the value of it
must be larger than the slot host function stack frame size(large than
the amount size of local variables).
notice: GCC has the proper C99 VLA support as well as alloca(). But
the _alloca of MSVC doesn't work properly under release mode, it
allocate space other where of the stack.
It's compliant unit dependents, so you can specify
SLOT_STACK_FRAME_SIZE on top of each .c source file. There also be
some platform which use the stack pointer as the stack frame pointer,
or similarly, the stack frame pointer point the top of current stack.
(ARM ADS and MSVC release-mode compilation as I know). In such case,
it is possible allocated the stack frame dynamically without C99 VLA
and alloca() support, so you can define the frame size inside the slot
at runtime. just use the comment macro statement in the example codes:
SLOT_SET_STACK_FRAME_SIZE(180). Although at first, you need to specify
the macro SLOT_STACK_FRAME_REVERSE as 1.
Since it lambda style, the signal can be used as the equivalent of
functor in other languages. Also I used it to define a ASYNC_RUN
macro, so I can write:
ASYNC_RUN( statements ...);
whenever I need to make some codes run concurrently, etc.
refer the source archive for details, thanks very much.
--
comp.lang.c.moderated - moderation address: cl...@plethora.net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.