Separated reference counting from Resources

Former-commit-id: 7380818cfee9e249c11fd15da9ff7883a6e76565
This commit is contained in:
Lynix
2014-07-15 00:59:02 +02:00
parent 0af8bc4829
commit 9e04e8a0e4
51 changed files with 566 additions and 508 deletions

View File

@@ -0,0 +1,39 @@
// Copyright (C) 2014 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 <Nazara/Core/ObjectListener.hpp>
#include <Nazara/Core/Debug.hpp>
NzObjectListener::~NzObjectListener() = default;
bool NzObjectListener::OnObjectCreated(const NzRefCounted* object, int index)
{
NazaraUnused(object);
NazaraUnused(index);
return true;
}
bool NzObjectListener::OnObjectDestroy(const NzRefCounted* object, int index)
{
NazaraUnused(object);
NazaraUnused(index);
return true;
}
bool NzObjectListener::OnObjectModified(const NzRefCounted* object, int index, unsigned int code)
{
NazaraUnused(object);
NazaraUnused(index);
NazaraUnused(code);
return true;
}
void NzObjectListener::OnObjectReleased(const NzRefCounted* object, int index)
{
NazaraUnused(object);
NazaraUnused(index);
}

View File

@@ -0,0 +1,173 @@
// Copyright (C) 2014 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 <Nazara/Core/RefCounted.hpp>
#include <Nazara/Core/Config.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/ObjectListener.hpp>
#if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_REFCOUNTED
#include <Nazara/Core/ThreadSafety.hpp>
#else
#include <Nazara/Core/ThreadSafetyOff.hpp>
#endif
#include <Nazara/Core/Debug.hpp>
NzRefCounted::NzRefCounted(bool persistent) :
m_persistent(persistent),
m_referenceCount(0),
m_objectListenersLocked(false)
{
}
NzRefCounted::~NzRefCounted()
{
m_objectListenersLocked = true;
for (auto& pair : m_objectListeners)
pair.first->OnObjectReleased(this, pair.second.first);
#if NAZARA_CORE_SAFE
if (m_referenceCount > 0)
NazaraWarning("Resource destroyed while still referenced " + NzString::Number(m_referenceCount) + " time(s)");
#endif
}
void NzRefCounted::AddObjectListener(NzObjectListener* listener, int index) const
{
///DOC: Est ignoré si appelé depuis un évènement
NazaraLock(m_mutex)
if (!m_objectListenersLocked)
{
auto pair = m_objectListeners.insert(std::make_pair(listener, std::make_pair(index, 1U)));
if (!pair.second)
pair.first->second.second++;
}
}
void NzRefCounted::AddReference() const
{
m_referenceCount++;
}
unsigned int NzRefCounted::GetReferenceCount() const
{
return m_referenceCount;
}
bool NzRefCounted::IsPersistent() const
{
return m_persistent;
}
void NzRefCounted::RemoveObjectListener(NzObjectListener* listener) const
{
///DOC: Est ignoré si appelé depuis un évènement
NazaraLock(m_mutex);
if (!m_objectListenersLocked)
{
ObjectListenerMap::iterator it = m_objectListeners.find(listener);
if (it != m_objectListeners.end())
RemoveObjectListenerIterator(it);
}
}
bool NzRefCounted::RemoveReference() const
{
#if NAZARA_CORE_SAFE
if (m_referenceCount == 0)
{
NazaraError("Impossible to remove reference (Ref. counter is already 0)");
return false;
}
#endif
if (--m_referenceCount == 0 && !m_persistent)
{
delete this; // Suicide
return true;
}
else
return false;
}
bool NzRefCounted::SetPersistent(bool persistent, bool checkReferenceCount)
{
m_persistent = persistent;
if (checkReferenceCount && !persistent && m_referenceCount == 0)
{
delete this;
return true;
}
else
return false;
}
void NzRefCounted::NotifyCreated()
{
NazaraLock(m_mutex)
m_objectListenersLocked = true;
auto it = m_objectListeners.begin();
while (it != m_objectListeners.end())
{
if (!it->first->OnObjectCreated(this, it->second.first))
RemoveObjectListenerIterator(it++);
else
++it;
}
m_objectListenersLocked = false;
}
void NzRefCounted::NotifyDestroy()
{
NazaraLock(m_mutex)
m_objectListenersLocked = true;
auto it = m_objectListeners.begin();
while (it != m_objectListeners.end())
{
if (!it->first->OnObjectDestroy(this, it->second.first))
RemoveObjectListenerIterator(it++);
else
++it;
}
m_objectListenersLocked = false;
}
void NzRefCounted::NotifyModified(unsigned int code)
{
NazaraLock(m_mutex)
m_objectListenersLocked = true;
auto it = m_objectListeners.begin();
while (it != m_objectListeners.end())
{
if (!it->first->OnObjectModified(this, it->second.first, code))
RemoveObjectListenerIterator(it++);
else
++it;
}
m_objectListenersLocked = false;
}
void NzRefCounted::RemoveObjectListenerIterator(ObjectListenerMap::iterator iterator) const
{
unsigned int& referenceCount = iterator->second.second;
if (referenceCount == 1)
m_objectListeners.erase(iterator);
else
referenceCount--;
}

View File

@@ -3,174 +3,16 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Resource.hpp>
#include <Nazara/Core/Config.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/ResourceListener.hpp>
#include <Nazara/Utility/StaticMesh.hpp>
#include <Nazara/Utility/VertexDeclaration.hpp>
#include <typeinfo>
#if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_RESOURCE
#include <Nazara/Core/ThreadSafety.hpp>
#else
#include <Nazara/Core/ThreadSafetyOff.hpp>
#endif
#include <Nazara/Core/Debug.hpp>
NzResource::NzResource(bool persistent) :
m_resourcePersistent(persistent),
m_resourceReferenceCount(0),
m_resourceListenersLocked(false)
NzResource::~NzResource() = default;
NzString NzResource::GetFilePath() const
{
return m_filePath;
}
NzResource::~NzResource()
void NzResource::SetFilePath(const NzString& filePath)
{
m_resourceListenersLocked = true;
for (auto& pair : m_resourceListeners)
pair.first->OnResourceReleased(this, pair.second.first);
#if NAZARA_CORE_SAFE
if (m_resourceReferenceCount > 0)
NazaraWarning("Resource destroyed while still referenced " + NzString::Number(m_resourceReferenceCount) + " time(s)");
#endif
}
void NzResource::AddResourceListener(NzResourceListener* listener, int index) const
{
///DOC: Est ignoré si appelé depuis un évènement
NazaraLock(m_mutex)
if (!m_resourceListenersLocked)
{
auto pair = m_resourceListeners.insert(std::make_pair(listener, std::make_pair(index, 1U)));
if (!pair.second)
pair.first->second.second++;
}
}
void NzResource::AddResourceReference() const
{
m_resourceReferenceCount++;
}
unsigned int NzResource::GetResourceReferenceCount() const
{
return m_resourceReferenceCount;
}
bool NzResource::IsPersistent() const
{
return m_resourcePersistent;
}
void NzResource::RemoveResourceListener(NzResourceListener* listener) const
{
///DOC: Est ignoré si appelé depuis un évènement
NazaraLock(m_mutex);
if (!m_resourceListenersLocked)
{
ResourceListenerMap::iterator it = m_resourceListeners.find(listener);
if (it != m_resourceListeners.end())
RemoveResourceListenerIterator(it);
}
}
bool NzResource::RemoveResourceReference() const
{
#if NAZARA_CORE_SAFE
if (m_resourceReferenceCount == 0)
{
NazaraError("Impossible to remove reference (Ref. counter is already 0)");
return false;
}
#endif
if (--m_resourceReferenceCount == 0 && !m_resourcePersistent)
{
delete this; // Suicide
return true;
}
else
return false;
}
bool NzResource::SetPersistent(bool persistent, bool checkReferenceCount)
{
m_resourcePersistent = persistent;
if (checkReferenceCount && !persistent && m_resourceReferenceCount == 0)
{
delete this;
return true;
}
else
return false;
}
void NzResource::NotifyCreated()
{
NazaraLock(m_mutex)
m_resourceListenersLocked = true;
auto it = m_resourceListeners.begin();
while (it != m_resourceListeners.end())
{
if (!it->first->OnResourceCreated(this, it->second.first))
RemoveResourceListenerIterator(it++);
else
++it;
}
m_resourceListenersLocked = false;
}
void NzResource::NotifyDestroy()
{
NazaraLock(m_mutex)
m_resourceListenersLocked = true;
auto it = m_resourceListeners.begin();
while (it != m_resourceListeners.end())
{
if (!it->first->OnResourceDestroy(this, it->second.first))
RemoveResourceListenerIterator(it++);
else
++it;
}
m_resourceListenersLocked = false;
}
void NzResource::NotifyModified(unsigned int code)
{
NazaraLock(m_mutex)
m_resourceListenersLocked = true;
auto it = m_resourceListeners.begin();
while (it != m_resourceListeners.end())
{
if (!it->first->OnResourceModified(this, it->second.first, code))
RemoveResourceListenerIterator(it++);
else
++it;
}
m_resourceListenersLocked = false;
}
void NzResource::RemoveResourceListenerIterator(ResourceListenerMap::iterator iterator) const
{
unsigned int& referenceCount = iterator->second.second;
if (referenceCount == 1)
m_resourceListeners.erase(iterator);
else
referenceCount--;
m_filePath = filePath;
}

View File

