Added ResourceRef (Automatic resource reference)

Former-commit-id: 97a0b2732f4dc443b8e1676e68b33b1b53ddf4fb
This commit is contained in:
Lynix
2013-03-15 03:09:58 +01:00
parent 4ee6ca05ed
commit 6c2fb1eb89
29 changed files with 344 additions and 299 deletions

View File

@@ -11,8 +11,6 @@
#include <Nazara/3D/Debug.hpp>
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();
}
}

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -13,7 +13,7 @@
namespace
{
std::unordered_map<nzUInt32, NzShader*> s_shaders;
std::unordered_map<nzUInt32, NzResourceRef<NzShader>> 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();
}

View File

@@ -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)
{

View File

@@ -136,7 +136,7 @@ struct NzSkeletalMeshImpl
std::vector<NzWeight> 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;
}

View File

@@ -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)
{

View File

@@ -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<NzMeshVertex*>(m_mesh->GetBindPoseBuffer());
m_mesh->AddResourceReference();
}
virtual ~SkeletalMeshVertexMapper() noexcept
{
m_mesh->RemoveResourceReference();
}
NzVector3f GetNormal(unsigned int i) const