Events in D
bitwise via Digitalmars-d
digitalmars-d at puremagic.com
Mon Aug 28 22:10:25 PDT 2017
I needed some C# style events, so I rolled my own. Long story
short, the result was unsatisfactory.
Library based events are inadequate for basically the same
reasons as library based properties (often suggested/attempted in
C++). The problem is that the properties/events don't have access
to the fields or methods of the containing object, and as such,
incur the cost of an extra pointer per event/property, or worse,
a delegate if custom behavior per event is needed, in order to
provide that access. One obvious example would be synchronized
properties/events.
Anyways, I threw together some code while thinking about what an
event may look like in D:
struct Foo
{
List!(void function()) callbacks;
@event void onEvent(string op, Args...)(Args args)
{
static if(op == "+")
{
callbacks.add(args[0]);
}
else static if(op == "-")
{
callbacks.remove(args[0])
}
else static if(op == "()")
{
foreach(cb; callbacks)
cb(args);
}
}
// or..
@event {
void onEvent(string op, Args...)(Args args)
if(op == "+" && Args.length == 1 &&
isSomeFunction(Args[0]))
{
callbacks.add(args[0]);
}
void onEvent(string op, Args...)(Args args)
if(op == "-" && Args.length == 1 &&
isSomeFunction(Args[0]))
{
callbacks.remove(args[0]);
}
void onEvent(string op, Args...)(Args args)
if(op == "()" && __traits(compiles, {
callbacks[0](args); })
{
foreach(cb; callbacks)
cb(args);
}
// this could work in the example above
// if events just always returned an int
bool onEvent(string op, Args...)(Args args)
if(op == "!!" && Args.length == 0)
{
return !callbacks.empty;
}
}
}
void baz(int n) {
writeln(n);
}
so usage like this:
`
Foo foo;
foo.onEvent += (int n) => writeln(n);
foo.onEvent += &baz;
foo.onEvent -= &baz;
if(foo.onEvent)
foo.onEvent(1);
`
becomes this:
`
Foo foo;
foo.onEvent!"+"(() => writeln("bar"));
foo.onEvent!"+"(&baz);
foo.onEvent!"-"(&baz);
if(foo.onEvent!"!!"())
foo.onEvent!"()"(1);
`
and outputs this:
1
More information about the Digitalmars-d
mailing list