Loading...
Searching...
No Matches
EventManager.h
Go to the documentation of this file.
1// Copyright (c) 2025 Dave R. Smith.
2// Malena Framework — Licensed under PolyForm Noncommercial 1.0.0; commercial use requires a paid license. See LICENSE.
3
4//
5// EventManager.h
6//
7
8#ifndef MALENA_EVENTSMANAGER_H
9#define MALENA_EVENTSMANAGER_H
10
12#include <map>
13#include <string>
14#include <vector>
18#include <SFML/Window/Event.hpp>
19#include <optional>
20
21namespace ml
22{
23 class Fireable;
24 class EventReceiver;
25 class Core;
26 class Unsubscribable;
27
46 {
48 struct Subscriber
49 {
50 EventReceiver* receiver;
51 Core* core;
52 };
53
54 inline static std::map<
55 std::string,
56 std::vector<Subscriber>
57 > _subscribers;
59
60 public:
75 template<typename EnumType>
76 static void subscribe(EnumType eventEnum, EventReceiver* component, Core* core = nullptr)
77 {
78 // `core` may be supplied by callers that already KNOW the Core
79 // identity — notably ComponentCore, which subscribes from inside its
80 // own constructor. Resolving it there by dynamic_cast would be a
81 // cast on a partially-constructed object: undefined, tolerated by
82 // Clang, and a hard RTTI failure on MSVC (0xC0000409 at startup).
83 doSubscribe(EnumKey::get(eventEnum), component, core);
84 }
85
95 template<typename EnumType>
96 static void unsubscribe(EnumType eventEnum, Core* core)
97 {
98 deferOrExecute([key = EnumKey::get(eventEnum), core]()
99 {
100 doUnsubscribe(key, core);
101 });
102 }
103
112 static void unsubscribeAll(Core* core);
113
119 static void clear();
120
129 static bool hasReceiver(EventReceiver* receiver);
130
141 template<typename EnumType>
142 static void fire(EnumType eventEnum,
143 Fireable* dispatcher,
144 const std::optional<sf::Event>& event,
145 SystemCallback resolve = nullptr,
146 SystemCallback reject = nullptr)
147 {
148 doFire(EnumKey::get(eventEnum), dispatcher, event, resolve, reject);
149 }
150
151 friend class AppManager;
152 friend class Fireable;
153 friend class Core;
154 friend class Unsubscribable;
155
156 private:
158 static void unsubscribe(const std::string& key, Core* core)
159 {
160 deferOrExecute([key, core]() { doUnsubscribe(key, core); });
161 }
162
163
164
165 static void doSubscribe(const std::string& key, EventReceiver* component, Core* core = nullptr);
166 static void doFire(const std::string& key,
167 Fireable* dispatcher,
168 const std::optional<sf::Event>& event,
169 SystemCallback resolve,
170 SystemCallback reject);
171 static void doUnsubscribe(const std::string& key, Core* core);
172 static void doUnsubscribeAll(Core* core);
173
174 public:
175 static void forceUnsubscribeAll(Core* core);
177 };
178
179} // namespace ml
180
181#endif // MALENA_EVENTSMANAGER_H
Virtual base class for all Malena framework objects.
Definition Core.h:97
CRTP base that gives a manager safe deferred-operation support.
static void deferOrExecute(std::function< void()> operation)
Centralized event bus for the Malena trait-based event system.
static void clear()
Remove all subscriptions for all events.
static void unsubscribe(EnumType eventEnum, Core *core)
Remove a component's subscription to one event.
friend class Core
friend class AppManager
static void fire(EnumType eventEnum, Fireable *dispatcher, const std::optional< sf::Event > &event, SystemCallback resolve=nullptr, SystemCallback reject=nullptr)
Fire an event to all matching subscribers.
static void subscribe(EnumType eventEnum, EventReceiver *component, Core *core=nullptr)
Register a component for an enum-keyed event.
friend class Fireable
static bool hasReceiver(EventReceiver *receiver)
True if receiver is still registered under any event key.
static void unsubscribeAll(Core *core)
Remove all subscriptions for a component.
friend class Unsubscribable
Base class for all event-receiving traits.
Trait that gives components the ability to unsubscribe from events.
#define MALENA_API
Definition Animate.h:25
static std::string get(EnumType value)
Generate a unique string key for an enum value.
Definition EnumKey.h:67