dedup
This commit is contained in:
parent
7078bcf5ba
commit
834ba5b137
1 changed files with 42 additions and 56 deletions
|
|
@ -55,21 +55,24 @@ namespace Crafter {
|
|||
std::function<void()> function;
|
||||
};
|
||||
|
||||
export template<typename T>
|
||||
class Event {
|
||||
public:
|
||||
// Base implementation for Event<T> - common functionality
|
||||
template<typename T>
|
||||
class EventBase {
|
||||
protected:
|
||||
std::map<int, std::vector<EventListener<T>*>> listeners;
|
||||
Event() = default;
|
||||
Event(Event&& other) : listeners(std::move(other.listeners)) {
|
||||
|
||||
public:
|
||||
EventBase() = default;
|
||||
EventBase(EventBase&& other) : listeners(std::move(other.listeners)) {
|
||||
for (const auto& listenerSlice : listeners) {
|
||||
for (const auto& listener : listenerSlice.second) {
|
||||
listener->eventToListenTo = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
Event(Event&) = delete;
|
||||
Event& operator=(Event&) = delete;
|
||||
~Event() {
|
||||
EventBase(EventBase&) = delete;
|
||||
EventBase& operator=(EventBase&) = delete;
|
||||
virtual ~EventBase() {
|
||||
for (const auto& listenerSlice : listeners) {
|
||||
for (const auto& listener : listenerSlice.second) {
|
||||
listener->eventToListenTo = nullptr;
|
||||
|
|
@ -87,11 +90,38 @@ namespace Crafter {
|
|||
}
|
||||
|
||||
void RemoveListener(EventListener<T>* listener) {
|
||||
listeners[listener->priority].erase(std::remove(listeners[listener->priority].begin(), listeners[listener->priority].end(), listener), listeners[listener->priority].end());
|
||||
listeners[listener->priority].erase(
|
||||
std::remove(listeners[listener->priority].begin(),
|
||||
listeners[listener->priority].end(),
|
||||
listener),
|
||||
listeners[listener->priority].end()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// Specialized Event<void> with different Invoke signature
|
||||
export template<>
|
||||
class Event<void> : public EventBase<void> {
|
||||
public:
|
||||
using EventBase<void>::EventBase;
|
||||
|
||||
void Invoke() {
|
||||
for (const auto& listenerSlice : this->listeners) {
|
||||
for (const auto& listener : listenerSlice.second) {
|
||||
listener->function();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Generic Event<T> with Invoke signature
|
||||
export template<typename T>
|
||||
class Event : public EventBase<T> {
|
||||
public:
|
||||
using EventBase<T>::EventBase;
|
||||
|
||||
void Invoke(T data) {
|
||||
for (const auto& listenerSlice : listeners) {
|
||||
for (const auto& listenerSlice : this->listeners) {
|
||||
for (const auto& listener : listenerSlice.second) {
|
||||
listener->function(data);
|
||||
}
|
||||
|
|
@ -99,6 +129,7 @@ namespace Crafter {
|
|||
}
|
||||
};
|
||||
|
||||
// Common implementations for EventListener<T>
|
||||
template<typename T> void EventListener<T>::SetEvent(Event<T>* eventToListenTo, std::function<void(T)> listener, int priority)
|
||||
{
|
||||
this->priority = priority;
|
||||
|
|
@ -124,52 +155,7 @@ namespace Crafter {
|
|||
eventToListenTo = nullptr;
|
||||
}
|
||||
|
||||
export template<>
|
||||
class Event<void> {
|
||||
public:
|
||||
std::map<int, std::vector<EventListener<void>*>> listeners;
|
||||
Event() = default;
|
||||
Event(Event&& other) : listeners(std::move(other.listeners)) {
|
||||
for (const auto& listenerSlice : listeners) {
|
||||
for (const auto& listener : listenerSlice.second) {
|
||||
listener->eventToListenTo = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
Event(Event&) = delete;
|
||||
Event& operator=(Event&) = delete;
|
||||
~Event() {
|
||||
for (const auto& listenerSlice : listeners) {
|
||||
const std::vector<EventListener<void>*> slice = listenerSlice.second;
|
||||
for (const auto& listener : slice) {
|
||||
listener->eventToListenTo = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AddListener(EventListener<void>* listener, int priority = 0) {
|
||||
if (listeners.contains(priority)) {
|
||||
listeners[priority].push_back(listener);
|
||||
}
|
||||
else {
|
||||
listeners[priority] = std::vector<EventListener<void>*>{ listener };
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveListener(EventListener<void>* listener) {
|
||||
listeners[listener->priority].erase(std::remove(listeners[listener->priority].begin(), listeners[listener->priority].end(), listener), listeners[listener->priority].end());
|
||||
}
|
||||
|
||||
void Invoke() {
|
||||
for (const auto& listenerSlice : listeners) {
|
||||
const std::vector<EventListener<void>*> slice = listenerSlice.second;
|
||||
for (const auto& listener : slice) {
|
||||
listener->function();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Specific implementations for EventListener<void>
|
||||
void EventListener<void>::SetEvent(Event<void>* eventToListenTo, std::function<void()> listener, int priority)
|
||||
{
|
||||
this->priority = priority;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue