// Copyright (C) 2017 Jérôme Leclercq // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequisites.hpp #include #include #include #include #include namespace Nz { /*! * \ingroup core * \class Nz::HandledObject * \brief Core class that represents a handled object */ /*! * \brief Constructs a HandledObject object by assignation * * \param object HandledObject to assign into this */ template HandledObject::HandledObject(const HandledObject& object) { NazaraUnused(object); // Don't copy anything, we're a copy of the object, we have no handle right now } /*! * \brief Constructs a HandledObject object by move semantic * * \param object HandledObject to move into this */ template HandledObject::HandledObject(HandledObject&& object) : m_handles(std::move(object.m_handles)) { for (ObjectHandle* handle : m_handles) handle->OnObjectMoved(static_cast(this)); } /*! * \brief Destructs the object and calls UnregisterAllHandles * * \see UnregisterAllHandles */ template HandledObject::~HandledObject() { UnregisterAllHandles(); } /*! * \brief Creates a ObjectHandle for this * \return ObjectHandle to this */ template ObjectHandle HandledObject::CreateHandle() { return ObjectHandle(static_cast(this)); } /*! * \brief Sets the reference of the HandledObject with the handle from another * \return A reference to this * * \param object The other HandledObject */ template HandledObject& HandledObject::operator=(const HandledObject& object) { NazaraUnused(object); // Nothing to do return *this; } /*! * \brief Moves the HandledObject into this * \return A reference to this * * \param object HandledObject to move in this */ template HandledObject& HandledObject::operator=(HandledObject&& object) { UnregisterAllHandles(); m_handles = std::move(object.m_handles); for (ObjectHandle* handle : m_handles) handle->OnObjectMoved(static_cast(this)); return *this; } /*! * \brief Registers a handle * * \param handle Handle to register * * \remark One handle can only be registered once, errors can occur if it's more than once */ template void HandledObject::RegisterHandle(ObjectHandle* handle) { m_handles.push_back(handle); } /*! * \brief Unregisters all handles */ template void HandledObject::UnregisterAllHandles() { // Tell every handle we got destroyed, to null them for (ObjectHandle* handle : m_handles) handle->OnObjectDestroyed(); m_handles.clear(); } /*! * \brief Unregisters a handle * * \param handle Handle to unregister * * \remark One handle can only be unregistered once, crash can occur if it's more than once * \remark Produces a NazaraAssert if handle not registered */ template void HandledObject::UnregisterHandle(ObjectHandle* handle) noexcept { auto it = std::find(m_handles.begin(), m_handles.end(), handle); NazaraAssert(it != m_handles.end(), "Handle not registered"); // Swap and pop idiom, more efficient than vector::erase std::swap(*it, m_handles.back()); m_handles.pop_back(); } /*! * \brief Updates one handle with another * * \param oldHandle Old handle to replace * \param newHandle New handle to take place * * \remark Produces a NazaraAssert if handle not registered */ template void HandledObject::UpdateHandle(ObjectHandle* oldHandle, ObjectHandle* 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; } }