-
Notifications
You must be signed in to change notification settings - Fork 1
Event System
⚠️ This wiki is under construction. Pages are being populated incrementally.
Events in Nodens follow a data-oriented principle, where an event is a plain-old-data (POD) struct with an appropriate Name member variable for debugging:
struct EventExample {
static constexpr std::string_view Name = "Example";
// More Data members...
}To enforce this we use C++20 concepts:
template <typename TEvent>
concept Event = std::is_standard_layout_v<TEvent>
&& std::is_trivially_copyable_v<TEvent>
&& requires {
{ TEvent::Name } -> std::same_as<const std::string_view&>;
};Nodens separates Events into two categories:
- Input Events: These are any events coming in from the GLFW, be it input events (e.g. key or button presses) or window events (e.g. close or resize window).
- Non-input Events: Any other event defined by your application or other subsystems.
Each category is routed through the framework in a different way.
All available input event types are defined on src/Nodens/Events/InputEvents.cppm under the Nodens::InputEvents namespace.
We use an std::variant named InputEvent to store arbitrary input events, and they are routed through the LayerStack inside a RoutedInputEvent wrapper struct:
struct RoutedInputEvent {
InputEvent Event;
bool Handled;
}The Handled flag is used to mark input events as "consumed" so that they don't propagate further down the layer stack.
All input events generated by the window are immediately passed to the Application::OnInputEvent method, which is set as the GLFW window callback.
Traversing the LayerStack from top to bottom, each Layer's own OnInputEvent method is called and the event can be dispatched to their appropriate handlers.
The dispatch process can be made using the InputEventDispatcher utility as follows
void YourLayer::OnInputEvent(RoutedInputEvent& e) {
InputEventDispatcher dispatcher(e);
dispatcher.Dispatch<Nodens::InputEvents::KeyPressedEvent>(
[this](Nodens::InputEvents::KeyPressedEvent& event){
std::print("Handled event {}", event);
return true;
}
)
}The templated Dispatch<EventType>(Handler) method calls the Handler function if the type held by the variant e.Event matches the EventType passed as the template parameter.
Non-input events are routed exclusively through the EventBus using type-erasure techniques.
The EventBus is a singleton class (for now) that implements a publisher/subscriber model, and features both immediate dispatch (handling events on the local stack) and thread-safe deferred dispatch using double-buffered per-event-type queues.
- Layer System: How input events are routed through layers.
-
Event,InputEventDispatcher,EventBusin the API Reference.
Getting Started
Architecture
Guides
Reference