// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp #include #include #include #include namespace Nz { template ObjectHandle::ObjectHandle() : m_object(nullptr) { } template ObjectHandle::ObjectHandle(T* object) : ObjectHandle() { Reset(object); } template ObjectHandle::ObjectHandle(const ObjectHandle& handle) : ObjectHandle() { Reset(handle); } template ObjectHandle::ObjectHandle(ObjectHandle&& handle) noexcept : ObjectHandle() { Reset(std::move(handle)); } template ObjectHandle::~ObjectHandle() { Reset(nullptr); } template T* ObjectHandle::GetObject() const { return m_object; } template bool ObjectHandle::IsValid() const { return m_object != nullptr; } template void ObjectHandle::Reset(T* object) { // Si nous avions déjà une entité, nous devons l'informer que nous ne pointons plus sur elle if (m_object) m_object->UnregisterHandle(this); m_object = object; if (m_object) // On informe la nouvelle entité que nous pointons sur elle m_object->RegisterHandle(this); } template void ObjectHandle::Reset(const ObjectHandle& handle) { Reset(handle.GetObject()); } template void ObjectHandle::Reset(ObjectHandle&& handle) noexcept { if (m_object) m_object->UnregisterHandle(this); if (T* object = handle.GetObject()) { object->UpdateHandle(&handle, this); handle.m_object = nullptr; } } template ObjectHandle& ObjectHandle::Swap(ObjectHandle& handle) { // Comme nous inversons les handles, nous devons prévenir les entités // La version par défaut de swap (à base de move) aurait fonctionné, // mais en enregistrant les handles une fois de plus que nécessaire (à cause de la copie temporaire). if (m_object) { m_object->UnregisterHandle(this); m_object->RegisterHandle(&handle); } if (handle.m_object) { handle.m_object->UnregisterHandle(&handle); handle.m_object->RegisterHandle(this); } // On effectue l'échange std::swap(m_object, handle.m_object); return *this; } template Nz::String ObjectHandle::ToString() const { Nz::StringStream ss; ss << "ObjectHandle("; if (IsValid()) ss << m_object->ToString(); else ss << "Null"; ss << ')'; return ss; } template ObjectHandle::operator bool() const { return IsValid(); } template ObjectHandle::operator T*() const { return m_object; } template T* ObjectHandle::operator->() const { return m_object; } template ObjectHandle& ObjectHandle::operator=(T* entity) { Reset(entity); return *this; } template ObjectHandle& ObjectHandle::operator=(const ObjectHandle& handle) { Reset(handle); return *this; } template ObjectHandle& ObjectHandle::operator=(ObjectHandle&& handle) noexcept { Reset(std::move(handle)); return *this; } template void ObjectHandle::OnObjectDestroyed() { // Shortcut m_object = nullptr; } template void ObjectHandle::OnObjectMoved(T* newObject) { // The object has been moved, update our pointer m_object = newObject; } template std::ostream& operator<<(std::ostream& out, const ObjectHandle& handle) { return handle.ToString(); } template bool operator==(const ObjectHandle& lhs, const ObjectHandle& rhs) { return lhs.GetObject() == rhs.GetObject(); } template bool operator==(const T& lhs, const ObjectHandle& rhs) { return &lhs == rhs.GetObject(); } template bool operator==(const ObjectHandle& lhs, const T& rhs) { return lhs.GetObject() == &rhs; } template bool operator!=(const ObjectHandle& lhs, const ObjectHandle& rhs) { return !(lhs == rhs); } template bool operator!=(const T& lhs, const ObjectHandle& rhs) { return !(lhs == rhs); } template bool operator!=(const ObjectHandle& lhs, const T& rhs) { return !(lhs == rhs); } template bool operator<(const ObjectHandle& lhs, const ObjectHandle& rhs) { return lhs.m_object < rhs.m_object; } template bool operator<(const T& lhs, const ObjectHandle& rhs) { return &lhs < rhs.m_object; } template bool operator<(const ObjectHandle& lhs, const T& rhs) { return lhs.m_object < &rhs; } template bool operator<=(const ObjectHandle& lhs, const ObjectHandle& rhs) { return !(lhs > rhs); } template bool operator<=(const T& lhs, const ObjectHandle& rhs) { return !(lhs > rhs); } template bool operator<=(const ObjectHandle& lhs, const T& rhs) { return !(lhs > rhs); } template bool operator>(const ObjectHandle& lhs, const ObjectHandle& rhs) { return rhs < lhs; } template bool operator>(const T& lhs, const ObjectHandle& rhs) { return rhs < lhs; } template bool operator>(const ObjectHandle& lhs, const T& rhs) { return rhs < lhs; } template bool operator>=(const ObjectHandle& lhs, const ObjectHandle& rhs) { return !(lhs < rhs); } template bool operator>=(const T& lhs, const ObjectHandle& rhs) { return !(lhs < rhs); } template bool operator>=(const ObjectHandle& lhs, const T& rhs) { return !(lhs < rhs); } template const ObjectHandle ObjectHandle::InvalidHandle; } namespace std { template void swap(Nz::ObjectHandle& lhs, Nz::ObjectHandle& rhs) { lhs.Swap(rhs); } }