aboutsummaryrefslogtreecommitdiff
path: root/src/crepe/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/crepe/api')
-rw-r--r--src/crepe/api/EventManager.cpp54
-rw-r--r--src/crepe/api/EventManager.h39
-rw-r--r--src/crepe/api/EventManager.hpp36
-rw-r--r--src/crepe/api/IKeyListener.cpp3
-rw-r--r--src/crepe/api/IKeyListener.h4
-rw-r--r--src/crepe/api/IMouseListener.cpp3
-rw-r--r--src/crepe/api/IMouseListener.h2
7 files changed, 71 insertions, 70 deletions
diff --git a/src/crepe/api/EventManager.cpp b/src/crepe/api/EventManager.cpp
index 993db86..20f0dd3 100644
--- a/src/crepe/api/EventManager.cpp
+++ b/src/crepe/api/EventManager.cpp
@@ -1,6 +1,7 @@
#include "EventManager.h"
using namespace crepe;
+using namespace std;
EventManager & EventManager::get_instance() {
static EventManager instance;
@@ -8,30 +9,23 @@ EventManager & EventManager::get_instance() {
}
void EventManager::dispatch_events() {
- for (auto event_it = this->events_queue.begin(); event_it != this->events_queue.end();) {
- std::unique_ptr<Event> & event = (*event_it).event;
- int channel = (*event_it).channel;
- std::type_index event_type = (*event_it).type;
-
- bool event_handled = false;
- auto handlers_it = this->subscribers.find(event_type);
- if (handlers_it == this->subscribers.end()) {
- continue;
- }
- std::vector<CallbackEntry> & handlers = handlers_it->second;
-
- for (auto handler_it = handlers.begin(); handler_it != handlers.end(); ++handler_it) {
- // If callback is executed and returns true, remove the event from the queue
- if ((*handler_it).callback->exec(*event)) {
- event_it = this->events_queue.erase(event_it);
- event_handled = true;
- break;
- }
- }
+ for (auto & event : this->events_queue) {
+ this->handle_event(event.type, event.channel, *event.event.get());
+ }
+ this->events_queue.clear();
+}
- if (!event_handled) {
- ++event_it;
- }
+void EventManager::handle_event(type_index type, event_channel_t channel, const Event & data) {
+ auto handlers_it = this->subscribers.find(type);
+ if (handlers_it == this->subscribers.end()) return;
+
+ vector<CallbackEntry> & handlers = handlers_it->second;
+ for (auto & handler : handlers) {
+ bool check_channel = handler.channel != CHANNEL_ALL || channel != CHANNEL_ALL;
+ if (check_channel && handler.channel != channel) continue;
+
+ bool handled = handler.callback->exec(data);
+ if (handled) return;
}
}
@@ -40,15 +34,13 @@ void EventManager::clear() {
this->events_queue.clear();
}
-void EventManager::unsubscribe(subscription_t event_id) {
+void EventManager::unsubscribe(subscription_t id) {
for (auto & [event_type, handlers] : this->subscribers) {
- for (auto it = handlers.begin(); it != handlers.end();) {
- if (it->id == event_id) {
- it = handlers.erase(it);
- return;
- } else {
- ++it;
- }
+ for (auto it = handlers.begin(); it != handlers.end(); it++) {
+ // find listener with subscription id
+ if ((*it).id != id) continue;
+ it = handlers.erase(it);
+ return;
}
}
}
diff --git a/src/crepe/api/EventManager.h b/src/crepe/api/EventManager.h
index bd9772a..348a04d 100644
--- a/src/crepe/api/EventManager.h
+++ b/src/crepe/api/EventManager.h
@@ -1,8 +1,6 @@
#pragma once
-#include <functional>
#include <memory>
-#include <type_traits>
#include <typeindex>
#include <unordered_map>
#include <vector>
@@ -11,8 +9,17 @@
#include "EventHandler.h"
namespace crepe {
-//! typedef for subscription value
-typedef int subscription_t;
+
+//! Event listener unique ID
+typedef size_t subscription_t;
+
+/**
+ * \brief Event channel
+ *
+ * Events can be sent to a specific channel, which prevents listeners on other channels from
+ * being called. The default channel is EventManager::CHANNEL_ALL, which calls all listeners.
+ */
+typedef size_t event_channel_t;
/**
* \class EventManager
@@ -24,7 +31,7 @@ typedef int subscription_t;
*/
class EventManager {
public:
- static constexpr int CHANNEL_ALL = -1;
+ static constexpr const event_channel_t CHANNEL_ALL = -1;
/**
* \brief Get the singleton instance of the EventManager.
@@ -49,7 +56,7 @@ public:
*/
template <typename EventType>
subscription_t subscribe(const EventHandler<EventType> & callback,
- int channel = CHANNEL_ALL);
+ event_channel_t channel = CHANNEL_ALL);
/**
* \brief Unsubscribe a previously registered callback.
@@ -70,7 +77,7 @@ public:
* \param channel The channel to trigger the event on (default is CHANNEL_ALL, which triggers on all channels).
*/
template <typename EventType>
- void trigger_event(const EventType & event, int channel = CHANNEL_ALL);
+ void trigger_event(const EventType & event, event_channel_t channel = CHANNEL_ALL);
/**
* \brief Queue an event for later processing.
@@ -82,7 +89,7 @@ public:
* \param channel The channel to associate with the event (default is CHANNEL_ALL).
*/
template <typename EventType>
- void queue_event(const EventType & event, int channel = CHANNEL_ALL);
+ void queue_event(const EventType & event, event_channel_t channel = CHANNEL_ALL);
/**
* \brief Process all queued events.
@@ -113,17 +120,29 @@ private:
*/
struct QueueEntry {
std::unique_ptr<Event> event; ///< The event instance.
- int channel = CHANNEL_ALL; ///< The channel associated with the event.
+ event_channel_t channel = CHANNEL_ALL; ///< The channel associated with the event.
std::type_index type; ///< The type of the event.
};
/**
+ * \brief Internal event handler
+ *
+ * This function processes a single event, and is used to process events both during
+ * EventManager::dispatch_events and inside EventManager::trigger_event
+ *
+ * \param type \c typeid of concrete Event class
+ * \param channel Event channel
+ * \param data Event data
+ */
+ void handle_event(std::type_index type, event_channel_t channel, const Event & data);
+
+ /**
* \struct CallbackEntry
* \brief Represents a registered event handler callback.
*/
struct CallbackEntry {
std::unique_ptr<IEventHandlerWrapper> callback; ///< The callback function wrapper.
- int channel = CHANNEL_ALL; ///< The channel this callback listens to.
+ event_channel_t channel = CHANNEL_ALL; ///< The channel this callback listens to.
subscription_t id = -1; ///< Unique subscription ID.
};
diff --git a/src/crepe/api/EventManager.hpp b/src/crepe/api/EventManager.hpp
index b2a94bd..a5f4556 100644
--- a/src/crepe/api/EventManager.hpp
+++ b/src/crepe/api/EventManager.hpp
@@ -1,9 +1,12 @@
+#pragma once
+
#include "EventManager.h"
namespace crepe {
template <typename EventType>
-subscription_t EventManager::subscribe(const EventHandler<EventType> & callback, int channel) {
+subscription_t EventManager::subscribe(const EventHandler<EventType> & callback,
+ event_channel_t channel) {
subscription_counter++;
std::type_index event_type = typeid(EventType);
std::unique_ptr<EventHandlerWrapper<EventType>> handler
@@ -15,34 +18,19 @@ subscription_t EventManager::subscribe(const EventHandler<EventType> & callback,
}
template <typename EventType>
-void EventManager::queue_event(const EventType & event, int channel) {
+void EventManager::queue_event(const EventType & event, event_channel_t channel) {
static_assert(std::is_base_of<Event, EventType>::value,
"EventType must derive from Event");
- std::type_index event_type = typeid(EventType);
-
- auto event_ptr = std::make_unique<EventType>(event);
-
- this->events_queue.push_back(
- QueueEntry{.event = std::move(event_ptr), .channel = channel, .type = event_type});
+ this->events_queue.push_back(QueueEntry{
+ .event = std::make_unique<EventType>(event),
+ .channel = channel,
+ .type = typeid(EventType),
+ });
}
template <typename EventType>
-void EventManager::trigger_event(const EventType & event, int channel) {
- std::type_index event_type = typeid(EventType);
-
- auto handlers_it = this->subscribers.find(event_type);
- if (handlers_it != this->subscribers.end()) {
- const std::vector<CallbackEntry> & handlers = handlers_it->second;
-
- for (const CallbackEntry & handler : handlers) {
- if (handler.channel != channel && handler.channel != CHANNEL_ALL) {
- continue;
- }
- if (handler.callback->exec(event)) {
- break;
- }
- }
- }
+void EventManager::trigger_event(const EventType & event, event_channel_t channel) {
+ this->handle_event(typeid(EventType), channel, event);
}
} // namespace crepe
diff --git a/src/crepe/api/IKeyListener.cpp b/src/crepe/api/IKeyListener.cpp
index 7aefaf7..8642655 100644
--- a/src/crepe/api/IKeyListener.cpp
+++ b/src/crepe/api/IKeyListener.cpp
@@ -3,7 +3,8 @@
using namespace crepe;
// Constructor with specified channel
-IKeyListener::IKeyListener(int channel) : event_manager(EventManager::get_instance()) {
+IKeyListener::IKeyListener(event_channel_t channel)
+ : event_manager(EventManager::get_instance()) {
this->press_id = event_manager.subscribe<KeyPressEvent>(
[this](const KeyPressEvent & event) { return this->on_key_pressed(event); }, channel);
this->release_id = event_manager.subscribe<KeyReleaseEvent>(
diff --git a/src/crepe/api/IKeyListener.h b/src/crepe/api/IKeyListener.h
index 2a89cbc..328a4c2 100644
--- a/src/crepe/api/IKeyListener.h
+++ b/src/crepe/api/IKeyListener.h
@@ -16,7 +16,7 @@ public:
* \brief Constructs an IKeyListener with a specified channel.
* \param channel The channel ID for event handling.
*/
- IKeyListener(int channel = EventManager::CHANNEL_ALL);
+ IKeyListener(event_channel_t channel = EventManager::CHANNEL_ALL);
virtual ~IKeyListener();
IKeyListener(const IKeyListener &) = delete;
IKeyListener & operator=(const IKeyListener &) = delete;
@@ -43,7 +43,7 @@ private:
//! Key release event id
subscription_t release_id = -1;
//! EventManager reference
- EventManager & event_manager;;
+ EventManager & event_manager;
};
} // namespace crepe
diff --git a/src/crepe/api/IMouseListener.cpp b/src/crepe/api/IMouseListener.cpp
index 7d38280..989aeb3 100644
--- a/src/crepe/api/IMouseListener.cpp
+++ b/src/crepe/api/IMouseListener.cpp
@@ -2,7 +2,8 @@
using namespace crepe;
-IMouseListener::IMouseListener(int channel) : event_manager(EventManager::get_instance()) {
+IMouseListener::IMouseListener(event_channel_t channel)
+ : event_manager(EventManager::get_instance()) {
this->click_id = event_manager.subscribe<MouseClickEvent>(
[this](const MouseClickEvent & event) { return this->on_mouse_clicked(event); },
channel);
diff --git a/src/crepe/api/IMouseListener.h b/src/crepe/api/IMouseListener.h
index 91b33e1..15e1619 100644
--- a/src/crepe/api/IMouseListener.h
+++ b/src/crepe/api/IMouseListener.h
@@ -16,7 +16,7 @@ public:
* \brief Constructs an IMouseListener with a specified channel.
* \param channel The channel ID for event handling.
*/
- IMouseListener(int channel = EventManager::CHANNEL_ALL);
+ IMouseListener(event_channel_t channel = EventManager::CHANNEL_ALL);
virtual ~IMouseListener();
IMouseListener & operator=(const IMouseListener &) = delete;
IMouseListener(const IMouseListener &) = delete;