Core/ObjectHandle: Add noexcept move constructor/assignment

Former-commit-id: d726fab8750fe02fbed0e605bbf9a757c7f035de
This commit is contained in:
Lynix 2016-05-09 09:03:11 +02:00
parent 11c435aa7d
commit e9608366cd
6 changed files with 49 additions and 19 deletions

View File

@ -17,7 +17,7 @@ namespace Ndk
EntityOwner() = default; EntityOwner() = default;
explicit EntityOwner(Entity* entity); explicit EntityOwner(Entity* entity);
EntityOwner(const EntityOwner& handle) = delete; EntityOwner(const EntityOwner& handle) = delete;
EntityOwner(EntityOwner&& handle); EntityOwner(EntityOwner&& handle) noexcept = default;
~EntityOwner(); ~EntityOwner();
void Reset(Entity* entity = nullptr); void Reset(Entity* entity = nullptr);
@ -25,7 +25,7 @@ namespace Ndk
EntityOwner& operator=(Entity* entity); EntityOwner& operator=(Entity* entity);
EntityOwner& operator=(const EntityOwner& handle) = delete; EntityOwner& operator=(const EntityOwner& handle) = delete;
EntityOwner& operator=(EntityOwner&& handle); EntityOwner& operator=(EntityOwner&& handle) noexcept = default;
}; };
} }

View File

@ -14,11 +14,6 @@ namespace Ndk
Reset(entity); Reset(entity);
} }
inline EntityOwner::EntityOwner(EntityOwner&& handle) :
EntityHandle(std::move(handle))
{
}
inline EntityOwner::~EntityOwner() inline EntityOwner::~EntityOwner()
{ {
Reset(nullptr); Reset(nullptr);
@ -44,13 +39,6 @@ namespace Ndk
return *this; return *this;
} }
inline EntityOwner& EntityOwner::operator=(EntityOwner&& handle)
{
Reset(std::move(handle));
return *this;
}
} }
namespace std namespace std

View File

@ -36,7 +36,8 @@ namespace Nz
private: private:
void RegisterHandle(ObjectHandle<T>* handle); void RegisterHandle(ObjectHandle<T>* handle);
void UnregisterHandle(ObjectHandle<T>* handle); void UnregisterHandle(ObjectHandle<T>* handle) noexcept;
void UpdateHandle(ObjectHandle<T>* oldHandle, ObjectHandle<T>* newHandle) noexcept;
std::vector<ObjectHandle<T>*> m_handles; std::vector<ObjectHandle<T>*> m_handles;
}; };

View File

@ -71,14 +71,24 @@ namespace Nz
} }
template<typename T> template<typename T>
void HandledObject<T>::UnregisterHandle(ObjectHandle<T>* handle) void HandledObject<T>::UnregisterHandle(ObjectHandle<T>* handle) noexcept
{ {
///DOC: Un handle ne doit être libéré qu'une fois, et doit faire partie de la liste, sous peine de crash ///DOC: Un handle ne doit être libéré qu'une fois, et doit faire partie de la liste, sous peine de crash
auto it = std::find(m_handles.begin(), m_handles.end(), handle); auto it = std::find(m_handles.begin(), m_handles.end(), handle);
NazaraAssert(it != m_handles.end(), "Handle not registred"); NazaraAssert(it != m_handles.end(), "Handle not registered");
// On échange cet élément avec le dernier, et on diminue la taille du vector de 1 // Swap and pop idiom, more efficient than vector::erase
std::swap(*it, m_handles.back()); std::swap(*it, m_handles.back());
m_handles.pop_back(); m_handles.pop_back();
} }
template<typename T>
void HandledObject<T>::UpdateHandle(ObjectHandle<T>* oldHandle, ObjectHandle<T>* newHandle) noexcept
{
auto it = std::find(m_handles.begin(), m_handles.end(), oldHandle);
NazaraAssert(it != m_handles.end(), "Handle not registered");
// Simply update the handle
*it = newHandle;
}
} }

View File

@ -23,6 +23,7 @@ namespace Nz
ObjectHandle(); ObjectHandle();
explicit ObjectHandle(T* object); explicit ObjectHandle(T* object);
ObjectHandle(const ObjectHandle& handle); ObjectHandle(const ObjectHandle& handle);
ObjectHandle(ObjectHandle&& handle) noexcept;
~ObjectHandle(); ~ObjectHandle();
T* GetObject() const; T* GetObject() const;
@ -31,6 +32,7 @@ namespace Nz
void Reset(T* object = nullptr); void Reset(T* object = nullptr);
void Reset(const ObjectHandle& handle); void Reset(const ObjectHandle& handle);
void Reset(ObjectHandle&& handle) noexcept;
ObjectHandle& Swap(ObjectHandle& handle); ObjectHandle& Swap(ObjectHandle& handle);
@ -42,6 +44,7 @@ namespace Nz
ObjectHandle& operator=(T* object); ObjectHandle& operator=(T* object);
ObjectHandle& operator=(const ObjectHandle& handle); ObjectHandle& operator=(const ObjectHandle& handle);
ObjectHandle& operator=(ObjectHandle&& handle) noexcept;
static const ObjectHandle InvalidHandle; static const ObjectHandle InvalidHandle;

View File

@ -24,11 +24,18 @@ namespace Nz
template<typename T> template<typename T>
ObjectHandle<T>::ObjectHandle(const ObjectHandle<T>& handle) : ObjectHandle<T>::ObjectHandle(const ObjectHandle<T>& handle) :
ObjectHandle() ObjectHandle()
{ {
Reset(handle); Reset(handle);
} }
template<typename T>
ObjectHandle<T>::ObjectHandle(ObjectHandle<T>&& handle) noexcept :
ObjectHandle()
{
Reset(std::move(handle));
}
template<typename T> template<typename T>
ObjectHandle<T>::~ObjectHandle() ObjectHandle<T>::~ObjectHandle()
{ {
@ -66,6 +73,19 @@ namespace Nz
Reset(handle.GetObject()); Reset(handle.GetObject());
} }
template<typename T>
void ObjectHandle<T>::Reset(ObjectHandle<T>&& handle) noexcept
{
if (m_object)
m_object->UnregisterHandle(this);
if (T* object = handle.GetObject())
{
object->UpdateHandle(&handle, this);
handle.m_object = nullptr;
}
}
template<typename T> template<typename T>
ObjectHandle<T>& ObjectHandle<T>::Swap(ObjectHandle<T>& handle) ObjectHandle<T>& ObjectHandle<T>::Swap(ObjectHandle<T>& handle)
{ {
@ -138,6 +158,14 @@ namespace Nz
return *this; return *this;
} }
template<typename T>
ObjectHandle<T>& ObjectHandle<T>::operator=(ObjectHandle<T>&& handle) noexcept
{
Reset(std::move(handle));
return *this;
}
template<typename T> template<typename T>
void ObjectHandle<T>::OnObjectDestroyed() void ObjectHandle<T>::OnObjectDestroyed()
{ {