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;
explicit EntityOwner(Entity* entity);
EntityOwner(const EntityOwner& handle) = delete;
EntityOwner(EntityOwner&& handle);
EntityOwner(EntityOwner&& handle) noexcept = default;
~EntityOwner();
void Reset(Entity* entity = nullptr);
@ -25,7 +25,7 @@ namespace Ndk
EntityOwner& operator=(Entity* entity);
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);
}
inline EntityOwner::EntityOwner(EntityOwner&& handle) :
EntityHandle(std::move(handle))
{
}
inline EntityOwner::~EntityOwner()
{
Reset(nullptr);
@ -44,13 +39,6 @@ namespace Ndk
return *this;
}
inline EntityOwner& EntityOwner::operator=(EntityOwner&& handle)
{
Reset(std::move(handle));
return *this;
}
}
namespace std

View File

@ -36,7 +36,8 @@ namespace Nz
private:
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;
};

View File

@ -71,14 +71,24 @@ namespace Nz
}
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
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());
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();
explicit ObjectHandle(T* object);
ObjectHandle(const ObjectHandle& handle);
ObjectHandle(ObjectHandle&& handle) noexcept;
~ObjectHandle();
T* GetObject() const;
@ -31,6 +32,7 @@ namespace Nz
void Reset(T* object = nullptr);
void Reset(const ObjectHandle& handle);
void Reset(ObjectHandle&& handle) noexcept;
ObjectHandle& Swap(ObjectHandle& handle);
@ -42,6 +44,7 @@ namespace Nz
ObjectHandle& operator=(T* object);
ObjectHandle& operator=(const ObjectHandle& handle);
ObjectHandle& operator=(ObjectHandle&& handle) noexcept;
static const ObjectHandle InvalidHandle;

View File

@ -29,6 +29,13 @@ namespace Nz
Reset(handle);
}
template<typename T>
ObjectHandle<T>::ObjectHandle(ObjectHandle<T>&& handle) noexcept :
ObjectHandle()
{
Reset(std::move(handle));
}
template<typename T>
ObjectHandle<T>::~ObjectHandle()
{
@ -66,6 +73,19 @@ namespace Nz
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>
ObjectHandle<T>& ObjectHandle<T>::Swap(ObjectHandle<T>& handle)
{
@ -138,6 +158,14 @@ namespace Nz
return *this;
}
template<typename T>
ObjectHandle<T>& ObjectHandle<T>::operator=(ObjectHandle<T>&& handle) noexcept
{
Reset(std::move(handle));
return *this;
}
template<typename T>
void ObjectHandle<T>::OnObjectDestroyed()
{