From 2fc03e4050182f91f7573659e409811f14103f2c Mon Sep 17 00:00:00 2001 From: Patrick Wuttke Date: Mon, 23 Jun 2025 00:21:46 +0200 Subject: [PATCH] Made Signal allocator-aware. --- source/mijin/async/signal.hpp | 43 +++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/source/mijin/async/signal.hpp b/source/mijin/async/signal.hpp index 632b65a..382f352 100644 --- a/source/mijin/async/signal.hpp +++ b/source/mijin/async/signal.hpp @@ -33,11 +33,11 @@ inline constexpr signal_token_t INVALID_SIGNAL_TOKEN = std::numeric_limits -class Signal +template typename TAllocator, typename... TArgs> +class BaseSignal { public: - using handler_t = std::function; + using handler_t = std::function; // TODO: write a custom function wrapper with allocator support using token_t = signal_token_t; private: struct RegisteredHandler @@ -47,18 +47,24 @@ private: token_t token; Oneshot oneshot = Oneshot::NO; }; - using handler_vector_t = std::vector; + using handler_vector_t = std::vector>; private: handler_vector_t handlers_; token_t nextToken = 1; std::mutex handlersMutex_; public: - Signal() = default; - Signal(const Signal&) = delete; - Signal(Signal&&) MIJIN_NOEXCEPT = default; + explicit BaseSignal(TAllocator allocator = {}) : handlers_(TAllocator(std::move(allocator))) {} + BaseSignal(const BaseSignal&) = delete; + BaseSignal(BaseSignal&&) MIJIN_NOEXCEPT = default; + + void reinit(TAllocator allocator = {}) + { + MIJIN_ASSERT(handlers_.empty(), "Attempting to re-initialize a signal that already has handlers."); + handlers_ = handler_vector_t(TAllocator(std::move(allocator))); + } public: - Signal& operator=(const Signal&) = delete; - Signal& operator=(Signal&&) MIJIN_NOEXCEPT = default; + BaseSignal& operator=(const BaseSignal&) = delete; + BaseSignal& operator=(BaseSignal&&) MIJIN_NOEXCEPT = default; public: template inline token_t connect(THandler handler, Oneshot oneshot = Oneshot::NO, std::weak_ptr referenced = std::weak_ptr()) MIJIN_NOEXCEPT; @@ -70,13 +76,16 @@ public: inline void emit(TArgs2&&... args) MIJIN_NOEXCEPT; }; +template +using Signal = BaseSignal; + // // public functions // -template +template typename TAllocator, typename... TArgs> template -inline auto Signal::connect(THandler handler, Oneshot oneshot, std::weak_ptr referenced) MIJIN_NOEXCEPT -> token_t +inline auto BaseSignal::connect(THandler handler, Oneshot oneshot, std::weak_ptr referenced) MIJIN_NOEXCEPT -> token_t { std::lock_guard lock(handlersMutex_); @@ -91,9 +100,9 @@ inline auto Signal::connect(THandler handler, Oneshot oneshot, std::we return nextToken++; } -template +template typename TAllocator, typename... TArgs> template -inline auto Signal::connect(TObject& object, void (TObject::* handler)(TArgs...), Oneshot oneshot, std::weak_ptr referenced) MIJIN_NOEXCEPT -> token_t +inline auto BaseSignal::connect(TObject& object, void (TObject::* handler)(TArgs...), Oneshot oneshot, std::weak_ptr referenced) MIJIN_NOEXCEPT -> token_t { std::lock_guard lock(handlersMutex_); @@ -111,8 +120,8 @@ inline auto Signal::connect(TObject& object, void (TObject::* handler) return nextToken++; } -template -inline void Signal::disconnect(token_t token) MIJIN_NOEXCEPT +template typename TAllocator, typename... TArgs> +inline void BaseSignal::disconnect(token_t token) MIJIN_NOEXCEPT { std::lock_guard lock(handlersMutex_); @@ -123,9 +132,9 @@ inline void Signal::disconnect(token_t token) MIJIN_NOEXCEPT handlers_.erase(it, handlers_.end()); } -template +template typename TAllocator, typename... TArgs> template -inline void Signal::emit(TArgs2&&... args) MIJIN_NOEXCEPT +inline void BaseSignal::emit(TArgs2&&... args) MIJIN_NOEXCEPT { std::lock_guard lock(handlersMutex_);