Core/Signal: Optimize

Former-commit-id: 36fee5057acabf1b6bb8ef93ad6741206e10121b
This commit is contained in:
Lynix 2015-06-07 01:08:08 +02:00
parent 32e55c2e72
commit 1a0057313c
2 changed files with 19 additions and 10 deletions

View File

@ -9,7 +9,7 @@
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <list> #include <vector>
template<typename... Args> template<typename... Args>
class NzSignal class NzSignal
@ -40,7 +40,7 @@ class NzSignal
struct Slot; struct Slot;
using SlotPtr = std::shared_ptr<Slot>; using SlotPtr = std::shared_ptr<Slot>;
using SlotList = std::list<SlotPtr>; using SlotList = std::vector<SlotPtr>;
struct Slot struct Slot
{ {
@ -51,7 +51,7 @@ class NzSignal
Callback callback; Callback callback;
NzSignal* signal; NzSignal* signal;
typename SlotList::iterator it; typename SlotList::size_type index;
}; };
void Disconnect(const SlotPtr& slot); void Disconnect(const SlotPtr& slot);

View File

@ -3,7 +3,7 @@
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Error.hpp> #include <Nazara/Core/Error.hpp>
#include <algorithm> #include <utility>
#include <Nazara/Core/Debug.hpp> #include <Nazara/Core/Debug.hpp>
template<typename... Args> template<typename... Args>
@ -27,16 +27,15 @@ typename NzSignal<Args...>::Connection&& NzSignal<Args...>::Connect(const Callba
template<typename... Args> template<typename... Args>
typename NzSignal<Args...>::Connection&& NzSignal<Args...>::Connect(Callback&& func) typename NzSignal<Args...>::Connection&& NzSignal<Args...>::Connect(Callback&& func)
{ {
NazaraAssert(func, "Invalid function");
auto tempPtr = std::make_shared<Slot>(this); auto tempPtr = std::make_shared<Slot>(this);
tempPtr->callback = std::move(func); tempPtr->callback = std::move(func);
tempPtr->index = m_slots.size();
m_slots.emplace_back(std::move(tempPtr)); m_slots.emplace_back(std::move(tempPtr));
const auto& slotPtr = m_slots.back(); return Connection(m_slots.back());
slotPtr->it = m_slots.end();
--slotPtr->it;
return Connection(slotPtr);
} }
template<typename... Args> template<typename... Args>
@ -81,7 +80,17 @@ NzSignal<Args...>& NzSignal<Args...>::operator=(NzSignal&& signal)
template<typename... Args> template<typename... Args>
void NzSignal<Args...>::Disconnect(const SlotPtr& slot) void NzSignal<Args...>::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
} }