Event Dispatcher
Eugene Wissner via Digitalmars-d-announce
digitalmars-d-announce at puremagic.com
Thu Mar 10 10:08:15 PST 2016
Hey,
I wrote some time ago I'm working on the rewriting some parts of
Symfony web framework from PHP to D. One component is pretty
small and is already ready. It is an Event Dispatcher:
https://github.com/caraus-ecms/caraus (submodule
caraus:eventdispatcher).
Event dispatchers make it possible to write extensible
applications. You can register events in different places of your
application and attach callbacks to them. It is similar to
signals, but you have a central instance aware of all events and
callbacks (Mediator pattern:
https://en.wikipedia.org/wiki/Mediator_pattern).
It isn't very useful on its own, since the event dispatcher
should be passed everywhere but it can be used, for example,
with a DI container like poodinis. Since frameworks like
https://github.com/Skadi-d/Skadi.d had "Event Dispatcher" in its
TODO, I decided to write this Announce if something finds it
useful.
In the following lines I will only describe how it works and what
is for. You can find the example I describe here:
https://github.com/caraus-ecms/caraus/blob/master/examples/eventdispatcher/source/app.d
We want to extend a hello world program:
import std.stdio;
class HelloWorld
{
void hello()
{
writeln("Hello world!");
}
}
void main()
{
auto helloWorld = new HelloWorld;
helloWorld.hello();
}
We want that people can attach their own messages before "Hello
world!" or after it. We initialize the EventDispatcher in the
class using it:
dispatcher = new EventDispatcher;
and then attach events like this:
dispatcher.dispatch("postHello");
The last step is to register callbacks to this event:
dispatcher.addListener("postHello", delegate(Event e, string
eventName, EventDispatcher dispatcher) {
writeln("Bye!");
});
Everything together:
import caraus.eventdispatcher.dispatcher;
import caraus.eventdispatcher.event;
import std.functional;
import std.stdio;
class HelloWorld
{
EventDispatcher dispatcher;
this()
{
dispatcher = new EventDispatcher;
}
void hello()
{
writeln("Hello world!");
dispatcher.dispatch("postHello");
}
}
void main()
{
auto helloWorld = new HelloWorld;
helloWorld.dispatcher.addListener("postHello", delegate(Event e,
string eventName, EventDispatcher dispatcher) {
writeln("Bye!");
});
helloWorld.hello();
}
Now you should get:
Hello world!
Bye!
Why not just extend the HelloWorld class and override the
hello()? Imagine you write an apllication that should support
plugins. And two independent plugins extend the HelloWorld. One
plugin would conflict with the another. EventDispatcher make it
possible to register the events that can be used by application
plugins.
Note: If someone wonder about the whole web framework I
mentioned. In the last week I looked a lot into the vibe.d and I
moved to its core for handling the requests instead of my own
CGI-handling. I'm currently working on implementing SCGI based on
vibe.d IO. And I already have a simple web page of a customer
running on it (ok, it is a single page website, but it is already
something :))
Enjoy. Or like people say on this forum: Destroy.
More information about the Digitalmars-d-announce
mailing list