Signals and Slots in D
Walter Bright
newshound at digitalmars.com
Thu Sep 28 19:33:51 PDT 2006
Walter Bright wrote:
> Some of the boilerplate can be eliminated with a mixin.
Here's the mixin. Actually, 3 of them, one each for 0 arguments, 1
argument, and 2 arguments. I added a disconnect() function. Note how
trivial it is to use - no need for preprocessing.
import std.stdio;
template Signal() // for 0 arguments
{
void emit()
{
foreach (dg; slots)
dg();
}
void connect( void delegate() dg)
{
slots ~= dg;
}
void disconnect( void delegate() dg)
{
for (size_t i = 0; i < slots.length; i++)
{
if (slots[i] == dg)
{
if (i + 1 == slots.length)
slots = slots[0 .. i];
else
slots = slots[0 .. i] ~ slots[i + 1 .. length];
}
}
}
private:
void delegate()[] slots;
}
template Signal(T1) // for one argument
{
void emit( T1 i )
{
foreach (dg; slots)
dg(i);
}
void connect( void delegate(T1) dg)
{
slots ~= dg;
}
void disconnect( void delegate(T1) dg)
{
for (size_t i = 0; i < slots.length; i++)
{
if (slots[i] == dg)
{
if (i + 1 == slots.length)
slots = slots[0 .. i];
else
slots = slots[0 .. i] ~ slots[i + 1 .. length];
}
}
}
private:
void delegate(T1)[] slots;
}
template Signal(T1, T2) // for two arguments
{
void emit( T1 i, T2 j )
{
foreach (dg; slots)
dg(i, j);
}
void connect( void delegate(T1, T2) dg)
{
slots ~= dg;
}
void disconnect( void delegate(T1, T2) dg)
{
for (size_t i = 0; i < slots.length; i++)
{
if (slots[i] == dg)
{
if (i + 1 == slots.length)
slots = slots[0 .. i];
else
slots = slots[0 .. i] ~ slots[i + 1 .. length];
}
}
}
private:
void delegate(T1, T2)[] slots;
}
class Foo
{
this() { }
int value() { return val; }
void setValue( int v )
{
if ( v != val )
{
val = v;
emit(v);
}
}
mixin Signal!(int); // adds in all the boilerplate to make it work
private:
int val;
}
void main()
{
Foo a = new Foo;
Foo b = new Foo;
a.connect(&b.setValue);
b.setValue( 11 ); // a == 0 b == 11
a.setValue( 79 ); // a == 79 b == 79
writefln(b.value()); // prints 79
a.disconnect(&b.setValue);
a.setValue( 80);
writefln(b.value()); // prints 79
}
More information about the Digitalmars-d
mailing list