From 44f5fa5c8f258e8fc1f7d7e2e45e0485bd6cc490 Mon Sep 17 00:00:00 2001 From: rtk0c Date: Wed, 31 Mar 2021 20:19:18 -0700 Subject: Complete items tab (UI and serialization) --- core/src/Utils/Sigslot.hpp | 300 ++++++++++++++++++++++----------------------- 1 file changed, 150 insertions(+), 150 deletions(-) (limited to 'core/src/Utils/Sigslot.hpp') diff --git a/core/src/Utils/Sigslot.hpp b/core/src/Utils/Sigslot.hpp index 9aa5f4b..2751d9a 100644 --- a/core/src/Utils/Sigslot.hpp +++ b/core/src/Utils/Sigslot.hpp @@ -1,150 +1,150 @@ -#pragma once - -#include "Utils/fwd.hpp" - -#include -#include -#include -#include -#include - -class SignalStub { -public: - /// Non-template interface for Signal to implement (a barrier to stop template - /// arguments propagation). - class IWrapper { - public: - virtual ~IWrapper() = default; - virtual void RemoveFunction(int id) = 0; - }; - - enum { - InvalidId = -1, - }; - - struct Connection { - SlotGuard* guard; - int slotId; - int id = InvalidId; // If `InvalidId`, then this "spot" is unused - - bool IsOccupied() const; - }; - -private: - std::vector mConnections; - IWrapper* mWrapper; - -private: - template - friend class Signal; - friend class SlotGuard; - - SignalStub(IWrapper& wrapper); - ~SignalStub(); - - SignalStub(const SignalStub&) = delete; - SignalStub& operator=(const SignalStub&) = delete; - SignalStub(SignalStub&&) = default; - SignalStub& operator=(SignalStub&&) = default; - - std::span GetConnections() const; - Connection& InsertConnection(SlotGuard* guard = nullptr); - void RemoveConnection(int id); - void RemoveConnectionFor(SlotGuard& guard); - void RemoveAllConnections(); -}; - -template -class Signal : public SignalStub::IWrapper { -private: - // Must be in this order so that mFunctions is still intact when mStub's destructor runs - std::vector> mFunctions; - SignalStub mStub; - -public: - Signal() - : mStub(*this) { - } - - virtual ~Signal() = default; - - Signal(const Signal&) = delete; - Signal& operator=(const Signal&) = delete; - Signal(Signal&&) = default; - Signal& operator=(Signal&&) = default; - - void operator()(TArgs... args) { - for (auto& conn : mStub.GetConnections()) { - if (conn.IsOccupied()) { - mFunctions[conn.id](std::forward(args)...); - } - } - } - - template - int Connect(TFunction slot) { - auto& conn = mStub.InsertConnection(); - mFunctions.resize(std::max(mFunctions.size(), (size_t)conn.id + 1)); - mFunctions[conn.id] = std::move(slot); - return conn.id; - } - - template - int Connect(SlotGuard& guard, TFunction slot) { - auto& conn = mStub.InsertConnection(&guard); - mFunctions.resize(std::max(mFunctions.size(), (size_t)conn.id + 1)); - mFunctions[conn.id] = std::move(slot); - return conn.id; - } - - void Disconnect(int id) { - mStub.RemoveConnection(id); - } - - void DisconnectFor(SlotGuard& guard) { - mStub.RemoveConnectionFor(guard); - } - - void DisconnectAll() { - mStub.RemoveAllConnections(); - } - - virtual void RemoveFunction(int id) { - mFunctions[id] = {}; - } -}; - -/// Automatic disconnection mechanism for Signal<>. -/// Bind connection to this guard by using the Connect(SlotGuard&, TFunction) overload. -/// Either DisconnectAll() or the destructor disconnects all connections bound to this guard. -class SlotGuard { -private: - struct Connection { - SignalStub* stub = nullptr; - int stubId = SignalStub::InvalidId; - }; - std::vector mConnections; - -public: - friend class SignalStub; - SlotGuard(); - ~SlotGuard(); - - SlotGuard(const SlotGuard&) = delete; - SlotGuard& operator=(const SlotGuard&) = delete; - SlotGuard(SlotGuard&&) = default; - SlotGuard& operator=(SlotGuard&&) = default; - - /// Disconnect all connection associated with this SlotGuard. - void DisconnectAll(); - -private: - /// \return Slot id. - int InsertConnection(SignalStub& stub, int stubId); - /// Remove the connection data in this associated with slotId. This does not invoke - /// the connections' stub's RemoveConnection function. - void RemoveConnection(int slotId); - /// Disconnect all connections from the given stub associated with this SlotGuard. - /// Implementation for SignalStub::RemoveConnectionsFor(SlotGuard&) - void RemoveConnectionFor(SignalStub& stub); -}; +#pragma once + +#include "Utils/fwd.hpp" + +#include +#include +#include +#include +#include + +class SignalStub { +public: + /// Non-template interface for Signal to implement (a barrier to stop template + /// arguments propagation). + class IWrapper { + public: + virtual ~IWrapper() = default; + virtual void RemoveFunction(int id) = 0; + }; + + enum { + InvalidId = -1, + }; + + struct Connection { + SlotGuard* guard; + int slotId; + int id = InvalidId; // If `InvalidId`, then this "spot" is unused + + bool IsOccupied() const; + }; + +private: + std::vector mConnections; + IWrapper* mWrapper; + +private: + template + friend class Signal; + friend class SlotGuard; + + SignalStub(IWrapper& wrapper); + ~SignalStub(); + + SignalStub(const SignalStub&) = delete; + SignalStub& operator=(const SignalStub&) = delete; + SignalStub(SignalStub&&) = default; + SignalStub& operator=(SignalStub&&) = default; + + std::span GetConnections() const; + Connection& InsertConnection(SlotGuard* guard = nullptr); + void RemoveConnection(int id); + void RemoveConnectionFor(SlotGuard& guard); + void RemoveAllConnections(); +}; + +template +class Signal : public SignalStub::IWrapper { +private: + // Must be in this order so that mFunctions is still intact when mStub's destructor runs + std::vector> mFunctions; + SignalStub mStub; + +public: + Signal() + : mStub(*this) { + } + + virtual ~Signal() = default; + + Signal(const Signal&) = delete; + Signal& operator=(const Signal&) = delete; + Signal(Signal&&) = default; + Signal& operator=(Signal&&) = default; + + void operator()(TArgs... args) { + for (auto& conn : mStub.GetConnections()) { + if (conn.IsOccupied()) { + mFunctions[conn.id](std::forward(args)...); + } + } + } + + template + int Connect(TFunction slot) { + auto& conn = mStub.InsertConnection(); + mFunctions.resize(std::max(mFunctions.size(), (size_t)conn.id + 1)); + mFunctions[conn.id] = std::move(slot); + return conn.id; + } + + template + int Connect(SlotGuard& guard, TFunction slot) { + auto& conn = mStub.InsertConnection(&guard); + mFunctions.resize(std::max(mFunctions.size(), (size_t)conn.id + 1)); + mFunctions[conn.id] = std::move(slot); + return conn.id; + } + + void Disconnect(int id) { + mStub.RemoveConnection(id); + } + + void DisconnectFor(SlotGuard& guard) { + mStub.RemoveConnectionFor(guard); + } + + void DisconnectAll() { + mStub.RemoveAllConnections(); + } + + virtual void RemoveFunction(int id) { + mFunctions[id] = {}; + } +}; + +/// Automatic disconnection mechanism for Signal<>. +/// Bind connection to this guard by using the Connect(SlotGuard&, TFunction) overload. +/// Either DisconnectAll() or the destructor disconnects all connections bound to this guard. +class SlotGuard { +private: + struct Connection { + SignalStub* stub = nullptr; + int stubId = SignalStub::InvalidId; + }; + std::vector mConnections; + +public: + friend class SignalStub; + SlotGuard(); + ~SlotGuard(); + + SlotGuard(const SlotGuard&) = delete; + SlotGuard& operator=(const SlotGuard&) = delete; + SlotGuard(SlotGuard&&) = default; + SlotGuard& operator=(SlotGuard&&) = default; + + /// Disconnect all connection associated with this SlotGuard. + void DisconnectAll(); + +private: + /// \return Slot id. + int InsertConnection(SignalStub& stub, int stubId); + /// Remove the connection data in this associated with slotId. This does not invoke + /// the connections' stub's RemoveConnection function. + void RemoveConnection(int slotId); + /// Disconnect all connections from the given stub associated with this SlotGuard. + /// Implementation for SignalStub::RemoveConnectionsFor(SlotGuard&) + void RemoveConnectionFor(SignalStub& stub); +}; -- cgit v1.2.3-70-g09d2