Timeout and Interval events
This commit is contained in:
141
src/dawn/event/CustomEvent.hpp
Normal file
141
src/dawn/event/CustomEvent.hpp
Normal file
@ -0,0 +1,141 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
enum class CustomEventResult {
|
||||
NOTHING,
|
||||
REMOVE,
|
||||
INVOKE,
|
||||
INVOKE_AND_REMOVE
|
||||
};
|
||||
|
||||
template<
|
||||
typename InternalData,
|
||||
typename InternalListenerData,
|
||||
typename ListenerArgument,
|
||||
typename ...InvokeArgs
|
||||
>
|
||||
class CustomEvent {
|
||||
private:
|
||||
int32_t nextId = 0;
|
||||
std::unordered_map<
|
||||
int32_t,
|
||||
std::pair<InternalListenerData, std::function<void(InvokeArgs...)>>
|
||||
> listeners;
|
||||
|
||||
protected:
|
||||
InternalData internalData;
|
||||
|
||||
/**
|
||||
* Custom event filter. Decides whether or not the event should be emitted
|
||||
* to the listener.
|
||||
*
|
||||
* @param listenerData Data for this listener.
|
||||
* @param args The arguments to pass to the listeners.
|
||||
* @return The result of the filter.
|
||||
*/
|
||||
virtual enum CustomEventResult shouldEmit(
|
||||
const InternalListenerData &listenerData,
|
||||
const InvokeArgs... args
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Transform the arguments for listener data when the listener is first
|
||||
* subscribed.
|
||||
*
|
||||
* @param argument The argument to transform.
|
||||
* @return The transformed argument into an internal data format.
|
||||
*/
|
||||
virtual InternalListenerData transformData(
|
||||
const ListenerArgument &argument
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Transform the data for listener data after the event has been emitted.
|
||||
*
|
||||
* @param internalData The internal data to transform.
|
||||
* @return Updated/Transformed internal data.
|
||||
*/
|
||||
virtual InternalListenerData transformDataAfterEmit(
|
||||
const InternalListenerData &internalData
|
||||
) {
|
||||
return internalData;
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* Emits the event.
|
||||
* @param args The arguments to pass to the listeners.
|
||||
*/
|
||||
void emit(InvokeArgs... args) {
|
||||
auto copy = listeners;
|
||||
for(auto &pair : copy) {
|
||||
// Check emit test.
|
||||
auto result = this->shouldEmit(
|
||||
pair.second.first,
|
||||
args...
|
||||
);
|
||||
if(
|
||||
result == CustomEventResult::INVOKE ||
|
||||
result == CustomEventResult::INVOKE_AND_REMOVE
|
||||
) {
|
||||
pair.second.second(args...);
|
||||
}
|
||||
|
||||
if(
|
||||
result == CustomEventResult::REMOVE ||
|
||||
result == CustomEventResult::INVOKE_AND_REMOVE
|
||||
) {
|
||||
listeners.erase(pair.first);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(
|
||||
result == CustomEventResult::INVOKE ||
|
||||
result == CustomEventResult::INVOKE_AND_REMOVE
|
||||
) {
|
||||
// Update the internal data.
|
||||
listeners[pair.first].first = transformDataAfterEmit(
|
||||
pair.second.first
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens to the event.
|
||||
*
|
||||
* @param data Listener data to use.
|
||||
* @param listener The listener to add.
|
||||
* @returns A function that can be called to remove the listener.
|
||||
*/
|
||||
std::function<void()> listen(
|
||||
const ListenerArgument &data,
|
||||
const std::function<void(InvokeArgs...)> listener
|
||||
) {
|
||||
int32_t id = nextId++;
|
||||
|
||||
auto pair = std::make_pair(
|
||||
transformData(data),
|
||||
listener
|
||||
);
|
||||
|
||||
listeners[id] = pair;
|
||||
return [this, id]() {
|
||||
listeners.erase(id);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the custom event.
|
||||
*/
|
||||
virtual ~CustomEvent() {
|
||||
listeners.clear();
|
||||
}
|
||||
};
|
||||
}
|
@ -37,7 +37,9 @@ namespace Dawn {
|
||||
* @param listener The listener to add.
|
||||
* @returns A function that can be called to remove the listener.
|
||||
*/
|
||||
std::function<void()> listen(const std::function<void(A...)> listener) {
|
||||
std::function<void()> listen(
|
||||
const std::function<void(A...)> listener
|
||||
) {
|
||||
int32_t id = nextId++;
|
||||
listeners[id] = listener;
|
||||
return [this, id]() {
|
||||
@ -46,8 +48,7 @@ namespace Dawn {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a listener from the event.
|
||||
* @param id The id of the listener to remove.
|
||||
* Destroys the event.
|
||||
*/
|
||||
virtual ~Event() {
|
||||
listeners.clear();
|
||||
|
Reference in New Issue
Block a user