From 6c2fb1eb898456debe34b9bc8010db932db49aa0 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 15 Mar 2013 03:09:58 +0100 Subject: [PATCH] Added ResourceRef (Automatic resource reference) Former-commit-id: 97a0b2732f4dc443b8e1676e68b33b1b53ddf4fb --- include/Nazara/3D/Model.hpp | 6 +- include/Nazara/Audio/Sound.hpp | 2 +- include/Nazara/Audio/SoundBuffer.hpp | 3 + include/Nazara/Core/Resource.hpp | 4 +- include/Nazara/Core/ResourceRef.hpp | 44 ++++ include/Nazara/Core/ResourceRef.inl | 125 ++++++++++ include/Nazara/Renderer/Context.hpp | 6 + include/Nazara/Renderer/Material.hpp | 20 +- include/Nazara/Renderer/Shader.hpp | 8 +- include/Nazara/Renderer/Texture.hpp | 7 + include/Nazara/Utility/Animation.hpp | 3 + include/Nazara/Utility/Buffer.hpp | 6 + include/Nazara/Utility/Image.hpp | 3 + include/Nazara/Utility/IndexBuffer.hpp | 8 +- include/Nazara/Utility/Mesh.hpp | 3 + include/Nazara/Utility/SkeletalMesh.hpp | 5 + include/Nazara/Utility/StaticMesh.hpp | 5 + include/Nazara/Utility/SubMesh.hpp | 5 + include/Nazara/Utility/VertexBuffer.hpp | 10 +- include/Nazara/Utility/VertexDeclaration.hpp | 6 + src/Nazara/3D/Model.cpp | 56 ++--- src/Nazara/Audio/Sound.cpp | 9 - src/Nazara/Core/Resource.cpp | 16 +- src/Nazara/Renderer/Material.cpp | 233 ++++--------------- src/Nazara/Renderer/ShaderBuilder.cpp | 7 +- src/Nazara/Utility/IndexBuffer.cpp | 13 +- src/Nazara/Utility/SkeletalMesh.cpp | 8 +- src/Nazara/Utility/VertexBuffer.cpp | 17 +- src/Nazara/Utility/VertexMapper.cpp | 5 +- 29 files changed, 344 insertions(+), 299 deletions(-) create mode 100644 include/Nazara/Core/ResourceRef.hpp create mode 100644 include/Nazara/Core/ResourceRef.inl diff --git a/include/Nazara/3D/Model.hpp b/include/Nazara/3D/Model.hpp index 8f6b9aeae..1eb9d96b3 100644 --- a/include/Nazara/3D/Model.hpp +++ b/include/Nazara/3D/Model.hpp @@ -78,11 +78,11 @@ class NAZARA_API NzModel : public NzSceneNode, public NzUpdatable void UpdateBoundingBox() const; bool VisibilityTest(const NzFrustumf& frustum) override; - std::vector m_materials; + std::vector m_materials; mutable NzBoundingBoxf m_boundingBox; NzSkeleton m_skeleton; // Uniquement pour les animations squelettiques - NzAnimation* m_animation; - NzMesh* m_mesh; + NzAnimationRef m_animation; + NzMeshRef m_mesh; const NzSequence* m_currentSequence; bool m_animationEnabled; mutable bool m_boundingBoxUpdated; diff --git a/include/Nazara/Audio/Sound.hpp b/include/Nazara/Audio/Sound.hpp index d4883e35d..11cb1c966 100644 --- a/include/Nazara/Audio/Sound.hpp +++ b/include/Nazara/Audio/Sound.hpp @@ -42,7 +42,7 @@ class NAZARA_API NzSound : public NzSoundEmitter void Stop(); private: - const NzSoundBuffer* m_buffer = nullptr; + NzSoundBufferConstRef m_buffer; }; #endif // NAZARA_SOUND_HPP diff --git a/include/Nazara/Audio/SoundBuffer.hpp b/include/Nazara/Audio/SoundBuffer.hpp index 1cf50ea90..7b8b30575 100644 --- a/include/Nazara/Audio/SoundBuffer.hpp +++ b/include/Nazara/Audio/SoundBuffer.hpp @@ -13,6 +13,7 @@ #include #include #include +#include struct NzSoundBufferParams { @@ -22,7 +23,9 @@ struct NzSoundBufferParams class NzSound; class NzSoundBuffer; +using NzSoundBufferConstRef = NzResourceRef; using NzSoundBufferLoader = NzResourceLoader; +using NzSoundBufferRef = NzResourceRef; struct NzSoundBufferImpl; diff --git a/include/Nazara/Core/Resource.hpp b/include/Nazara/Core/Resource.hpp index 6e86b653b..d29ce38cb 100644 --- a/include/Nazara/Core/Resource.hpp +++ b/include/Nazara/Core/Resource.hpp @@ -49,8 +49,8 @@ class NAZARA_API NzResource bool IsPersistent() const; - void RemoveResourceListener(NzResourceListener* listener) const; - void RemoveResourceReference() const; + bool RemoveResourceListener(NzResourceListener* listener) const; + bool RemoveResourceReference() const; void SetPersistent(bool persistent = true, bool checkReferenceCount = true); diff --git a/include/Nazara/Core/ResourceRef.hpp b/include/Nazara/Core/ResourceRef.hpp new file mode 100644 index 000000000..0c6b39cec --- /dev/null +++ b/include/Nazara/Core/ResourceRef.hpp @@ -0,0 +1,44 @@ +// Copyright (C) 2013 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 + +#pragma once + +#ifndef NAZARA_RESOURCEREF_HPP +#define NAZARA_RESOURCEREF_HPP + +#include +#include +#include + +template +class NzResourceRef +{ + static_assert(std::is_base_of::value, "ResourceRef should only be used with resource type"); + + public: + NzResourceRef() = default; + NzResourceRef(T* resource); + NzResourceRef(const NzResourceRef& ref); + NzResourceRef(NzResourceRef&& ref); + ~NzResourceRef(); + + bool IsValid() const; + T* Release(); + bool Reset(T* resource = nullptr); + NzResourceRef& Swap(NzResourceRef& ref); + + operator bool() const; + operator T*() const; + T* operator->() const; + + NzResourceRef& operator=(const NzResourceRef& ref); + NzResourceRef& operator=(NzResourceRef&& ref); + + private: + T* m_resource = nullptr; +}; + +#include + +#endif // NAZARA_RESOURCEREF_HPP diff --git a/include/Nazara/Core/ResourceRef.inl b/include/Nazara/Core/ResourceRef.inl new file mode 100644 index 000000000..df077fb7a --- /dev/null +++ b/include/Nazara/Core/ResourceRef.inl @@ -0,0 +1,125 @@ +// Copyright (C) 2013 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 + +// http://www.easyrgb.com/index.php?X=MATH + +#include +#include + +template +NzResourceRef::NzResourceRef(T* resource) : +m_resource(resource) +{ + if (m_resource) + m_resource->AddResourceReference(); +} + +template +NzResourceRef::NzResourceRef(const NzResourceRef& ref) : +m_resource(ref.m_resource) +{ + if (m_resource) + m_resource->AddResourceReference(); +} + +template +NzResourceRef::NzResourceRef(NzResourceRef&& ref) : +m_resource(ref.m_resource) +{ + ref.m_resource = nullptr; // On vole la référence +} + +template +NzResourceRef::~NzResourceRef() +{ + if (m_resource) + m_resource->RemoveResourceReference(); +} + +template +bool NzResourceRef::IsValid() const +{ + return m_resource != nullptr; +} + +template +T* NzResourceRef::Release() +{ + T* resource = m_resource; + m_resource = nullptr; + + return resource; +} + +template +bool NzResourceRef::Reset(T* resource) +{ + bool destroyed = false; + if (m_resource) + { + destroyed = m_resource->RemoveResourceReference(); + m_resource = nullptr; + } + + m_resource = resource; + if (m_resource) + m_resource->AddResourceReference(); + + return destroyed; +} + +template +NzResourceRef& NzResourceRef::Swap(NzResourceRef& ref) +{ + std::swap(m_resource, ref.m_resource); + + return *this; +} + +template +NzResourceRef::operator bool() const +{ + return IsValid(); +} + +template +NzResourceRef::operator T*() const +{ + return m_resource; +} + +template +T* NzResourceRef::operator->() const +{ + return m_resource; +} + +template +NzResourceRef& NzResourceRef::operator=(const NzResourceRef& ref) +{ + if (m_resource != ref.m_resource) + { + Release(); + + if (ref) + { + m_resource = ref.m_resource; + m_resource->AddResourceReference(); + } + } + + return *this; +} + +template +NzResourceRef& NzResourceRef::operator=(NzResourceRef&& ref) +{ + Release(); + + std::swap(m_resource, ref.m_resource); + + return *this; +} + +#include diff --git a/include/Nazara/Renderer/Context.hpp b/include/Nazara/Renderer/Context.hpp index b54a3afc7..aee424a35 100644 --- a/include/Nazara/Renderer/Context.hpp +++ b/include/Nazara/Renderer/Context.hpp @@ -9,8 +9,14 @@ #include #include +#include #include +class NzContext; + +using NzContextConstRef = NzResourceRef; +using NzContextRef = NzResourceRef; + class NzContextImpl; class NAZARA_API NzContext : public NzResource diff --git a/include/Nazara/Renderer/Material.hpp b/include/Nazara/Renderer/Material.hpp index f9099698e..93e81f406 100644 --- a/include/Nazara/Renderer/Material.hpp +++ b/include/Nazara/Renderer/Material.hpp @@ -9,8 +9,11 @@ #include #include +#include #include +#include #include +#include #include #include @@ -23,9 +26,10 @@ struct NAZARA_API NzMaterialParams }; class NzMaterial; -class NzShader; +using NzMaterialConstRef = NzResourceRef; using NzMaterialLoader = NzResourceLoader; +using NzMaterialRef = NzResourceRef; class NAZARA_API NzMaterial : public NzResource { @@ -35,7 +39,7 @@ class NAZARA_API NzMaterial : public NzResource NzMaterial(); NzMaterial(const NzMaterial& material); NzMaterial(NzMaterial&& material); - ~NzMaterial(); + ~NzMaterial() = default; void Apply(const NzShader* shader) const; @@ -102,6 +106,8 @@ class NAZARA_API NzMaterial : public NzResource static NzMaterial* GetDefault(); private: + void Copy(const NzMaterial& material); + nzBlendFunc m_dstBlend; nzBlendFunc m_srcBlend; nzFaceCulling m_faceCulling; @@ -113,11 +119,11 @@ class NAZARA_API NzMaterial : public NzResource NzColor m_specularColor; NzTextureSampler m_diffuseSampler; NzTextureSampler m_specularSampler; - mutable const NzShader* m_customShader; - NzTexture* m_diffuseMap; - NzTexture* m_heightMap; - NzTexture* m_normalMap; - NzTexture* m_specularMap; + mutable NzShaderConstRef m_customShader; + NzTextureRef m_diffuseMap; + NzTextureRef m_heightMap; + NzTextureRef m_normalMap; + NzTextureRef m_specularMap; bool m_alphaBlendingEnabled; bool m_faceCullingEnabled; bool m_lightingEnabled; diff --git a/include/Nazara/Renderer/Shader.hpp b/include/Nazara/Renderer/Shader.hpp index 0e18c5bb7..9027b47ce 100644 --- a/include/Nazara/Renderer/Shader.hpp +++ b/include/Nazara/Renderer/Shader.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -18,9 +19,14 @@ #include #include -class NzShaderImpl; +class NzShader; class NzTexture; +using NzShaderConstRef = NzResourceRef; +using NzShaderRef = NzResourceRef; + +class NzShaderImpl; + class NAZARA_API NzShader : public NzResource, NzNonCopyable { friend class NzRenderer; diff --git a/include/Nazara/Renderer/Texture.hpp b/include/Nazara/Renderer/Texture.hpp index 993e5d704..56ba4e459 100644 --- a/include/Nazara/Renderer/Texture.hpp +++ b/include/Nazara/Renderer/Texture.hpp @@ -9,11 +9,18 @@ #include #include +#include +#include #include #include #include class NzRenderTexture; +class NzTexture; + +using NzTextureConstRef = NzResourceRef; +using NzTextureRef = NzResourceRef; + struct NzTextureImpl; class NAZARA_API NzTexture : public NzResource, NzNonCopyable diff --git a/include/Nazara/Utility/Animation.hpp b/include/Nazara/Utility/Animation.hpp index 5cbec097f..6daf03985 100644 --- a/include/Nazara/Utility/Animation.hpp +++ b/include/Nazara/Utility/Animation.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -27,7 +28,9 @@ struct NAZARA_API NzAnimationParams class NzAnimation; class NzSkeleton; +using NzAnimationConstRef = NzResourceRef; using NzAnimationLoader = NzResourceLoader; +using NzAnimationRef = NzResourceRef; struct NzAnimationImpl; diff --git a/include/Nazara/Utility/Buffer.hpp b/include/Nazara/Utility/Buffer.hpp index 9394e9b9c..32746b51f 100644 --- a/include/Nazara/Utility/Buffer.hpp +++ b/include/Nazara/Utility/Buffer.hpp @@ -10,8 +10,14 @@ #include #include #include +#include #include +class NzBuffer; + +using NzBufferConstRef = NzResourceRef; +using NzBufferRef = NzResourceRef; + class NzBufferImpl; class NAZARA_API NzBuffer : public NzResource, NzNonCopyable diff --git a/include/Nazara/Utility/Image.hpp b/include/Nazara/Utility/Image.hpp index 5390a36db..629ad1b33 100644 --- a/include/Nazara/Utility/Image.hpp +++ b/include/Nazara/Utility/Image.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -39,7 +40,9 @@ struct NAZARA_API NzImageParams class NzImage; +using NzImageConstRef = NzResourceRef; using NzImageLoader = NzResourceLoader; +using NzImageRef = NzResourceRef; class NAZARA_API NzImage : public NzResource { diff --git a/include/Nazara/Utility/IndexBuffer.hpp b/include/Nazara/Utility/IndexBuffer.hpp index ff99aa3e9..55b637ea5 100644 --- a/include/Nazara/Utility/IndexBuffer.hpp +++ b/include/Nazara/Utility/IndexBuffer.hpp @@ -9,8 +9,14 @@ #include #include +#include #include +class NzIndexBuffer; + +using NzIndexBufferConstRef = NzResourceRef; +using NzIndexBufferRef = NzResourceRef; + class NAZARA_API NzIndexBuffer : public NzResource { public: @@ -40,7 +46,7 @@ class NAZARA_API NzIndexBuffer : public NzResource void Unmap() const; private: - NzBuffer* m_buffer; + NzBufferRef m_buffer; bool m_ownsBuffer; unsigned int m_indexCount; unsigned int m_startIndex; diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index 826a6b2ab..78d94f709 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -36,7 +37,9 @@ class NzMesh; typedef NzVertexStruct_XYZ_Normal_UV_Tangent NzMeshVertex; +using NzMeshConstRef = NzResourceRef; using NzMeshLoader = NzResourceLoader; +using NzMeshRef = NzResourceRef; struct NzMeshImpl; diff --git a/include/Nazara/Utility/SkeletalMesh.hpp b/include/Nazara/Utility/SkeletalMesh.hpp index fc9bf9bd9..cfc4f1a91 100644 --- a/include/Nazara/Utility/SkeletalMesh.hpp +++ b/include/Nazara/Utility/SkeletalMesh.hpp @@ -24,6 +24,11 @@ struct NzWeight unsigned int jointIndex; }; +class NzSkeletalMesh; + +using NzSkeletalMeshConstRef = NzResourceRef; +using NzSkeletalMeshRef = NzResourceRef; + struct NzSkeletalMeshImpl; class NAZARA_API NzSkeletalMesh final : public NzSubMesh diff --git a/include/Nazara/Utility/StaticMesh.hpp b/include/Nazara/Utility/StaticMesh.hpp index deb885bc0..8e75eacf6 100644 --- a/include/Nazara/Utility/StaticMesh.hpp +++ b/include/Nazara/Utility/StaticMesh.hpp @@ -11,6 +11,11 @@ #include #include +class NzStaticMesh; + +using NzStaticMeshConstRef = NzResourceRef; +using NzStaticMeshRef = NzResourceRef; + class NAZARA_API NzStaticMesh final : public NzSubMesh, NzResourceListener { public: diff --git a/include/Nazara/Utility/SubMesh.hpp b/include/Nazara/Utility/SubMesh.hpp index d2870971a..a7a530ba3 100644 --- a/include/Nazara/Utility/SubMesh.hpp +++ b/include/Nazara/Utility/SubMesh.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -16,6 +17,10 @@ #include class NzMesh; +class NzSubMesh; + +using NzSubMeshConstRef = NzResourceRef; +using NzSubMeshRef = NzResourceRef; class NAZARA_API NzSubMesh : public NzResource { diff --git a/include/Nazara/Utility/VertexBuffer.hpp b/include/Nazara/Utility/VertexBuffer.hpp index 23ea27e60..083ecf7cb 100644 --- a/include/Nazara/Utility/VertexBuffer.hpp +++ b/include/Nazara/Utility/VertexBuffer.hpp @@ -9,9 +9,15 @@ #include #include +#include #include #include +class NzVertexBuffer; + +using NzVertexBufferConstRef = NzResourceRef; +using NzVertexBufferRef = NzResourceRef; + class NAZARA_API NzVertexBuffer : public NzResource { public: @@ -40,8 +46,8 @@ class NAZARA_API NzVertexBuffer : public NzResource void Unmap() const; private: - NzBuffer* m_buffer; - const NzVertexDeclaration* m_vertexDeclaration; + NzBufferRef m_buffer; + NzVertexDeclarationConstRef m_vertexDeclaration; bool m_ownsBuffer; unsigned int m_startVertex; unsigned int m_vertexCount; diff --git a/include/Nazara/Utility/VertexDeclaration.hpp b/include/Nazara/Utility/VertexDeclaration.hpp index 612444f6b..d14023439 100644 --- a/include/Nazara/Utility/VertexDeclaration.hpp +++ b/include/Nazara/Utility/VertexDeclaration.hpp @@ -9,6 +9,7 @@ #include #include +#include #include struct NzVertexElement @@ -20,6 +21,11 @@ struct NzVertexElement nzElementUsage usage; }; +class NzVertexDeclaration; + +using NzVertexDeclarationConstRef = NzResourceRef; +using NzVertexDeclarationRef = NzResourceRef; + struct NzVertexDeclarationImpl; class NAZARA_API NzVertexDeclaration : public NzResource diff --git a/src/Nazara/3D/Model.cpp b/src/Nazara/3D/Model.cpp index 2d5c194b5..8f463db63 100644 --- a/src/Nazara/3D/Model.cpp +++ b/src/Nazara/3D/Model.cpp @@ -11,8 +11,6 @@ #include NzModel::NzModel() : -m_animation(nullptr), -m_mesh(nullptr), m_currentSequence(nullptr), m_animationEnabled(true), m_boundingBoxUpdated(false), @@ -27,8 +25,6 @@ NzModel::NzModel(const NzModel& model) : NzSceneNode(model), m_materials(model.m_materials), m_boundingBox(model.m_boundingBox), -m_animation(model.m_animation), -m_mesh(model.m_mesh), m_currentSequence(model.m_currentSequence), m_animationEnabled(model.m_animationEnabled), m_boundingBoxUpdated(model.m_boundingBoxUpdated), @@ -40,19 +36,15 @@ m_nextFrame(model.m_nextFrame), m_skin(model.m_skin), m_skinCount(model.m_skinCount) { - if (m_mesh) + if (model.m_mesh) { - if (m_animation) - m_animation->AddResourceReference(); - - m_mesh->AddResourceReference(); + // Nous n'avons une animation et des matériaux que si nous avons un mesh + m_animation = model.m_animation; + m_mesh = model.m_mesh; + m_materials = model.m_materials; if (m_mesh->GetAnimationType() == nzAnimationType_Skeletal) m_skeleton = model.m_skeleton; - - // Nous n'avons des matériaux que si nous avons un mesh - for (const NzMaterial* material : m_materials) - material->AddResourceReference(); } } @@ -314,22 +306,11 @@ void NzModel::Reset() if (m_mesh) { - m_mesh->RemoveResourceReference(); - m_mesh = nullptr; + m_animation.Reset(); + m_mesh.Reset(); + m_materials.clear(); m_skeleton.Destroy(); - - if (m_animation) - { - m_animation->RemoveResourceReference(); - m_animation = nullptr; - } - - // Nous n'avons des matériaux que si nous avons un mesh - for (const NzMaterial* material : m_materials) - material->RemoveResourceReference(); - - m_materials.clear(); } } @@ -367,7 +348,6 @@ bool NzModel::SetAnimation(NzAnimation* animation) m_animation = animation; if (m_animation) { - m_animation->AddResourceReference(); m_currentFrame = 0; m_interpolation = 0.f; @@ -394,14 +374,10 @@ void NzModel::SetMaterial(unsigned int matIndex, NzMaterial* material) unsigned int index = m_skin*m_matCount + matIndex; - m_materials[index]->RemoveResourceReference(); - if (material) m_materials[index] = material; else m_materials[index] = NzMaterial::GetDefault(); - - m_materials[index]->AddResourceReference(); } void NzModel::SetMaterial(unsigned int skinIndex, unsigned int matIndex, NzMaterial* material) @@ -422,14 +398,10 @@ void NzModel::SetMaterial(unsigned int skinIndex, unsigned int matIndex, NzMater unsigned int index = skinIndex*m_matCount + matIndex; - m_materials[index]->RemoveResourceReference(); - if (material) m_materials[index] = material; else m_materials[index] = NzMaterial::GetDefault(); - - m_materials[index]->AddResourceReference(); } void NzModel::SetMesh(NzMesh* mesh, const NzModelParameters& modelParameters) @@ -440,7 +412,6 @@ void NzModel::SetMesh(NzMesh* mesh, const NzModelParameters& modelParameters) { m_boundingBoxUpdated = false; m_mesh = mesh; - m_mesh->AddResourceReference(); if (m_mesh->GetAnimationType() == nzAnimationType_Skeletal) m_skeleton = *mesh->GetSkeleton(); // Copie du squelette template @@ -462,7 +433,7 @@ void NzModel::SetMesh(NzMesh* mesh, const NzModelParameters& modelParameters) } m_matCount = mesh->GetMaterialCount(); - m_materials.resize(m_matCount, NzMaterial::GetDefault()); + m_materials.reserve(m_matCount); if (modelParameters.loadMaterials) { for (unsigned int i = 0; i < m_matCount; ++i) @@ -474,16 +445,17 @@ void NzModel::SetMesh(NzMesh* mesh, const NzModelParameters& modelParameters) if (material->LoadFromFile(mat, modelParameters.material)) { material->SetPersistent(false, false); // Pas de vérification des références car nous n'y avons pas encore accroché de référence - m_materials[i] = material.release(); + m_materials.push_back(material.release()); } else + { NazaraWarning("Failed to load material #" + NzString::Number(i)); + + m_materials.push_back(NzMaterial::GetDefault()); + } } } } - - for (const NzMaterial* material : m_materials) - material->AddResourceReference(); } } diff --git a/src/Nazara/Audio/Sound.cpp b/src/Nazara/Audio/Sound.cpp index 30e341817..684b7ba0a 100644 --- a/src/Nazara/Audio/Sound.cpp +++ b/src/Nazara/Audio/Sound.cpp @@ -25,9 +25,6 @@ NzSoundEmitter(sound) NzSound::~NzSound() { Stop(); - - if (m_buffer) - m_buffer->RemoveResourceReference(); } void NzSound::EnableLooping(bool loop) @@ -155,16 +152,10 @@ void NzSound::SetBuffer(const NzSoundBuffer* buffer) Stop(); - if (m_buffer) - m_buffer->RemoveResourceReference(); - m_buffer = buffer; if (m_buffer) - { - m_buffer->AddResourceReference(); alSourcei(m_source, AL_BUFFER, m_buffer->GetOpenALBuffer()); - } else alSourcei(m_source, AL_BUFFER, AL_NONE); } diff --git a/src/Nazara/Core/Resource.cpp b/src/Nazara/Core/Resource.cpp index 9535c592b..14b89dff5 100644 --- a/src/Nazara/Core/Resource.cpp +++ b/src/Nazara/Core/Resource.cpp @@ -68,7 +68,7 @@ bool NzResource::IsPersistent() const return m_resourcePersistent; } -void NzResource::RemoveResourceListener(NzResourceListener* listener) const +bool NzResource::RemoveResourceListener(NzResourceListener* listener) const { NazaraMutexLock(m_mutex); @@ -82,7 +82,7 @@ void NzResource::RemoveResourceListener(NzResourceListener* listener) const if (m_resourceReferenceCount == 0) { NazaraError("Impossible to remove reference (Ref. counter is already 0)"); - return; + return false; } #endif @@ -90,14 +90,18 @@ void NzResource::RemoveResourceListener(NzResourceListener* listener) const { NazaraMutexUnlock(m_mutex); delete this; + + return true; // On vient d'être supprimé } else { NazaraMutexUnlock(m_mutex); + + return false; } } -void NzResource::RemoveResourceReference() const +bool NzResource::RemoveResourceReference() const { NazaraMutexLock(m_mutex); @@ -105,7 +109,7 @@ void NzResource::RemoveResourceReference() const if (m_resourceReferenceCount == 0) { NazaraError("Impossible to remove reference (Ref. counter is already 0)"); - return; + return false; } #endif @@ -113,10 +117,14 @@ void NzResource::RemoveResourceReference() const { NazaraMutexUnlock(m_mutex); delete this; + + return true; } else { NazaraMutexUnlock(m_mutex); + + return false; } } diff --git a/src/Nazara/Renderer/Material.cpp b/src/Nazara/Renderer/Material.cpp index 776f76e27..16bc3d316 100644 --- a/src/Nazara/Renderer/Material.cpp +++ b/src/Nazara/Renderer/Material.cpp @@ -14,12 +14,7 @@ bool NzMaterialParams::IsValid() const return true; } -NzMaterial::NzMaterial() : -m_customShader(nullptr), -m_diffuseMap(nullptr), -m_heightMap(nullptr), -m_normalMap(nullptr), -m_specularMap(nullptr) +NzMaterial::NzMaterial() { Reset(); } @@ -27,28 +22,12 @@ m_specularMap(nullptr) NzMaterial::NzMaterial(const NzMaterial& material) : NzResource() { - std::memcpy(this, &material, sizeof(NzMaterial)); // Autorisé dans notre cas, et plus rapide - - // Cependant comme nous sommes une entité à part nous devons ajouter les références aux ressources - if (m_customShader) - m_customShader->AddResourceReference(); - - if (m_diffuseMap) - m_diffuseMap->AddResourceReference(); - - if (m_heightMap) - m_heightMap->AddResourceReference(); - - if (m_normalMap) - m_normalMap->AddResourceReference(); - - if (m_specularMap) - m_specularMap->AddResourceReference(); + Copy(material); } NzMaterial::NzMaterial(NzMaterial&& material) { - std::memcpy(this, &material, sizeof(NzMaterial)); // Autorisé dans notre cas, et plus rapide + Copy(material); // Nous "volons" la référence du matériau material.m_customShader = nullptr; @@ -58,24 +37,6 @@ NzMaterial::NzMaterial(NzMaterial&& material) material.m_specularMap = nullptr; } -NzMaterial::~NzMaterial() -{ - if (m_customShader) - m_customShader->RemoveResourceReference(); - - if (m_diffuseMap) - m_diffuseMap->RemoveResourceReference(); - - if (m_heightMap) - m_heightMap->RemoveResourceReference(); - - if (m_normalMap) - m_normalMap->RemoveResourceReference(); - - if (m_specularMap) - m_specularMap->RemoveResourceReference(); -} - void NzMaterial::Apply(const NzShader* shader) const { int ambientColorLocation = shader->GetUniformLocation("MaterialAmbient"); @@ -346,35 +307,11 @@ bool NzMaterial::LoadFromStream(NzInputStream& stream, const NzMaterialParams& p void NzMaterial::Reset() { - if (m_customShader) - { - m_customShader->RemoveResourceReference(); - m_customShader = nullptr; - } - - if (m_diffuseMap) - { - m_diffuseMap->RemoveResourceReference(); - m_diffuseMap = nullptr; - } - - if (m_heightMap) - { - m_heightMap->RemoveResourceReference(); - m_heightMap = nullptr; - } - - if (m_normalMap) - { - m_normalMap->RemoveResourceReference(); - m_normalMap = nullptr; - } - - if (m_specularMap) - { - m_specularMap->RemoveResourceReference(); - m_specularMap = nullptr; - } + m_customShader.Reset(); + m_diffuseMap.Reset(); + m_heightMap.Reset(); + m_normalMap.Reset(); + m_specularMap.Reset(); m_alphaBlendingEnabled = false; m_ambientColor = NzColor(128, 128, 128); @@ -402,15 +339,7 @@ void NzMaterial::SetAmbientColor(const NzColor& ambient) void NzMaterial::SetCustomShader(const NzShader* shader) { - if (m_customShader != shader) - { - if (m_customShader) - m_customShader->RemoveResourceReference(); - - m_customShader = shader; - if (m_customShader) - m_customShader->AddResourceReference(); - } + m_customShader = shader; } void NzMaterial::SetDiffuseColor(const NzColor& diffuse) @@ -420,21 +349,11 @@ void NzMaterial::SetDiffuseColor(const NzColor& diffuse) void NzMaterial::SetDiffuseMap(NzTexture* map) { - if (m_diffuseMap != map) - { - if (m_diffuseMap) - { - m_diffuseMap->RemoveResourceReference(); - m_shaderFlags &= ~nzShaderFlags_DiffuseMapping; - } - - m_diffuseMap = map; - if (m_diffuseMap) - { - m_diffuseMap->AddResourceReference(); - m_shaderFlags |= nzShaderFlags_DiffuseMapping; - } - } + m_diffuseMap = map; + if (m_diffuseMap) + m_shaderFlags |= nzShaderFlags_DiffuseMapping; + else + m_shaderFlags &= ~nzShaderFlags_DiffuseMapping; } void NzMaterial::SetDiffuseSampler(const NzTextureSampler& sampler) @@ -459,34 +378,16 @@ void NzMaterial::SetFaceFilling(nzFaceFilling filling) void NzMaterial::SetHeightMap(NzTexture* map) { - if (m_heightMap != map) - { - if (m_heightMap) - m_heightMap->RemoveResourceReference(); - - m_heightMap = map; - if (m_heightMap) - m_heightMap->AddResourceReference(); - } + m_heightMap = map; } void NzMaterial::SetNormalMap(NzTexture* map) { - if (m_normalMap != map) - { - if (m_normalMap) - { - m_normalMap->RemoveResourceReference(); - m_shaderFlags &= ~nzShaderFlags_NormalMapping; - } - - m_normalMap = map; - if (m_normalMap) - { - m_normalMap->AddResourceReference(); - m_shaderFlags |= nzShaderFlags_NormalMapping; - } - } + m_normalMap = map; + if (m_normalMap) + m_shaderFlags |= nzShaderFlags_NormalMapping; + else + m_shaderFlags &= ~nzShaderFlags_NormalMapping; } void NzMaterial::SetShininess(float shininess) @@ -501,21 +402,11 @@ void NzMaterial::SetSpecularColor(const NzColor& specular) void NzMaterial::SetSpecularMap(NzTexture* map) { - if (m_specularMap != map) - { - if (m_specularMap) - { - m_specularMap->RemoveResourceReference(); - m_shaderFlags &= ~nzShaderFlags_SpecularMapping; - } - - m_specularMap = map; - if (m_specularMap) - { - m_specularMap->AddResourceReference(); - m_shaderFlags |= nzShaderFlags_SpecularMapping; - } - } + m_specularMap = map; + if (m_specularMap) + m_shaderFlags |= nzShaderFlags_SpecularMapping; + else + m_shaderFlags &= ~nzShaderFlags_SpecularMapping; } void NzMaterial::SetSpecularSampler(const NzTextureSampler& sampler) @@ -535,60 +426,14 @@ void NzMaterial::SetZTestCompare(nzRendererComparison compareFunc) NzMaterial& NzMaterial::operator=(const NzMaterial& material) { - if (m_customShader) - m_customShader->RemoveResourceReference(); - - if (m_diffuseMap) - m_diffuseMap->RemoveResourceReference(); - - if (m_heightMap) - m_heightMap->RemoveResourceReference(); - - if (m_normalMap) - m_normalMap->RemoveResourceReference(); - - if (m_specularMap) - m_specularMap->RemoveResourceReference(); - - std::memcpy(this, &material, sizeof(NzMaterial)); // Autorisé dans notre cas, et plus rapide - - // Cependant comme nous sommes une entité à part nous devons ajouter les références aux ressources - if (m_customShader) - m_customShader->AddResourceReference(); - - if (m_diffuseMap) - m_diffuseMap->AddResourceReference(); - - if (m_heightMap) - m_heightMap->AddResourceReference(); - - if (m_normalMap) - m_normalMap->AddResourceReference(); - - if (m_specularMap) - m_specularMap->AddResourceReference(); + Copy(material); return *this; } NzMaterial& NzMaterial::operator=(NzMaterial&& material) { - if (m_customShader) - m_customShader->RemoveResourceReference(); - - if (m_diffuseMap) - m_diffuseMap->RemoveResourceReference(); - - if (m_heightMap) - m_heightMap->RemoveResourceReference(); - - if (m_normalMap) - m_normalMap->RemoveResourceReference(); - - if (m_specularMap) - m_specularMap->RemoveResourceReference(); - - std::memcpy(this, &material, sizeof(NzMaterial)); // Autorisé dans notre cas, et plus rapide + Copy(material); // Comme ça nous volons la référence du matériau material.m_customShader = nullptr; @@ -618,4 +463,28 @@ NzMaterial* NzMaterial::GetDefault() return &defaultMaterial; } +void NzMaterial::Copy(const NzMaterial& material) +{ + m_customShader.Reset(); + m_diffuseMap.Reset(); + m_heightMap.Reset(); + m_normalMap.Reset(); + m_specularMap.Reset(); + + std::memcpy(this, &material, sizeof(NzMaterial)); // Autorisé dans notre cas, et bien plus rapide + + // Ensuite une petite astuce pour récupérer correctement les références + m_customShader.Release(); + m_diffuseMap.Release(); + m_heightMap.Release(); + m_normalMap.Release(); + m_specularMap.Release(); + + m_customShader = material.m_customShader; + m_diffuseMap = material.m_diffuseMap; + m_heightMap = material.m_heightMap; + m_normalMap = material.m_normalMap; + m_specularMap = material.m_specularMap; +} + NzMaterialLoader::LoaderList NzMaterial::s_loaders; diff --git a/src/Nazara/Renderer/ShaderBuilder.cpp b/src/Nazara/Renderer/ShaderBuilder.cpp index c48a06144..fa86b7403 100644 --- a/src/Nazara/Renderer/ShaderBuilder.cpp +++ b/src/Nazara/Renderer/ShaderBuilder.cpp @@ -13,7 +13,7 @@ namespace { - std::unordered_map s_shaders; + std::unordered_map> s_shaders; NzString BuildFragmentShaderSource(nzUInt32 flags) { @@ -471,7 +471,6 @@ const NzShader* NzShaderBuilder::Get(nzUInt32 flags) } s_shaders[flags] = shader; - shader->AddResourceReference(); return shader; } @@ -489,15 +488,11 @@ bool NzShaderBuilder::Initialize() } s_shaders[0] = shader; - shader->AddResourceReference(); return true; } void NzShaderBuilder::Uninitialize() { - for (auto it : s_shaders) - it.second->RemoveResourceReference(); - s_shaders.clear(); } diff --git a/src/Nazara/Utility/IndexBuffer.cpp b/src/Nazara/Utility/IndexBuffer.cpp index 65f58db58..64ad4ea4c 100644 --- a/src/Nazara/Utility/IndexBuffer.cpp +++ b/src/Nazara/Utility/IndexBuffer.cpp @@ -28,8 +28,6 @@ m_startIndex(startIndex) throw std::runtime_error("Constructor failed"); } #endif - - m_buffer->AddResourceReference(); } } @@ -39,7 +37,6 @@ m_indexCount(length), m_startIndex(0) { m_buffer = new NzBuffer(nzBufferType_Index, length, (largeIndices) ? 4 : 2, storage, usage); - m_buffer->AddResourceReference(); m_buffer->SetPersistent(false); } @@ -57,23 +54,15 @@ m_startIndex(indexBuffer.m_startIndex) NzBuffer* buffer = indexBuffer.m_buffer; m_buffer = new NzBuffer(nzBufferType_Index, buffer->GetLength(), buffer->GetSize(), buffer->GetStorage(), buffer->GetUsage()); - m_buffer->AddResourceReference(); m_buffer->SetPersistent(false); m_buffer->CopyContent(*indexBuffer.m_buffer); } else - { m_buffer = indexBuffer.m_buffer; - m_buffer->AddResourceReference(); - } } } -NzIndexBuffer::~NzIndexBuffer() -{ - if (m_buffer) - m_buffer->RemoveResourceReference(); -} +NzIndexBuffer::~NzIndexBuffer() = default; bool NzIndexBuffer::Fill(const void* data, unsigned int offset, unsigned int length) { diff --git a/src/Nazara/Utility/SkeletalMesh.cpp b/src/Nazara/Utility/SkeletalMesh.cpp index 6b031f1db..697906d91 100644 --- a/src/Nazara/Utility/SkeletalMesh.cpp +++ b/src/Nazara/Utility/SkeletalMesh.cpp @@ -136,7 +136,7 @@ struct NzSkeletalMeshImpl std::vector weights; NzCubef aabb; nzUInt8* bindPoseBuffer; - const NzIndexBuffer* indexBuffer = nullptr; + NzIndexBufferConstRef indexBuffer; unsigned int vertexCount; }; @@ -401,11 +401,5 @@ void NzSkeletalMesh::Skin(NzMeshVertex* outputBuffer, const NzSkeleton* skeleton void NzSkeletalMesh::SetIndexBuffer(const NzIndexBuffer* indexBuffer) { - if (m_impl->indexBuffer) - m_impl->indexBuffer->RemoveResourceReference(); - - if (indexBuffer) - indexBuffer->AddResourceReference(); - m_impl->indexBuffer = indexBuffer; } diff --git a/src/Nazara/Utility/VertexBuffer.cpp b/src/Nazara/Utility/VertexBuffer.cpp index 8ab8bc08c..2b5e3d68f 100644 --- a/src/Nazara/Utility/VertexBuffer.cpp +++ b/src/Nazara/Utility/VertexBuffer.cpp @@ -29,9 +29,6 @@ m_vertexCount(vertexCount) throw std::invalid_argument("Invalid vertex declaration"); } #endif - - m_buffer->AddResourceReference(); - m_vertexDeclaration->AddResourceReference(); } NzVertexBuffer::NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzBufferStorage storage, nzBufferUsage usage) : @@ -49,9 +46,7 @@ m_vertexCount(length) #endif m_buffer = new NzBuffer(nzBufferType_Vertex, length, vertexDeclaration->GetStride(nzElementStream_VertexData), storage, usage); - m_buffer->AddResourceReference(); m_buffer->SetPersistent(false); - m_vertexDeclaration->AddResourceReference(); } NzVertexBuffer::NzVertexBuffer(const NzVertexBuffer& vertexBuffer) : @@ -66,24 +61,14 @@ m_vertexCount(vertexBuffer.m_vertexCount) NzBuffer* buffer = vertexBuffer.m_buffer; m_buffer = new NzBuffer(nzBufferType_Vertex, buffer->GetLength(), buffer->GetSize(), buffer->GetStorage(), buffer->GetUsage()); - m_buffer->AddResourceReference(); m_buffer->SetPersistent(false); m_buffer->CopyContent(*vertexBuffer.m_buffer); } else - { m_buffer = vertexBuffer.m_buffer; - m_buffer->AddResourceReference(); - } - - m_vertexDeclaration->AddResourceReference(); } -NzVertexBuffer::~NzVertexBuffer() -{ - m_buffer->RemoveResourceReference(); - m_vertexDeclaration->RemoveResourceReference(); -} +NzVertexBuffer::~NzVertexBuffer() = default; bool NzVertexBuffer::Fill(const void* data, unsigned int offset, unsigned int length) { diff --git a/src/Nazara/Utility/VertexMapper.cpp b/src/Nazara/Utility/VertexMapper.cpp index 6c6e0686e..e4462079a 100644 --- a/src/Nazara/Utility/VertexMapper.cpp +++ b/src/Nazara/Utility/VertexMapper.cpp @@ -52,7 +52,7 @@ namespace } protected: - NzSubMesh* m_subMesh; + NzSubMeshRef m_subMesh; }; class SkeletalMeshVertexMapper : public SubMeshVertexMapper @@ -63,13 +63,10 @@ namespace m_mesh(subMesh) { m_vertices = reinterpret_cast(m_mesh->GetBindPoseBuffer()); - - m_mesh->AddResourceReference(); } virtual ~SkeletalMeshVertexMapper() noexcept { - m_mesh->RemoveResourceReference(); } NzVector3f GetNormal(unsigned int i) const