@@ -1,39 +0,0 @@
// Copyright (C) 2014 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 <Nazara/Core/ResourceListener.hpp>
#include <Nazara/Core/Debug.hpp>
NzResourceListener::~NzResourceListener() = default;
bool NzResourceListener::OnResourceCreated(const NzResource* resource, int index)
{
NazaraUnused(resource);
NazaraUnused(index);
return true;
}
bool NzResourceListener::OnResourceDestroy(const NzResource* resource, int index)
{
NazaraUnused(resource);
NazaraUnused(index);
return true;
}
bool NzResourceListener::OnResourceModified(const NzResource* resource, int index, unsigned int code)
{
NazaraUnused(resource);
NazaraUnused(index);
NazaraUnused(code);
return true;
}
void NzResourceListener::OnResourceReleased(const NzResource* resource, int index)
{
NazaraUnused(resource);
NazaraUnused(index);
}

View File

@@ -13,11 +13,11 @@
namespace
{
enum ResourceType
enum ObjectType
{
ResourceType_IndexBuffer,
ResourceType_Material,
ResourceType_VertexBuffer
ObjectType_IndexBuffer,
ObjectType_Material,
ObjectType_VertexBuffer
};
}
@@ -74,7 +74,7 @@ void NzDeferredRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData
if (it == opaqueModels.end())
{
it = opaqueModels.insert(std::make_pair(material, ModelBatches::mapped_type())).first;
material->AddResourceListener(this, ResourceType_Material);
material->AddObjectListener(this, ObjectType_Material);
}
bool& used = std::get<0>(it->second);
@@ -89,9 +89,9 @@ void NzDeferredRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData
it2 = meshMap.insert(std::make_pair(meshData, MeshInstanceContainer::mapped_type())).first;
if (meshData.indexBuffer)
meshData.indexBuffer->AddResourceListener(this, ResourceType_IndexBuffer);
meshData.indexBuffer->AddObjectListener(this, ObjectType_IndexBuffer);
meshData.vertexBuffer->AddResourceListener(this, ResourceType_VertexBuffer);
meshData.vertexBuffer->AddObjectListener(this, ObjectType_VertexBuffer);
}
std::vector<NzMatrix4f>& instances = it2->second;
@@ -139,7 +139,7 @@ void NzDeferredRenderQueue::Clear(bool fully)
for (auto& matIt : opaqueModels)
{
const NzMaterial* material = matIt.first;
material->RemoveResourceListener(this);
material->RemoveObjectListener(this);
MeshInstanceContainer& instances = std::get<2>(matIt.second);
for (auto& instanceIt : instances)
@@ -147,9 +147,9 @@ void NzDeferredRenderQueue::Clear(bool fully)
const NzMeshData& renderData = instanceIt.first;
if (renderData.indexBuffer)
renderData.indexBuffer->RemoveResourceListener(this);
renderData.indexBuffer->RemoveObjectListener(this);
renderData.vertexBuffer->RemoveResourceListener(this);
renderData.vertexBuffer->RemoveObjectListener(this);
}
}
@@ -160,11 +160,11 @@ void NzDeferredRenderQueue::Clear(bool fully)
m_forwardQueue->Clear(fully);
}
bool NzDeferredRenderQueue::OnResourceDestroy(const NzResource* resource, int index)
bool NzDeferredRenderQueue::OnObjectDestroy(const NzRefCounted* object, int index)
{
switch (index)
{
case ResourceType_IndexBuffer:
case ObjectType_IndexBuffer:
{
for (auto& modelPair : opaqueModels)
{
@@ -172,7 +172,7 @@ bool NzDeferredRenderQueue::OnResourceDestroy(const NzResource* resource, int in
for (auto it = meshes.begin(); it != meshes.end();)
{
const NzMeshData& renderData = it->first;
if (renderData.indexBuffer == resource)
if (renderData.indexBuffer == object)
it = meshes.erase(it);
else
++it;
@@ -181,11 +181,11 @@ bool NzDeferredRenderQueue::OnResourceDestroy(const NzResource* resource, int in
break;
}
case ResourceType_Material:
opaqueModels.erase(static_cast<const NzMaterial*>(resource));
case ObjectType_Material:
opaqueModels.erase(static_cast<const NzMaterial*>(object));
break;
case ResourceType_VertexBuffer:
case ObjectType_VertexBuffer:
{
for (auto& modelPair : opaqueModels)
{
@@ -193,7 +193,7 @@ bool NzDeferredRenderQueue::OnResourceDestroy(const NzResource* resource, int in
for (auto it = meshes.begin(); it != meshes.end();)
{
const NzMeshData& renderData = it->first;
if (renderData.vertexBuffer == resource)
if (renderData.vertexBuffer == object)
it = meshes.erase(it);
else
++it;
@@ -206,14 +206,14 @@ bool NzDeferredRenderQueue::OnResourceDestroy(const NzResource* resource, int in
return false; // Nous ne voulons plus recevoir d'évènement de cette ressource
}
void NzDeferredRenderQueue::OnResourceReleased(const NzResource* resource, int index)
void NzDeferredRenderQueue::OnObjectReleased(const NzRefCounted* object, int index)
{
// La ressource vient d'être libérée, nous ne pouvons donc plus utiliser la méthode traditionnelle de recherche
// des pointeurs stockés (À cause de la fonction de triage utilisant des spécificités des ressources)
switch (index)
{
case ResourceType_IndexBuffer:
case ObjectType_IndexBuffer:
{
for (auto& modelPair : opaqueModels)
{
@@ -221,7 +221,7 @@ void NzDeferredRenderQueue::OnResourceReleased(const NzResource* resource, int i
for (auto it = meshes.begin(); it != meshes.end();)
{
const NzMeshData& renderData = it->first;
if (renderData.indexBuffer == resource)
if (renderData.indexBuffer == object)
it = meshes.erase(it);
else
++it;
@@ -230,11 +230,11 @@ void NzDeferredRenderQueue::OnResourceReleased(const NzResource* resource, int i
break;
}
case ResourceType_Material:
case ObjectType_Material:
{
for (auto it = opaqueModels.begin(); it != opaqueModels.end(); ++it)
{
if (it->first == resource)
if (it->first == object)
{
opaqueModels.erase(it);
break;
@@ -243,7 +243,7 @@ void NzDeferredRenderQueue::OnResourceReleased(const NzResource* resource, int i
break;
}
case ResourceType_VertexBuffer:
case ObjectType_VertexBuffer:
{
for (auto& modelPair : opaqueModels)
{
@@ -251,7 +251,7 @@ void NzDeferredRenderQueue::OnResourceReleased(const NzResource* resource, int i
for (auto it = meshes.begin(); it != meshes.end();)
{
const NzMeshData& renderData = it->first;
if (renderData.vertexBuffer == resource)
if (renderData.vertexBuffer == object)
it = meshes.erase(it);
else
++it;

View File

@@ -89,7 +89,7 @@ void NzForwardRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData&
if (it == opaqueModels.end())
{
it = opaqueModels.insert(std::make_pair(material, ModelBatches::mapped_type())).first;
material->AddResourceListener(this, ResourceType_Material);
material->AddObjectListener(this, ResourceType_Material);
}
bool& used = std::get<0>(it->second);
@@ -107,9 +107,9 @@ void NzForwardRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData&
squaredBoundingSphere.Set(meshAABB.GetSquaredBoundingSphere());
if (meshData.indexBuffer)
meshData.indexBuffer->AddResourceListener(this, ResourceType_IndexBuffer);
meshData.indexBuffer->AddObjectListener(this, ResourceType_IndexBuffer);
meshData.vertexBuffer->AddResourceListener(this, ResourceType_VertexBuffer);
meshData.vertexBuffer->AddObjectListener(this, ResourceType_VertexBuffer);
}
std::vector<NzMatrix4f>& instances = it2->second.second;
@@ -153,7 +153,7 @@ void NzForwardRenderQueue::Clear(bool fully)
for (auto& matIt : opaqueModels)
{
const NzMaterial* material = matIt.first;
material->RemoveResourceListener(this);
material->RemoveObjectListener(this);
MeshInstanceContainer& instances = std::get<2>(matIt.second);
for (auto& instanceIt : instances)
@@ -161,9 +161,9 @@ void NzForwardRenderQueue::Clear(bool fully)
const NzMeshData& renderData = instanceIt.first;
if (renderData.indexBuffer)
renderData.indexBuffer->RemoveResourceListener(this);
renderData.indexBuffer->RemoveObjectListener(this);
renderData.vertexBuffer->RemoveResourceListener(this);
renderData.vertexBuffer->RemoveObjectListener(this);
}
}
opaqueModels.clear();
@@ -188,7 +188,7 @@ void NzForwardRenderQueue::Sort(const NzAbstractViewer* viewer)
});
}
bool NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int index)
bool NzForwardRenderQueue::OnObjectDestroy(const NzRefCounted* object, int index)
{
switch (index)
{
@@ -200,7 +200,7 @@ bool NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int ind
for (auto it = meshes.begin(); it != meshes.end();)
{
const NzMeshData& renderData = it->first;
if (renderData.indexBuffer == resource)
if (renderData.indexBuffer == object)
it = meshes.erase(it);
else
++it;
@@ -210,7 +210,7 @@ bool NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int ind
}
case ResourceType_Material:
opaqueModels.erase(static_cast<const NzMaterial*>(resource));
opaqueModels.erase(static_cast<const NzMaterial*>(object));
break;
case ResourceType_VertexBuffer:
@@ -221,7 +221,7 @@ bool NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int ind
for (auto it = meshes.begin(); it != meshes.end();)
{
const NzMeshData& renderData = it->first;
if (renderData.vertexBuffer == resource)
if (renderData.vertexBuffer == object)
it = meshes.erase(it);
else
++it;
@@ -234,7 +234,7 @@ bool NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int ind
return false; // Nous ne voulons plus recevoir d'évènement de cette ressource
}
void NzForwardRenderQueue::OnResourceReleased(const NzResource* resource, int index)
void NzForwardRenderQueue::OnObjectReleased(const NzRefCounted* object, int index)
{
// La ressource vient d'être libérée, nous ne pouvons donc plus utiliser la méthode traditionnelle de recherche
// des pointeurs stockés (À cause de la fonction de triage utilisant des spécificités des ressources)
@@ -249,7 +249,7 @@ void NzForwardRenderQueue::OnResourceReleased(const NzResource* resource, int in
for (auto it = meshes.begin(); it != meshes.end();)
{
const NzMeshData& renderData = it->first;
if (renderData.indexBuffer == resource)
if (renderData.indexBuffer == object)
it = meshes.erase(it);
else
++it;
@@ -262,7 +262,7 @@ void NzForwardRenderQueue::OnResourceReleased(const NzResource* resource, int in
{
for (auto it = opaqueModels.begin(); it != opaqueModels.end(); ++it)
{
if (it->first == resource)
if (it->first == object)
{
opaqueModels.erase(it);
break;
@@ -279,7 +279,7 @@ void NzForwardRenderQueue::OnResourceReleased(const NzResource* resource, int in
for (auto it = meshes.begin(); it != meshes.end();)
{
const NzMeshData& renderData = it->first;
if (renderData.vertexBuffer == resource)
if (renderData.vertexBuffer == object)
it = meshes.erase(it);
else
++it;

View File

@@ -29,6 +29,7 @@ NzMaterial::NzMaterial()
}
NzMaterial::NzMaterial(const NzMaterial& material) :
NzRefCounted(),
NzResource()
{
Copy(material);

View File

@@ -4,7 +4,7 @@
#include <Nazara/Graphics/SkinningManager.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/Core/ResourceListener.hpp>
#include <Nazara/Core/ObjectListener.hpp>
#include <Nazara/Core/TaskScheduler.hpp>
#include <Nazara/Utility/Algorithm.hpp>
#include <Nazara/Utility/SkeletalMesh.hpp>
@@ -16,10 +16,10 @@
namespace
{
enum ResourceType
enum ObjectType
{
ResourceType_SkeletalMesh,
ResourceType_Skeleton,
ObjectType_SkeletalMesh,
ObjectType_Skeleton,
};
struct BufferData
@@ -40,38 +40,38 @@ namespace
SkeletonMap s_cache;
std::vector<SkinningData> s_skinningQueue;
class ResourceListener : public NzResourceListener
class ObjectListener : public NzObjectListener
{
public:
bool OnResourceDestroy(const NzResource* resource, int index)
bool OnObjectDestroy(const NzRefCounted* object, int index) override
{
switch (index)
{
case ResourceType_SkeletalMesh:
case ObjectType_SkeletalMesh:
{
for (auto& pair : s_cache)
{
MeshMap& meshMap = pair.second;
meshMap.erase(static_cast<const NzSkeletalMesh*>(resource));
meshMap.erase(static_cast<const NzSkeletalMesh*>(object));
}
break;
}
case ResourceType_Skeleton:
s_cache.erase(static_cast<const NzSkeleton*>(resource));
case ObjectType_Skeleton:
s_cache.erase(static_cast<const NzSkeleton*>(object));
break;
}
return false;
}
bool OnResourceModified(const NzResource* resource, int index, unsigned int code)
bool OnObjectModified(const NzRefCounted* object, int index, unsigned int code) override
{
NazaraUnused(code);
switch (index)
{
case ResourceType_SkeletalMesh:
case ObjectType_SkeletalMesh:
{
for (auto& pair : s_cache)
{
@@ -82,9 +82,9 @@ namespace
break;
}
case ResourceType_Skeleton:
case ObjectType_Skeleton:
{
for (auto& pair : s_cache.at(static_cast<const NzSkeleton*>(resource)))
for (auto& pair : s_cache.at(static_cast<const NzSkeleton*>(object)))
pair.second.updated = false;
break;
}
@@ -93,13 +93,13 @@ namespace
return true;
}
void OnResourceReleased(const NzResource* resource, int index)
void OnObjectReleased(const NzRefCounted* resource, int index) override
{
OnResourceDestroy(resource, index);
OnObjectDestroy(resource, index);
}
};
ResourceListener listener;
ObjectListener listener;
void Skin_MonoCPU(const NzSkeletalMesh* mesh, const NzSkeleton* skeleton, NzVertexBuffer* buffer)
{
@@ -163,7 +163,7 @@ NzVertexBuffer* NzSkinningManager::GetBuffer(const NzSkeletalMesh* mesh, const N
if (it == s_cache.end())
{
it = s_cache.insert(std::make_pair(skeleton, SkeletonMap::mapped_type())).first;
skeleton->AddResourceListener(&listener, ResourceType_Skeleton);
skeleton->AddObjectListener(&listener, ObjectType_Skeleton);
}
NzVertexBuffer* buffer;
@@ -179,7 +179,7 @@ NzVertexBuffer* NzSkinningManager::GetBuffer(const NzSkeletalMesh* mesh, const N
BufferData data({vertexBuffer.get(), true});
meshMap.insert(std::make_pair(mesh, data));
mesh->AddResourceListener(&listener, ResourceType_SkeletalMesh);
mesh->AddObjectListener(&listener, ObjectType_SkeletalMesh);
s_skinningQueue.push_back(SkinningData{mesh, skeleton, vertexBuffer.get()});
@@ -223,10 +223,10 @@ void NzSkinningManager::Uninitialize()
{
for (auto& pair : s_cache)
{
pair.first->RemoveResourceListener(&listener);
pair.first->RemoveObjectListener(&listener);
MeshMap& meshMap = pair.second;
for (auto& pair2 : meshMap)
pair2.first->RemoveResourceListener(&listener);
pair2.first->RemoveObjectListener(&listener);
}
s_cache.clear();
s_skinningQueue.clear();

View File

@@ -150,7 +150,7 @@ bool NzRenderTexture::AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 in
attachment.height = buffer->GetHeight();
attachment.width = buffer->GetWidth();
buffer->AddResourceListener(this, attachIndex);
buffer->AddObjectListener(this, attachIndex);
m_impl->checked = false;
@@ -294,7 +294,7 @@ bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 i
attachment.texture = texture;
attachment.width = texture->GetWidth();
texture->AddResourceListener(this, attachIndex);
texture->AddObjectListener(this, attachIndex);
m_impl->checked = false;
@@ -339,7 +339,7 @@ bool NzRenderTexture::Create(bool lock)
m_impl = impl.release();
m_impl->context = NzContext::GetCurrent();
m_impl->context->AddResourceListener(this);
m_impl->context->AddObjectListener(this);
if (lock)
{
@@ -371,16 +371,16 @@ void NzRenderTexture::Destroy()
if (IsActive())
NzRenderer::SetTarget(nullptr);
m_impl->context->RemoveResourceListener(this);
m_impl->context->RemoveObjectListener(this);
for (const Attachment& attachment : m_impl->attachments)
{
if (attachment.isUsed)
{
if (attachment.isBuffer)
attachment.buffer->RemoveResourceListener(this);
attachment.buffer->RemoveObjectListener(this);
else
attachment.texture->RemoveResourceListener(this);
attachment.texture->RemoveObjectListener(this);
}
}
@@ -429,7 +429,7 @@ void NzRenderTexture::Detach(nzAttachmentPoint attachmentPoint, nzUInt8 index)
{
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, GL_RENDERBUFFER, 0);
attachement.buffer->RemoveResourceListener(this);
attachement.buffer->RemoveObjectListener(this);
attachement.buffer = nullptr;
}
else
@@ -439,7 +439,7 @@ void NzRenderTexture::Detach(nzAttachmentPoint attachmentPoint, nzUInt8 index)
else
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, 0, 0, 0);
attachement.texture->RemoveResourceListener(this);
attachement.texture->RemoveObjectListener(this);
attachement.texture = nullptr;
}
@@ -877,10 +877,10 @@ void NzRenderTexture::EnsureTargetUpdated() const
}
}
bool NzRenderTexture::OnResourceDestroy(const NzResource* resource, int index)
bool NzRenderTexture::OnObjectDestroy(const NzRefCounted* object, int index)
{
if (resource == m_impl->context)
// Notre contexte va être détruit, libérons la RenderTexture pour éviter un leak
if (object == m_impl->context)
// Notre contexte va être détruit, libérons la RenderTexture pour éviter un éventuel leak
Destroy();
else // Sinon, c'est une texture
{

View File

@@ -8,6 +8,7 @@
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/Core/Log.hpp>
#include <Nazara/Core/ObjectListener.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <Nazara/Renderer/DebugDrawer.hpp>
@@ -34,12 +35,12 @@
namespace
{
enum ResourceType
enum ObjectType
{
ResourceType_Context,
ResourceType_IndexBuffer,
ResourceType_VertexBuffer,
ResourceType_VertexDeclaration
ObjectType_Context,
ObjectType_IndexBuffer,
ObjectType_VertexBuffer,
ObjectType_VertexDeclaration
};
enum UpdateFlags
@@ -95,23 +96,23 @@ namespace
unsigned int s_maxTextureUnit;
unsigned int s_maxVertexAttribs;
class ResourceListener : public NzResourceListener
class ObjectListener : public NzObjectListener
{
public:
void OnResourceReleased(const NzResource* resource, int index) override
void OnObjectReleased(const NzRefCounted* object, int index) override
{
switch (index)
{
case ResourceType_Context:
case ObjectType_Context:
{
const NzContext* context = static_cast<const NzContext*>(resource);
const NzContext* context = static_cast<const NzContext*>(object);
s_vaos.erase(context);
break;
}
case ResourceType_IndexBuffer:
case ObjectType_IndexBuffer:
{
const NzIndexBuffer* indexBuffer = static_cast<const NzIndexBuffer*>(resource);
const NzIndexBuffer* indexBuffer = static_cast<const NzIndexBuffer*>(object);
for (auto& pair : s_vaos)
{
const NzContext* context = pair.first;
@@ -140,9 +141,9 @@ namespace
break;
}
case ResourceType_VertexBuffer:
case ObjectType_VertexBuffer:
{
const NzVertexBuffer* vertexBuffer = static_cast<const NzVertexBuffer*>(resource);
const NzVertexBuffer* vertexBuffer = static_cast<const NzVertexBuffer*>(object);
for (auto& pair : s_vaos)
{
const NzContext* context = pair.first;
@@ -171,9 +172,9 @@ namespace
break;
}
case ResourceType_VertexDeclaration:
case ObjectType_VertexDeclaration:
{
const NzVertexDeclaration* vertexDeclaration = static_cast<const NzVertexDeclaration*>(resource);
const NzVertexDeclaration* vertexDeclaration = static_cast<const NzVertexDeclaration*>(object);
for (auto& pair : s_vaos)
{
const NzContext* context = pair.first;
@@ -210,7 +211,7 @@ namespace
}
};
ResourceListener s_listener;
ObjectListener s_listener;
}
void NzRenderer::BeginCondition(const NzGpuQuery& query, nzGpuQueryCondition condition)
@@ -1530,13 +1531,13 @@ void NzRenderer::Uninitialize()
const NzVertexDeclaration* instancingDeclaration = std::get<3>(key);
if (indexBuffer)
indexBuffer->RemoveResourceListener(&s_listener);
indexBuffer->RemoveObjectListener(&s_listener);
vertexBuffer->RemoveResourceListener(&s_listener);
vertexDeclaration->RemoveResourceListener(&s_listener);
vertexBuffer->RemoveObjectListener(&s_listener);
vertexDeclaration->RemoveObjectListener(&s_listener);
if (instancingDeclaration)
instancingDeclaration->RemoveResourceListener(&s_listener);
instancingDeclaration->RemoveObjectListener(&s_listener);
NzOpenGL::DeleteVertexArray(context, pair2.second);
}
@@ -1710,7 +1711,7 @@ bool NzRenderer::EnsureStateUpdate()
auto it = s_vaos.find(context);
if (it == s_vaos.end())
{
context->AddResourceListener(&s_listener, ResourceType_Context);
context->AddObjectListener(&s_listener, ObjectType_Context);
auto pair = s_vaos.insert(std::make_pair(context, Context_Map::mapped_type()));
vaos = &pair.first->second;
}
@@ -1733,13 +1734,13 @@ bool NzRenderer::EnsureStateUpdate()
// On l'ajoute à notre liste
vaoIt = vaos->insert(std::make_pair(key, s_currentVAO)).first;
if (s_indexBuffer)
s_indexBuffer->AddResourceListener(&s_listener, ResourceType_IndexBuffer);
s_indexBuffer->AddObjectListener(&s_listener, ObjectType_IndexBuffer);
s_vertexBuffer->AddResourceListener(&s_listener, ResourceType_VertexBuffer);
vertexDeclaration->AddResourceListener(&s_listener, ResourceType_VertexDeclaration);
s_vertexBuffer->AddObjectListener(&s_listener, ObjectType_VertexBuffer);
vertexDeclaration->AddObjectListener(&s_listener, ObjectType_VertexDeclaration);
if (instancingDeclaration)
instancingDeclaration->AddResourceListener(&s_listener, ResourceType_VertexDeclaration);
instancingDeclaration->AddObjectListener(&s_listener, ObjectType_VertexDeclaration);
// Et on indique qu'on veut le programmer
update = true;

View File

@@ -51,6 +51,7 @@ m_sharedImage(&emptyImage)
}
NzImage::NzImage(const NzImage& image) :
NzRefCounted(),
NzResource(),
m_sharedImage(image.m_sharedImage)
{

View File

@@ -22,7 +22,7 @@ NzIndexBuffer::NzIndexBuffer(bool largeIndices, unsigned int length, nzBufferSto
}
NzIndexBuffer::NzIndexBuffer(const NzIndexBuffer& indexBuffer) :
NzResource(),
NzRefCounted(),
m_buffer(indexBuffer.m_buffer),
m_largeIndices(indexBuffer.m_largeIndices),
m_endOffset(indexBuffer.m_endOffset),
@@ -32,7 +32,7 @@ m_startOffset(indexBuffer.m_startOffset)
}
NzIndexBuffer::NzIndexBuffer(NzIndexBuffer&& indexBuffer) noexcept :
NzResource(),
NzRefCounted(),
m_buffer(std::move(indexBuffer.m_buffer)),
m_largeIndices(indexBuffer.m_largeIndices),
m_endOffset(indexBuffer.m_endOffset),

View File

@@ -91,8 +91,8 @@ void NzMesh::AddSubMesh(NzSubMesh* subMesh)
}
#endif
subMesh->AddResourceListener(this, m_impl->subMeshes.size());
subMesh->AddResourceReference();
subMesh->AddObjectListener(this, m_impl->subMeshes.size());
subMesh->AddReference();
m_impl->aabbUpdated = false; // On invalide l'AABB
m_impl->subMeshes.push_back(subMesh);
@@ -135,8 +135,8 @@ void NzMesh::AddSubMesh(const NzString& identifier, NzSubMesh* subMesh)
int index = m_impl->subMeshes.size();
subMesh->AddResourceListener(this, index);
subMesh->AddResourceReference();
subMesh->AddObjectListener(this, index);
subMesh->AddReference();
m_impl->aabbUpdated = false; // On invalide l'AABB
m_impl->subMeshes.push_back(subMesh);
@@ -373,8 +373,8 @@ void NzMesh::Destroy()
for (NzSubMesh* subMesh : m_impl->subMeshes)
{
subMesh->RemoveResourceListener(this);
subMesh->RemoveResourceReference();
subMesh->RemoveObjectListener(this);
subMesh->RemoveReference();
}
delete m_impl;
@@ -866,8 +866,8 @@ void NzMesh::RemoveSubMesh(const NzString& identifier)
// On libère la ressource
NzSubMesh* subMesh = *it2;
subMesh->RemoveResourceListener(this);
subMesh->RemoveResourceReference();
subMesh->RemoveObjectListener(this);
subMesh->RemoveReference();
m_impl->subMeshes.erase(it2);
@@ -896,8 +896,8 @@ void NzMesh::RemoveSubMesh(unsigned int index)
// On libère la ressource
NzSubMesh* subMesh = *it;
subMesh->RemoveResourceListener(this);
subMesh->RemoveResourceReference();
subMesh->RemoveObjectListener(this);
subMesh->RemoveReference();
m_impl->subMeshes.erase(it);
@@ -1011,9 +1011,9 @@ void NzMesh::Transform(const NzMatrix4f& matrix)
m_impl->aabbUpdated = false;
}
void NzMesh::OnResourceReleased(const NzResource* resource, int index)
void NzMesh::OnObjectReleased(const NzRefCounted* object, int index)
{
NazaraUnused(resource);
NazaraUnused(object);
RemoveSubMesh(index);
}

View File

@@ -16,7 +16,7 @@ struct NzSkeletonImpl
};
NzSkeleton::NzSkeleton(const NzSkeleton& skeleton) :
NzResource(),
NzRefCounted(),
m_impl(nullptr)
{
operator=(skeleton);

View File

@@ -13,7 +13,7 @@
#include <Nazara/Utility/Debug.hpp>
NzSubMesh::NzSubMesh(const NzMesh* parent) :
NzResource(false), // Un SubMesh n'est pas persistant par défaut
NzRefCounted(false), // Un SubMesh n'est pas persistant par défaut
m_primitiveMode(nzPrimitiveMode_TriangleList),
m_parent(parent),
m_matIndex(0)

View File

@@ -18,7 +18,7 @@ NzVertexBuffer::NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, uns
}
NzVertexBuffer::NzVertexBuffer(const NzVertexBuffer& vertexBuffer) :
NzResource(),
NzRefCounted(),
m_buffer(vertexBuffer.m_buffer),
m_vertexDeclaration(vertexBuffer.m_vertexDeclaration),
m_endOffset(vertexBuffer.m_endOffset),

View File

@@ -19,7 +19,7 @@ m_stride(0)
}
NzVertexDeclaration::NzVertexDeclaration(const NzVertexDeclaration& declaration) :
NzResource(),
NzRefCounted(),
m_stride(declaration.m_stride)
{
std::memcpy(m_components, declaration.m_components, sizeof(Component)*(nzVertexComponent_Max+1));