30namespace DiscordCoreInternal {
39 template<
typename RTy,
typename... ArgTypes>
friend class EventDelegate;
41 template<
typename RTy,
typename... ArgTypes>
friend class Event;
45 template<
typename RTy,
typename... ArgTypes>
friend class TriggerEvent;
54 std::string handlerId{};
55 std::string eventId{};
59 return lhs.eventId == rhs.eventId && lhs.handlerId == rhs.handlerId;
62 DiscordCoreAPI_Dll
inline bool operator<(
const EventDelegateToken& lhs,
const EventDelegateToken& rhs) {
63 return stoll(lhs.handlerId) < stoll(rhs.handlerId);
69 template<
typename RTy02,
typename... ArgTypes02>
friend class Event;
73 function.swap(other.function);
74 other.function = std::function<RTy(ArgTypes...)>{};
80 *
this = std::move(other);
87 EventDelegate<RTy, ArgTypes...>& operator=(std::function<RTy(ArgTypes...)> functionNew) {
88 function = functionNew;
97 EventDelegate<RTy, ArgTypes...>& operator=(RTy (*functionNew)(ArgTypes...)) {
98 function = functionNew;
110 std::function<RTy(ArgTypes...)> function{};
113 template<
typename RTy,
typename... ArgTypes>
class Event {
115 std::map<EventDelegateToken, EventDelegate<RTy, ArgTypes...>> functions{};
117 Event<RTy, ArgTypes...>& operator=(Event<RTy, ArgTypes...>&& other)
noexcept {
118 if (
this != &other) {
119 functions = std::move(other.functions);
120 other.functions = std::map<EventDelegateToken, EventDelegate<RTy, ArgTypes...>>{};
121 eventId = std::move(other.eventId);
122 other.eventId = std::string{};
127 Event(Event<RTy, ArgTypes...>&& other)
noexcept {
128 *
this = std::move(other);
131 Event<RTy, ArgTypes...>& operator=(
const Event<RTy, ArgTypes...>&) =
delete;
133 Event(
const Event<RTy, ArgTypes...>&) =
delete;
136 eventId = std::to_string(std::chrono::duration_cast<Microseconds>(HRClock::now().time_since_epoch()).count());
139 EventDelegateToken add(EventDelegate<RTy, ArgTypes...> eventDelegate) {
140 EventDelegateToken eventToken{};
141 eventToken.handlerId = std::to_string(std::chrono::duration_cast<Microseconds>(HRClock::now().time_since_epoch()).count());
142 eventToken.eventId = eventId;
143 functions[eventToken] = std::move(eventDelegate);
147 void erase(EventDelegateToken eventToken) {
148 if (eventToken.eventId == eventId) {
149 if (functions.contains(eventToken)) {
150 functions.erase(eventToken);
155 std::vector<RTy> operator()(ArgTypes&... args) {
156 std::vector<RTy> vector{};
157 for (
auto& [key, value]: functions) {
158 vector.emplace_back(value.function(args...));
164 std::string eventId{};
170 template<
typename RTy02,
typename... ArgTypes02>
friend class TriggerEvent;
173 if (
this != &other) {
174 function.swap(other.function);
175 other.function = std::function<RTy(ArgTypes...)>{};
176 testFunction.swap(other.testFunction);
177 other.testFunction = std::function<bool(ArgTypes...)>{};
183 *
this = std::move(other);
190 TriggerEventDelegate<RTy, ArgTypes...>& operator=(std::function<RTy(ArgTypes...)> functionNew) {
191 function = functionNew;
201 function = functionNew;
205 void setTestFunction(std::function<
bool(ArgTypes...)> testFunctionNew) {
206 testFunction = testFunctionNew;
209 void setTestFunction(
bool (*testFunctionNew)(ArgTypes...)) {
210 testFunction = testFunctionNew;
221 std::function<
bool(ArgTypes...)> testFunction{};
222 std::function<RTy(ArgTypes...)> function{};
227 template<
typename RTy,
typename... ArgTypes>
class TriggerEvent {
229 std::map<EventDelegateToken, TriggerEventDelegate<RTy, ArgTypes...>> functions{};
231 TriggerEvent<RTy, ArgTypes...>& operator=(Event<RTy, ArgTypes...>&& other)
noexcept {
232 if (
this != &other) {
233 functions = std::move(other.functions);
234 other.functions = std::map<EventDelegateToken, TriggerEventDelegate<RTy, ArgTypes...>>{};
235 eventId = std::move(other.eventId);
236 other.eventId = std::string{};
241 TriggerEvent(Event<RTy, ArgTypes...>&& other)
noexcept {
242 *
this = std::move(other);
245 TriggerEvent<RTy, ArgTypes...>& operator=(
const Event<RTy, ArgTypes...>&) =
delete;
247 TriggerEvent(
const TriggerEvent<RTy, ArgTypes...>&) =
delete;
250 eventId = std::to_string(std::chrono::duration_cast<Microseconds>(HRClock::now().time_since_epoch()).count());
253 EventDelegateToken add(TriggerEventDelegate<RTy, ArgTypes...> eventDelegate) {
254 EventDelegateToken eventToken{};
255 eventToken.handlerId = std::to_string(std::chrono::duration_cast<Microseconds>(HRClock::now().time_since_epoch()).count());
256 eventToken.eventId = eventId;
257 functions[eventToken] = std::move(eventDelegate);
261 void erase(EventDelegateToken eventToken) {
262 if (eventToken.eventId == eventId) {
263 if (functions.contains(eventToken)) {
264 functions.erase(eventToken);
269 void operator()(ArgTypes&... args) {
270 for (
auto iterator = functions.begin(); iterator != functions.end(); ++iterator) {
271 if (iterator.operator*().second.testFunction(args...)) {
272 iterator.operator*().second.function(args...);
273 functions.erase(iterator);
280 std::string eventId{};
Event-delegate token, representing an event.
Event-delegate, for representing an event-function to be executed.
EventDelegate(RTy(*functionNew)(ArgTypes...))
Constructor, taking a pointer to a function of type RTy(*)(ArgTypes...) as an argument.
EventDelegate(std::function< RTy(ArgTypes...)> functionNew)
Constructor, taking a std::function<RTy(ArgTypes..)> as an argument.
An event that gets fired depending on the result of a "trigger-function" return value.
TriggerEventDelegate(std::function< RTy(ArgTypes...)> functionNew)
Constructor, taking a std::function<RTy(ArgTypes..)> as an argument.
TriggerEventDelegate(RTy(*functionNew)(ArgTypes...))
Constructor, taking a pointer to a function of type RTy(*)(ArgTypes...) as an argument.