From ede0cf05499c2799029c3c646cb8314b3a43477a Mon Sep 17 00:00:00 2001 From: crupest Date: Mon, 1 Jan 2024 22:20:21 +0800 Subject: WORKING: Event2. --- include/cru/common/Event2.h | 116 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 include/cru/common/Event2.h (limited to 'include') diff --git a/include/cru/common/Event2.h b/include/cru/common/Event2.h new file mode 100644 index 00000000..a8476db3 --- /dev/null +++ b/include/cru/common/Event2.h @@ -0,0 +1,116 @@ +#pragma once + +#include + +#include +#include +#include +#include +#include + +namespace cru { +template +class EventContext { + public: + EventContext() : argument_(), result_() {} + explicit EventContext(TArgument argument) + : argument_(std::move(argument)), result_() {} + EventContext(TArgument argument, TResult result) + : argument_(std::move(argument)), result_(std::move(result)) {} + + TArgument& GetArgument() { return argument_; } + const TArgument& GetArgument() const { return argument_; } + + TResult& GetResult() { return result_; } + const TResult& GetResult() const { return result_; } + void SetResult(TResult&& result) { result_ = std::forward(result); } + + bool GetStopHandling() const { return stop_handling_; } + void SetStopHandling(bool stop = true) { stop_handling_ = stop; } + + private: + TArgument argument_; + TResult result_; + bool stop_handling_ = false; +}; + +template +class Event2; + +template +constexpr bool is_event2_v = false; + +template +constexpr bool is_event2_v> = true; + +template +class EventHandlerToken { + static_assert(is_event2_v, "TEvent2 must be Event2 class."); + + public: + EventHandlerToken(ObjectResolver event_resolver, int token_value); + + ObjectResolver GetEventResolver() const { return event_resolver_; } + int GetTokenValue() const { return token_value_; } + void RevokeHandler() const; + + private: + ObjectResolver event_resolver_; + int token_value_; +}; + +template +class Event2 : public SelfResolvable> { + public: + using HandlerToken = EventHandlerToken; + using Context = EventContext; + using Handler = std::function; + using SpyOnlyHandler = std::function; + + template + static std::enable_if_t, Handler> WrapAsHandler( + TFunc&& handler) { + return Handler([h = std::forward(handler)](Context&) { h(); }); + } + + template + static std::enable_if_t, Handler> + WrapAsHandler(TFunc&& handler) { + return Handler(std::forward(handler)); + } + + private: + struct HandlerData { + int token_value_; + Handler handler_; + }; + + public: + Event2(const Event2&) = delete; + Event2(Event2&&) = delete; + Event2& operator=(const Event2&) = delete; + Event2& operator=(Event2&&) = delete; + ~Event2() override = default; + + public: + + + void RevokeHandler(int token_value); + void RevokeHandler(const HandlerToken& token) { + return RevokeHandler(token.GetTokenValue()); + } + + private: + int current_token_value_ = 1; + std::vector handlers_; +}; + +template +void EventHandlerToken::RevokeHandler() const { + auto event = this->event_resolver_.Resolve(); + if (event) { + event->RevokeHandler(this->token_value_); + } +} +} // namespace cru -- cgit v1.2.3