diff --git a/include/Nazara/Core/Signal.hpp b/include/Nazara/Core/Signal.hpp index f551e9767..83e30b06f 100644 --- a/include/Nazara/Core/Signal.hpp +++ b/include/Nazara/Core/Signal.hpp @@ -9,7 +9,7 @@ #include #include -#include +#include template class NzSignal @@ -40,7 +40,7 @@ class NzSignal struct Slot; using SlotPtr = std::shared_ptr; - using SlotList = std::list; + using SlotList = std::vector; struct Slot { @@ -51,7 +51,7 @@ class NzSignal Callback callback; NzSignal* signal; - typename SlotList::iterator it; + typename SlotList::size_type index; }; void Disconnect(const SlotPtr& slot); diff --git a/include/Nazara/Core/Signal.inl b/include/Nazara/Core/Signal.inl index 75a82624f..ac92f7a6e 100644 --- a/include/Nazara/Core/Signal.inl +++ b/include/Nazara/Core/Signal.inl @@ -3,7 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include +#include #include template @@ -27,16 +27,15 @@ typename NzSignal::Connection&& NzSignal::Connect(const Callba template typename NzSignal::Connection&& NzSignal::Connect(Callback&& func) { + NazaraAssert(func, "Invalid function"); + auto tempPtr = std::make_shared(this); tempPtr->callback = std::move(func); + tempPtr->index = m_slots.size(); m_slots.emplace_back(std::move(tempPtr)); - const auto& slotPtr = m_slots.back(); - slotPtr->it = m_slots.end(); - --slotPtr->it; - - return Connection(slotPtr); + return Connection(m_slots.back()); } template @@ -81,7 +80,17 @@ NzSignal& NzSignal::operator=(NzSignal&& signal) template void NzSignal::Disconnect(const SlotPtr& slot) { - m_slots.erase(slot->it); + NazaraAssert(slot, "Invalid slot pointer"); + NazaraAssert(slot->index < m_slots.size(), "Invalid slot index"); + + // "Swap this slot with the last one and pop" idiom + // This will preserve slot indexes + SlotPtr& current = m_slots[slot->index]; + + std::swap(current, m_slots.back()); + m_slots.pop_back(); + + current->index = slot->index; //< Update the moved slot index }