diff options
author | rtk0c <[email protected]> | 2022-06-30 21:38:53 -0700 |
---|---|---|
committer | rtk0c <[email protected]> | 2022-06-30 21:38:53 -0700 |
commit | 7fe47a9d5b1727a61dc724523b530762f6d6ba19 (patch) | |
tree | e95be6e66db504ed06d00b72c579565bab873277 /core/src/Utils/Sigslot.hpp | |
parent | 2cf952088d375ac8b2f45b144462af0953436cff (diff) |
Restructure project
Diffstat (limited to 'core/src/Utils/Sigslot.hpp')
-rw-r--r-- | core/src/Utils/Sigslot.hpp | 165 |
1 files changed, 0 insertions, 165 deletions
diff --git a/core/src/Utils/Sigslot.hpp b/core/src/Utils/Sigslot.hpp deleted file mode 100644 index 5638f12..0000000 --- a/core/src/Utils/Sigslot.hpp +++ /dev/null @@ -1,165 +0,0 @@ -#pragma once - -#include "Utils/fwd.hpp" - -#include <cstddef> -#include <functional> -#include <span> -#include <utility> -#include <vector> - -class SignalStub -{ -public: - /// Non-template interface for Signal<T...> 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<Connection> mConnections; - IWrapper* mWrapper; - -private: - template <class...> - 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<const Connection> GetConnections() const; - Connection& InsertConnection(SlotGuard* guard = nullptr); - void RemoveConnection(int id); - void RemoveConnectionFor(SlotGuard& guard); - void RemoveAllConnections(); -}; - -template <class... TArgs> -class Signal : public SignalStub::IWrapper -{ -private: - // Must be in this order so that mFunctions is still intact when mStub's destructor runs - std::vector<std::function<void(TArgs...)>> 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<TArgs>(args)...); - } - } - } - - template <class TFunction> - 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 <class TFunction> - 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<Connection> mConnections; - -public: - friend class SignalStub; - SlotGuard(); - ~SlotGuard(); - - SlotGuard(const SlotGuard&) = delete; - SlotGuard& operator=(const SlotGuard&) = delete; - SlotGuard(SlotGuard&&) = default; - SlotGuard& operator=(SlotGuard&&) = default; - - /// DisconnectBySource 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); - /// DisconnectBySource all connections from the given stub associated with this SlotGuard. - /// Implementation for SignalStub::RemoveConnectionsFor(SlotGuard&) - void RemoveConnectionFor(SignalStub& stub); -}; |