-
Notifications
You must be signed in to change notification settings - Fork 2
Events
Zenith features an extensible event system that works across engine subsystems and even Lua scripts. The ZEvent class is the base interface for all events and can be sub-classed to create custom events. If your intent is to create a custom event for use with the engine, make sure to define a static Type
property with a unique identifier in your subclass. Take a look at the ready made events for some examples.
Events also include a timestamp property that can be queried with the TimeStamp
method. This timestamp is set when the event is initially fired, to indicate the time of the event.
A ZEventAgent is a carrier for all Zenith events. Events submitted to the ZEventAgent are sent to all registered listeners interested in that particular event. This is indeed akin to the Observer pattern, in case you've drawn the parallel.
To register a listener with the event agent, we must create a callback delegate that we can pass in alongside the type of event we're registering. Zenith uses the stable FastDelegate implementation by Don Clugston to ease the pains of registering arbitrary callbacks with the event system. We create a delegate using the ZEventDelegate Zenith type:
// We can pass in a global function...
ZEventDelegate callback(&someFunction);
// ... or a static class method
ZEventDelegate classCallback(&SomeClass::SomeCallback);
We can also utilize instance methods as callbacks by using the FastDelegate MakeDelegate
function:
ZEventDelegate callback = MakeDelegate(this, &MyClass::MyInstanceMethod);
The first argument is a pointer to the class instance, and the second the actual method we wish to use. All registered listener functions should accept a pointer to a ZEvent as their sole argument.
With our newfound knowledge of the ZEventDelegate, we can now register callbacks for events. To do this, we simply pass in the delegate and event type to the event agent's AddListener
method. Remember that an event agent is created as a subsystem on engine initialization, so there is no need to create a new one.
ZEventDelegate callback(&objectSelectedCallback);
ZEngine::EventAgent()->AddListener(callback, ZObjectSelectedEvent::Type);
Submitting events is just as trivial. ZEventAgent handles all submitted events in a first-in-first-out order. We can queue an event using the QueueEvent
method. Alternatively, the ZEventAgent can also be used to fire an event immediately if the need arises. To do this, we use the TriggerEvent
method:
auto firedFirst = std::make_shared<ZFireEvent>();
auto firedLater = std::make_shared<ZFireEvent>();
ZEngine::EventAgent()->QueueEvent(firedLater);
ZEngine::EventAgent()->TriggerEvent(firedFirst);
Zenith comes with a few useful event sub-classes, and others are sure to be added soon. The prepackaged events include: