Skip to content

Instantly share code, notes, and snippets.

@bithavoc
Created December 23, 2013 04:02
Show Gist options
  • Select an option

  • Save bithavoc/8091473 to your computer and use it in GitHub Desktop.

Select an option

Save bithavoc/8091473 to your computer and use it in GitHub Desktop.
Demo of event list triggers in D
import std.stdio;
import std.algorithm;
import std.string;
// event list declared with string return value, first parameter as string and second parameters as int.
static EventList!(string, string, int) formatter;
// event list declared with no parameters and returning void.
static EventList!void voidEvents;
void main() {
auto a = 2;
formatter = new EventList!(string, string, int)();
// add a delegate to the list
formatter.add((text, value){
a++;
return text.format(value);
});
// same operation but with ^
formatter ^ (text, value) {
return "replaced by last call";
};
auto formatterTrigger = formatter.own;
auto text = formatterTrigger("hello %d", 23);
text.writeln;
voidEvents = new EventList!void;
auto voidEventsTrigger = voidEvents.own;
voidEventsTrigger.changed = (operation, dele) {
"subscription executed".writeln;
};
voidEvents ^ {
"simple to execute".writeln;
};
voidEventsTrigger();
}
enum EventListOperation {
Added,
Removed
}
class EventList(TReturn, Args...) {
private:
TReturn delegate(Args)[] _list;
Trigger _trigger;
void notify(EventListOperation operation, TReturn delegate(Args) item) {
if(_trigger && _trigger.changed) {
_trigger.changed(operation, item);
}
}
public:
auto opBinary(string op)(TReturn delegate(Args) rhs) {
static if (op == "^") {
this.add(rhs);
}
else static assert(0, "Operator "~op~" not implemented");
return this;
}
void add(TReturn delegate(Args args) item) {
_list ~= item;
this.notify(EventListOperation.Added, item);
}
final class Trigger {
private:
void delegate(EventListOperation operation, TReturn delegate(Args) item) changed;
package:
// protect constructor, use EventList.own instead
this() {
}
public:
auto opCall(Args args) {
return execute(args);
}
auto execute(Args args) {
static if (is( TReturn == void )) {
// it's void returning, don't do anything
foreach(d;_list) {
d(args);
}
} else {
// execute saving the last result
TReturn v;
foreach(d;_list) {
v = d(args);
}
return v;
}
}
}
auto own() {
if(_trigger !is null) {
throw new Exception("Event already owned");
}
return _trigger = new Trigger;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment