Events in D
kinke via Digitalmars-d
digitalmars-d at puremagic.com
Tue Aug 29 13:27:11 PDT 2017
On Tuesday, 29 August 2017 at 05:10:25 UTC, bitwise wrote:
> I needed some C# style events, so I rolled my own. Long story
> short, the result was unsatisfactory.
>
> [...]
> Anyways, I threw together some code while thinking about what
> an event may look like in D:
>
> [...]
I like the C# event syntax too and came up with the following D
analogon, just to prove that a primitive library-based solution
in D is doable in 35 lines and can offer as much comfort as C#
here.
struct Event(Args)
{
alias CB = void delegate(Args);
CB[] callbacks;
void opOpAssign(string op)(CB handler)
if (op == "+" || op == "-")
{
static if (op == "+")
callbacks ~= handler;
else
{
import std.algorithm.mutation : remove;
callbacks = callbacks.remove!(x => x == handler);
}
}
void opOpAssign(string op)(void function(Args) handler)
if (op == "+" || op == "-")
{
import std.functional : toDelegate;
opOpAssign!op(toDelegate(handler));
}
void opCall(Args args)
{
foreach (cb; callbacks)
cb(args);
}
bool opCast(T)()
if (is(T == bool))
{
return callbacks.length != 0;
}
}
The following test code prints the expected output:
struct S
{
int a;
void handler(int arg)
{
printf("S.handler: this.a = %d, arg = %d\n", a, arg);
}
}
void func(int arg) { printf("func: arg = %d\n", arg); }
void main()
{
Event!int onChanged;
auto s = S(666);
assert(!onChanged);
onChanged += (int arg) { printf("lambda: arg = %d\n", arg); };
onChanged += &func;
onChanged += &s.handler;
assert(onChanged);
onChanged(1);
onChanged -= &s.handler;
onChanged(2);
onChanged -= &func;
onChanged(3);
}
More information about the Digitalmars-d
mailing list