solanaceae_util/solanaceae/util/event_provider.hpp

74 lines
1.6 KiB
C++
Raw Normal View History

2023-07-21 22:07:23 +02:00
#pragma once
#include <array>
#include <vector>
2023-07-25 16:21:53 +02:00
#include <cstddef>
2023-07-21 22:07:23 +02:00
template<typename EventI>
struct EventProviderI {
using enumType = typename EventI::enumType;
// keeps track of subscriptions for you
// and destorys them on destruction
struct SubscriptionReference {
EventProviderI& _ep;
EventI* _object {nullptr};
std::vector<enumType> _subs;
SubscriptionReference(EventProviderI& ep, EventI* object) :
_ep(ep), _object(object)
{
}
~SubscriptionReference(void) {
for (const enumType et : _subs) {
2024-10-24 12:31:22 +02:00
_ep.unsubscribe(_object, et);
}
}
SubscriptionReference& subscribe(const enumType event_type) {
2024-10-24 12:31:22 +02:00
_ep.subscribe(_object, event_type);
_subs.push_back(event_type);
return *this;
}
};
2023-07-21 22:07:23 +02:00
virtual ~EventProviderI(void) {};
virtual void subscribe(EventI* object, const enumType event_type) {
2023-07-25 16:21:53 +02:00
_subscribers.at(static_cast<size_t>(event_type)).push_back(object);
2023-07-21 22:07:23 +02:00
}
2024-10-24 12:31:22 +02:00
virtual void unsubscribe(EventI* object, const enumType event_type) {
auto& o_vec = _subscribers.at(static_cast<size_t>(event_type));
for (auto o_it = o_vec.cbegin(); o_it != o_vec.cend(); o_it++) {
if (*o_it == object) {
o_vec.erase(o_it);
break;
}
}
}
SubscriptionReference newSubRef(EventI* object) {
return SubscriptionReference{*this, object};
}
2023-07-21 22:07:23 +02:00
protected:
template<typename T>
bool dispatch(enumType event_type, const T& event) {
2023-07-25 16:21:53 +02:00
for (auto* zei : _subscribers.at(static_cast<size_t>(event_type))) {
2023-07-21 22:07:23 +02:00
if (zei->onEvent(event)) {
return true;
}
}
return false;
}
protected:
std::array<
std::vector<EventI*>,
2023-07-25 16:21:53 +02:00
static_cast<size_t>(enumType::MAX)
2023-07-21 22:07:23 +02:00
> _subscribers;
};