Event¶
An event is a structure that contains information regarding an action which has occured. Events are used to notify other parts of the engine that something has happened.
This pattern is useful to decouple different parts of the engine, so as to avoid situations like deeply nested
functions calls, big switch or if statements, and so on.
Base Type¶
All events must inherit from the Event structure, and all events should be declared as structures as well.
The base Event structure is defined as follows:
#pragma once
#include "bboc/engine/event/IEvent.hpp"
namespace BBOC {
struct Event : public IEvent {
virtual ~Event() = default;
virtual void translate([[maybe_unused]] Luau &context) const override {
context.error("Unimplemented event translation method");
}
};
};
Tip
Declaring a constructor for the inherited event structures is not necessary, as the C++ language will automatically generate a default constructor with the constituent members of the structure as arguments.
Event Handler Types¶
There are two forms of event handlers declared in the engine, EventHandlerMethod and EventHandlerFunction:
#pragma once
#include "bboc/engine/event/Event.hpp"
#include <functional>
namespace BBOC {
template<typename T>
using EventLike = std::enable_if_t<std::is_base_of_v<Event, T>, int>;
template<typename T, typename U, EventLike<T> = 0>
using EventHandlerMethod = void (U::*)(const T &);
template<typename T, EventLike<T> = 0>
using EventHandlerFunction = std::function<void(const T &event)>;
bool operator==(const EventHandlerFunction<Event> &lhs,
const EventHandlerFunction<Event> &rhs);
};
These two types represent member functions and lambda/free functions, respectively, and can be used interchangeably to handle events emitted to the event bus during event subscribing.
Tip
It is recommended to use EventHandlerMethod over EventHandlerFunction when possible, as this will make the
implementation more maintainable, readable and easier to understand.
Miscellaneous Details¶
The EventLike using directive is used by some member functions of the EventBus class to determine if the type
passed as a template argument is inheriting the Event structure.
The bool operator== declaration is used to enable std::find during event subscribing and unsubscribing, and should
not be used externally by end users. This is yet another example of advocation against the use of using namespace in
most cases.
Example¶
The following is an example of an event structure that represents a key press event on the keyboard, from the interface:
#pragma once
#include "bboc/engine/event/Event.hpp"
#include <string>
namespace BBOC {
struct InterfaceKeyPressEvent : public Event {
InterfaceKeyPressEvent(int keyCode) :
keyCode(keyCode) {}
// Structures do not need to have _ as a prefix
const int keyCode;
};
}