mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-08-04 09:44:10 +00:00
Proposal for observers and deferred implementations (#1599)
This commit is contained in:
92
dCommon/Implementation.h
Normal file
92
dCommon/Implementation.h
Normal file
@@ -0,0 +1,92 @@
|
||||
#ifndef __IMPLEMENTATION_H__
|
||||
#define __IMPLEMENTATION_H__
|
||||
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
|
||||
/**
|
||||
* @brief A way to defer the implementation of an action.
|
||||
*
|
||||
* @tparam R The result of the action.
|
||||
* @tparam T The types of the arguments that the implementation requires.
|
||||
*/
|
||||
template <typename R, typename... T>
|
||||
class Implementation {
|
||||
public:
|
||||
typedef std::function<std::optional<R>(T...)> ImplementationFunction;
|
||||
|
||||
/**
|
||||
* @brief Sets the implementation of the action.
|
||||
*
|
||||
* @param implementation The implementation of the action.
|
||||
*/
|
||||
void SetImplementation(const ImplementationFunction& implementation) {
|
||||
this->implementation = implementation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clears the implementation of the action.
|
||||
*/
|
||||
void ClearImplementation() {
|
||||
implementation.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if the implementation is set.
|
||||
*
|
||||
* @return true If the implementation is set.
|
||||
* @return false If the implementation is not set.
|
||||
*/
|
||||
bool IsSet() const {
|
||||
return implementation.has_value();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Executes the implementation if it is set.
|
||||
*
|
||||
* @param args The arguments to pass to the implementation.
|
||||
* @return std::optional<R> The optional result of the implementation. If the result is not set, it indicates that the default action should be taken.
|
||||
*/
|
||||
std::optional<R> Execute(T... args) const {
|
||||
return IsSet() ? implementation.value()(args...) : std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Exectues the implementation if it is set, otherwise returns a default value.
|
||||
*
|
||||
* @param args The arguments to pass to the implementation.
|
||||
* @param defaultValue The default value to return if the implementation is not set or should not be deferred.
|
||||
*/
|
||||
R ExecuteWithDefault(T... args, const R& defaultValue) const {
|
||||
return Execute(args...).value_or(defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* = operator overload.
|
||||
*/
|
||||
Implementation& operator=(const Implementation& other) {
|
||||
implementation = other.implementation;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* = operator overload.
|
||||
*/
|
||||
Implementation& operator=(const ImplementationFunction& implementation) {
|
||||
this->implementation = implementation;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* () operator overload.
|
||||
*/
|
||||
std::optional<R> operator()(T... args) {
|
||||
return !IsSet() ? std::nullopt : implementation(args...);
|
||||
}
|
||||
|
||||
private:
|
||||
std::optional<ImplementationFunction> implementation;
|
||||
|
||||
};
|
||||
|
||||
#endif //!__IMPLEMENTATION_H__
|
73
dCommon/Observable.h
Normal file
73
dCommon/Observable.h
Normal file
@@ -0,0 +1,73 @@
|
||||
#ifndef __OBSERVABLE_H__
|
||||
#define __OBSERVABLE_H__
|
||||
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
/**
|
||||
* @brief An event which can be observed by multiple observers.
|
||||
*
|
||||
* @tparam T The types of the arguments to be passed to the observers.
|
||||
*/
|
||||
template <typename... T>
|
||||
class Observable {
|
||||
public:
|
||||
typedef std::function<void(T...)> Observer;
|
||||
|
||||
/**
|
||||
* @brief Adds an observer to the event.
|
||||
*
|
||||
* @param observer The observer to add.
|
||||
*/
|
||||
void AddObserver(const Observer& observer) {
|
||||
observers.push_back(observer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Removes an observer from the event.
|
||||
*
|
||||
* @param observer The observer to remove.
|
||||
*/
|
||||
void RemoveObserver(const Observer& observer) {
|
||||
observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Notifies all observers of the event.
|
||||
*
|
||||
* @param args The arguments to pass to the observers.
|
||||
*/
|
||||
void Notify(T... args) {
|
||||
for (const auto& observer : observers) {
|
||||
observer(args...);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* += operator overload.
|
||||
*/
|
||||
Observable& operator+=(const Observer& observer) {
|
||||
AddObserver(observer);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* -= operator overload.
|
||||
*/
|
||||
Observable& operator-=(const Observer& observer) {
|
||||
RemoveObserver(observer);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* () operator overload.
|
||||
*/
|
||||
void operator()(T... args) {
|
||||
Notify(args...);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<Observer> observers;
|
||||
};
|
||||
|
||||
#endif //!__OBSERVABLE_H__
|
Reference in New Issue
Block a user