Created
December 23, 2013 04:02
-
-
Save bithavoc/8091473 to your computer and use it in GitHub Desktop.
Demo of event list triggers in D
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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