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.cpp | 428 ++++++++++++++++++++++----------------------- 1 file changed, 214 insertions(+), 214 deletions(-) (limited to 'core/src/Utils/Sigslot.cpp') diff --git a/core/src/Utils/Sigslot.cpp b/core/src/Utils/Sigslot.cpp index a36eb2f..14deece 100644 --- a/core/src/Utils/Sigslot.cpp +++ b/core/src/Utils/Sigslot.cpp @@ -1,214 +1,214 @@ -#include "Sigslot.hpp" - -#include - -bool SignalStub::Connection::IsOccupied() const { - return id != InvalidId; -} - -SignalStub::SignalStub(IWrapper& wrapper) - : mWrapper{ &wrapper } { -} - -SignalStub::~SignalStub() { - RemoveAllConnections(); -} - -std::span SignalStub::GetConnections() const { - return mConnections; -} - -SignalStub::Connection& SignalStub::InsertConnection(SlotGuard* guard) { - Connection* result; - int size = static_cast(mConnections.size()); - for (int i = 0; i < size; ++i) { - auto& conn = mConnections[i]; - if (!conn.IsOccupied()) { - result = &conn; - result->id = i; - goto setup; - } - } - - mConnections.push_back(Connection{}); - result = &mConnections.back(); - result->id = size; - -setup: - if (guard) { - result->guard = guard; - result->slotId = guard->InsertConnection(*this, result->id); - } - return *result; -} - -void SignalStub::RemoveConnection(int id) { - if (id >= 0 && id < mConnections.size()) { - auto& conn = mConnections[id]; - if (conn.IsOccupied()) { - mWrapper->RemoveFunction(conn.id); - if (conn.guard) { - conn.guard->RemoveConnection(conn.slotId); - } - - conn.guard = nullptr; - conn.slotId = SignalStub::InvalidId; - conn.id = SignalStub::InvalidId; - } - } -} - -void SignalStub::RemoveConnectionFor(SlotGuard& guard) { - guard.RemoveConnectionFor(*this); -} - -void SignalStub::RemoveAllConnections() { - for (size_t i = 0; i < mConnections.size(); ++i) { - RemoveConnection(i); - } -} - -SlotGuard::SlotGuard() { -} - -SlotGuard::~SlotGuard() { - DisconnectAll(); -} - -void SlotGuard::DisconnectAll() { - for (auto& conn : mConnections) { - if (conn.stub) { - // Also calls SlotGuard::removeConnection, our copy of the data will be cleared in it - conn.stub->RemoveConnection(conn.stubId); - } - } -} - -int SlotGuard::InsertConnection(SignalStub& stub, int stubId) { - int size = static_cast(mConnections.size()); - for (int i = 0; i < size; ++i) { - auto& conn = mConnections[i]; - if (!conn.stub) { - conn.stub = &stub; - conn.stubId = stubId; - return i; - } - } - - mConnections.push_back(Connection{}); - auto& conn = mConnections.back(); - conn.stub = &stub; - conn.stubId = stubId; - return size; -} - -void SlotGuard::RemoveConnectionFor(SignalStub& stub) { - for (auto& conn : mConnections) { - if (conn.stub == &stub) { - conn.stub->RemoveConnection(conn.stubId); - } - } -} - -void SlotGuard::RemoveConnection(int slotId) { - mConnections[slotId] = {}; -} - -TEST_CASE("Signal connect and disconnect") { - Signal<> sig; - - int counter = 0; - int id = sig.Connect([&]() { counter++; }); - - sig(); - CHECK(counter == 1); - - sig(); - CHECK(counter == 2); - - sig.Disconnect(id); - sig(); - CHECK(counter == 2); -} - -TEST_CASE("Signal with parameters") { - Signal sig; - - int counter = 0; - int id = sig.Connect([&](int i) { counter += i; }); - - sig(1); - CHECK(counter == 1); - - sig(0); - CHECK(counter == 1); - - sig(4); - CHECK(counter == 5); - - sig.Disconnect(id); - sig(1); - CHECK(counter == 5); -} - -TEST_CASE("Signal disconnectAll()") { - Signal<> sig; - - int counter1 = 0; - int counter2 = 0; - sig.Connect([&]() { counter1++; }); - sig.Connect([&]() { counter2++; }); - - sig(); - CHECK(counter1 == 1); - CHECK(counter2 == 1); - - sig(); - CHECK(counter1 == 2); - CHECK(counter2 == 2); - - sig.DisconnectAll(); - sig(); - CHECK(counter1 == 2); - CHECK(counter2 == 2); -} - -TEST_CASE("SlotGuard auto-disconnection") { - int counter1 = 0; - int counter2 = 0; - Signal<> sig; - - { - SlotGuard guard; - sig.Connect(guard, [&]() { counter1 += 1; }); - sig.Connect(guard, [&]() { counter2 += 1; }); - - sig(); - CHECK(counter1 == 1); - CHECK(counter2 == 1); - - sig(); - CHECK(counter1 == 2); - CHECK(counter2 == 2); - } - - sig(); - CHECK(counter1 == 2); - CHECK(counter2 == 2); -} - -TEST_CASE("Signal destruct before SlotGuard") { - int counter = 0; - SlotGuard guard; - - { - Signal<> sig2; - sig2.Connect(guard, [&]() { counter++; }); - - sig2(); - CHECK(counter == 1); - } - - // Shouldn't error - guard.DisconnectAll(); -} +#include "Sigslot.hpp" + +#include + +bool SignalStub::Connection::IsOccupied() const { + return id != InvalidId; +} + +SignalStub::SignalStub(IWrapper& wrapper) + : mWrapper{ &wrapper } { +} + +SignalStub::~SignalStub() { + RemoveAllConnections(); +} + +std::span SignalStub::GetConnections() const { + return mConnections; +} + +SignalStub::Connection& SignalStub::InsertConnection(SlotGuard* guard) { + Connection* result; + int size = static_cast(mConnections.size()); + for (int i = 0; i < size; ++i) { + auto& conn = mConnections[i]; + if (!conn.IsOccupied()) { + result = &conn; + result->id = i; + goto setup; + } + } + + mConnections.push_back(Connection{}); + result = &mConnections.back(); + result->id = size; + +setup: + if (guard) { + result->guard = guard; + result->slotId = guard->InsertConnection(*this, result->id); + } + return *result; +} + +void SignalStub::RemoveConnection(int id) { + if (id >= 0 && id < mConnections.size()) { + auto& conn = mConnections[id]; + if (conn.IsOccupied()) { + mWrapper->RemoveFunction(conn.id); + if (conn.guard) { + conn.guard->RemoveConnection(conn.slotId); + } + + conn.guard = nullptr; + conn.slotId = SignalStub::InvalidId; + conn.id = SignalStub::InvalidId; + } + } +} + +void SignalStub::RemoveConnectionFor(SlotGuard& guard) { + guard.RemoveConnectionFor(*this); +} + +void SignalStub::RemoveAllConnections() { + for (size_t i = 0; i < mConnections.size(); ++i) { + RemoveConnection(i); + } +} + +SlotGuard::SlotGuard() { +} + +SlotGuard::~SlotGuard() { + DisconnectAll(); +} + +void SlotGuard::DisconnectAll() { + for (auto& conn : mConnections) { + if (conn.stub) { + // Also calls SlotGuard::removeConnection, our copy of the data will be cleared in it + conn.stub->RemoveConnection(conn.stubId); + } + } +} + +int SlotGuard::InsertConnection(SignalStub& stub, int stubId) { + int size = static_cast(mConnections.size()); + for (int i = 0; i < size; ++i) { + auto& conn = mConnections[i]; + if (!conn.stub) { + conn.stub = &stub; + conn.stubId = stubId; + return i; + } + } + + mConnections.push_back(Connection{}); + auto& conn = mConnections.back(); + conn.stub = &stub; + conn.stubId = stubId; + return size; +} + +void SlotGuard::RemoveConnectionFor(SignalStub& stub) { + for (auto& conn : mConnections) { + if (conn.stub == &stub) { + conn.stub->RemoveConnection(conn.stubId); + } + } +} + +void SlotGuard::RemoveConnection(int slotId) { + mConnections[slotId] = {}; +} + +TEST_CASE("Signal connect and disconnect") { + Signal<> sig; + + int counter = 0; + int id = sig.Connect([&]() { counter++; }); + + sig(); + CHECK(counter == 1); + + sig(); + CHECK(counter == 2); + + sig.Disconnect(id); + sig(); + CHECK(counter == 2); +} + +TEST_CASE("Signal with parameters") { + Signal sig; + + int counter = 0; + int id = sig.Connect([&](int i) { counter += i; }); + + sig(1); + CHECK(counter == 1); + + sig(0); + CHECK(counter == 1); + + sig(4); + CHECK(counter == 5); + + sig.Disconnect(id); + sig(1); + CHECK(counter == 5); +} + +TEST_CASE("Signal disconnectAll()") { + Signal<> sig; + + int counter1 = 0; + int counter2 = 0; + sig.Connect([&]() { counter1++; }); + sig.Connect([&]() { counter2++; }); + + sig(); + CHECK(counter1 == 1); + CHECK(counter2 == 1); + + sig(); + CHECK(counter1 == 2); + CHECK(counter2 == 2); + + sig.DisconnectAll(); + sig(); + CHECK(counter1 == 2); + CHECK(counter2 == 2); +} + +TEST_CASE("SlotGuard auto-disconnection") { + int counter1 = 0; + int counter2 = 0; + Signal<> sig; + + { + SlotGuard guard; + sig.Connect(guard, [&]() { counter1 += 1; }); + sig.Connect(guard, [&]() { counter2 += 1; }); + + sig(); + CHECK(counter1 == 1); + CHECK(counter2 == 1); + + sig(); + CHECK(counter1 == 2); + CHECK(counter2 == 2); + } + + sig(); + CHECK(counter1 == 2); + CHECK(counter2 == 2); +} + +TEST_CASE("Signal destruct before SlotGuard") { + int counter = 0; + SlotGuard guard; + + { + Signal<> sig2; + sig2.Connect(guard, [&]() { counter++; }); + + sig2(); + CHECK(counter == 1); + } + + // Shouldn't error + guard.DisconnectAll(); +} -- cgit v1.2.3-70-g09d2