Made Signal allocator-aware.

This commit is contained in:
Patrick 2025-06-23 00:21:46 +02:00
parent 94e94f02b6
commit 2fc03e4050

View File

@ -33,11 +33,11 @@ inline constexpr signal_token_t INVALID_SIGNAL_TOKEN = std::numeric_limits<signa
MIJIN_DEFINE_FLAG(Oneshot); MIJIN_DEFINE_FLAG(Oneshot);
template<typename... TArgs> template<template<typename> typename TAllocator, typename... TArgs>
class Signal class BaseSignal
{ {
public: public:
using handler_t = std::function<void(TArgs...)>; using handler_t = std::function<void(TArgs...)>; // TODO: write a custom function wrapper with allocator support
using token_t = signal_token_t; using token_t = signal_token_t;
private: private:
struct RegisteredHandler struct RegisteredHandler
@ -47,18 +47,24 @@ private:
token_t token; token_t token;
Oneshot oneshot = Oneshot::NO; Oneshot oneshot = Oneshot::NO;
}; };
using handler_vector_t = std::vector<RegisteredHandler>; using handler_vector_t = std::vector<RegisteredHandler, TAllocator<RegisteredHandler>>;
private: private:
handler_vector_t handlers_; handler_vector_t handlers_;
token_t nextToken = 1; token_t nextToken = 1;
std::mutex handlersMutex_; std::mutex handlersMutex_;
public: public:
Signal() = default; explicit BaseSignal(TAllocator<void> allocator = {}) : handlers_(TAllocator<RegisteredHandler>(std::move(allocator))) {}
Signal(const Signal&) = delete; BaseSignal(const BaseSignal&) = delete;
Signal(Signal&&) MIJIN_NOEXCEPT = default; BaseSignal(BaseSignal&&) MIJIN_NOEXCEPT = default;
void reinit(TAllocator<void> allocator = {})
{
MIJIN_ASSERT(handlers_.empty(), "Attempting to re-initialize a signal that already has handlers.");
handlers_ = handler_vector_t(TAllocator<RegisteredHandler>(std::move(allocator)));
}
public: public:
Signal& operator=(const Signal&) = delete; BaseSignal& operator=(const BaseSignal&) = delete;
Signal& operator=(Signal&&) MIJIN_NOEXCEPT = default; BaseSignal& operator=(BaseSignal&&) MIJIN_NOEXCEPT = default;
public: public:
template<typename THandler, typename TWeak = void> template<typename THandler, typename TWeak = void>
inline token_t connect(THandler handler, Oneshot oneshot = Oneshot::NO, std::weak_ptr<TWeak> referenced = std::weak_ptr<TWeak>()) MIJIN_NOEXCEPT; inline token_t connect(THandler handler, Oneshot oneshot = Oneshot::NO, std::weak_ptr<TWeak> referenced = std::weak_ptr<TWeak>()) MIJIN_NOEXCEPT;
@ -70,13 +76,16 @@ public:
inline void emit(TArgs2&&... args) MIJIN_NOEXCEPT; inline void emit(TArgs2&&... args) MIJIN_NOEXCEPT;
}; };
template<typename... TArgs>
using Signal = BaseSignal<MIJIN_DEFAULT_ALLOCATOR, TArgs...>;
// //
// public functions // public functions
// //
template<typename... TArgs> template<template<typename> typename TAllocator, typename... TArgs>
template<typename THandler, typename TWeak> template<typename THandler, typename TWeak>
inline auto Signal<TArgs...>::connect(THandler handler, Oneshot oneshot, std::weak_ptr<TWeak> referenced) MIJIN_NOEXCEPT -> token_t inline auto BaseSignal<TAllocator, TArgs...>::connect(THandler handler, Oneshot oneshot, std::weak_ptr<TWeak> referenced) MIJIN_NOEXCEPT -> token_t
{ {
std::lock_guard lock(handlersMutex_); std::lock_guard lock(handlersMutex_);
@ -91,9 +100,9 @@ inline auto Signal<TArgs...>::connect(THandler handler, Oneshot oneshot, std::we
return nextToken++; return nextToken++;
} }
template<typename... TArgs> template<template<typename> typename TAllocator, typename... TArgs>
template<typename TObject, typename TWeak> template<typename TObject, typename TWeak>
inline auto Signal<TArgs...>::connect(TObject& object, void (TObject::* handler)(TArgs...), Oneshot oneshot, std::weak_ptr<TWeak> referenced) MIJIN_NOEXCEPT -> token_t inline auto BaseSignal<TAllocator, TArgs...>::connect(TObject& object, void (TObject::* handler)(TArgs...), Oneshot oneshot, std::weak_ptr<TWeak> referenced) MIJIN_NOEXCEPT -> token_t
{ {
std::lock_guard lock(handlersMutex_); std::lock_guard lock(handlersMutex_);
@ -111,8 +120,8 @@ inline auto Signal<TArgs...>::connect(TObject& object, void (TObject::* handler)
return nextToken++; return nextToken++;
} }
template<typename... TArgs> template<template<typename> typename TAllocator, typename... TArgs>
inline void Signal<TArgs...>::disconnect(token_t token) MIJIN_NOEXCEPT inline void BaseSignal<TAllocator, TArgs...>::disconnect(token_t token) MIJIN_NOEXCEPT
{ {
std::lock_guard lock(handlersMutex_); std::lock_guard lock(handlersMutex_);
@ -123,9 +132,9 @@ inline void Signal<TArgs...>::disconnect(token_t token) MIJIN_NOEXCEPT
handlers_.erase(it, handlers_.end()); handlers_.erase(it, handlers_.end());
} }
template<typename... TArgs> template<template<typename> typename TAllocator, typename... TArgs>
template<typename... TArgs2> template<typename... TArgs2>
inline void Signal<TArgs...>::emit(TArgs2&&... args) MIJIN_NOEXCEPT inline void BaseSignal<TAllocator, TArgs...>::emit(TArgs2&&... args) MIJIN_NOEXCEPT
{ {
std::lock_guard lock(handlersMutex_); std::lock_guard lock(handlersMutex_);