Improved ResourceListeners
Former-commit-id: 8016c23cb75aab94762a1e2838dbbcac2093119b
This commit is contained in:
@@ -12,15 +12,16 @@
|
||||
|
||||
NzResource::NzResource(bool persistent) :
|
||||
m_resourcePersistent(persistent),
|
||||
m_resourceReferenceCount(0)
|
||||
m_resourceReferenceCount(0),
|
||||
m_resourceListenersLocked(false)
|
||||
{
|
||||
}
|
||||
|
||||
NzResource::~NzResource()
|
||||
{
|
||||
EnsureResourceListenerUpdate();
|
||||
for (const NzResourceEntry& entry : m_resourceListenersCache)
|
||||
entry.listener->OnResourceReleased(this, entry.index);
|
||||
m_resourceListenersLocked = true;
|
||||
for (auto& pair : m_resourceListeners)
|
||||
pair.first->OnResourceReleased(this, pair.second);
|
||||
|
||||
#if NAZARA_CORE_SAFE
|
||||
if (m_resourceReferenceCount > 0)
|
||||
@@ -30,10 +31,11 @@ NzResource::~NzResource()
|
||||
|
||||
void NzResource::AddResourceListener(NzResourceListener* listener, int index) const
|
||||
{
|
||||
///DOC: Est ignoré si appelé depuis un évènement
|
||||
NazaraLock(m_mutex)
|
||||
|
||||
if (m_resourceListeners.insert(NzResourceEntry(listener, index)).second)
|
||||
m_resourceListenerUpdated = false;
|
||||
if (!m_resourceListenersLocked)
|
||||
m_resourceListeners.insert(std::make_pair(listener, index));
|
||||
}
|
||||
|
||||
void NzResource::AddResourceReference() const
|
||||
@@ -53,10 +55,11 @@ bool NzResource::IsPersistent() const
|
||||
|
||||
void NzResource::RemoveResourceListener(NzResourceListener* listener) const
|
||||
{
|
||||
NazaraMutexLock(m_mutex);
|
||||
///DOC: Est ignoré si appelé depuis un évènement
|
||||
NazaraLock(m_mutex);
|
||||
|
||||
if (m_resourceListeners.erase(listener) != 0)
|
||||
m_resourceListenerUpdated = false;
|
||||
if (!m_resourceListenersLocked)
|
||||
m_resourceListeners.erase(listener);
|
||||
}
|
||||
|
||||
bool NzResource::RemoveResourceReference() const
|
||||
@@ -97,26 +100,34 @@ void NzResource::NotifyCreated()
|
||||
{
|
||||
NazaraLock(m_mutex)
|
||||
|
||||
EnsureResourceListenerUpdate();
|
||||
for (const NzResourceEntry& entry : m_resourceListenersCache)
|
||||
entry.listener->OnResourceCreated(this, entry.index);
|
||||
m_resourceListenersLocked = true;
|
||||
|
||||
auto it = m_resourceListeners.begin();
|
||||
while (it != m_resourceListeners.end())
|
||||
{
|
||||
if (!it->first->OnResourceCreated(this, it->second))
|
||||
m_resourceListeners.erase(it++);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
m_resourceListenersLocked = false;
|
||||
}
|
||||
|
||||
void NzResource::NotifyDestroy()
|
||||
{
|
||||
NazaraLock(m_mutex)
|
||||
|
||||
EnsureResourceListenerUpdate();
|
||||
for (const NzResourceEntry& entry : m_resourceListenersCache)
|
||||
entry.listener->OnResourceDestroy(this, entry.index);
|
||||
}
|
||||
m_resourceListenersLocked = true;
|
||||
|
||||
void NzResource::EnsureResourceListenerUpdate() const
|
||||
{
|
||||
// Déjà bloqué par une mutex
|
||||
if (!m_resourceListenerUpdated)
|
||||
auto it = m_resourceListeners.begin();
|
||||
while (it != m_resourceListeners.end())
|
||||
{
|
||||
m_resourceListenersCache = m_resourceListeners;
|
||||
m_resourceListenerUpdated = true;
|
||||
if (!it->first->OnResourceDestroy(this, it->second))
|
||||
m_resourceListeners.erase(it++);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
m_resourceListenersLocked = false;
|
||||
}
|
||||
|
||||
@@ -7,16 +7,20 @@
|
||||
|
||||
NzResourceListener::~NzResourceListener() = default;
|
||||
|
||||
void NzResourceListener::OnResourceCreated(const NzResource* resource, int index)
|
||||
bool NzResourceListener::OnResourceCreated(const NzResource* resource, int index)
|
||||
{
|
||||
NazaraUnused(resource);
|
||||
NazaraUnused(index);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzResourceListener::OnResourceDestroy(const NzResource* resource, int index)
|
||||
bool NzResourceListener::OnResourceDestroy(const NzResource* resource, int index)
|
||||
{
|
||||
NazaraUnused(resource);
|
||||
NazaraUnused(index);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzResourceListener::OnResourceReleased(const NzResource* resource, int index)
|
||||
|
||||
@@ -206,7 +206,7 @@ void NzForwardRenderQueue::Sort(const NzCamera& camera)
|
||||
std::sort(transparentsModels.begin(), transparentsModels.end(), comparator);
|
||||
}
|
||||
|
||||
void NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int index)
|
||||
bool NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
@@ -231,7 +231,7 @@ void NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int ind
|
||||
}
|
||||
}
|
||||
|
||||
resource->RemoveResourceListener(this);
|
||||
return false; // Nous ne voulons plus recevoir d'évènement de cette ressource
|
||||
}
|
||||
|
||||
bool NzForwardRenderQueue::SkeletalMeshComparator::operator()(const NzSkeletalMesh* subMesh1, const NzSkeletalMesh* subMesh2)
|
||||
|
||||
@@ -520,7 +520,7 @@ bool NzGLSLProgram::SendVector(int location, const NzVector4f& vector)
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzGLSLProgram::OnResourceCreated(const NzResource* resource, int index)
|
||||
bool NzGLSLProgram::OnResourceCreated(const NzResource* resource, int index)
|
||||
{
|
||||
NazaraUnused(resource);
|
||||
|
||||
@@ -530,7 +530,7 @@ void NzGLSLProgram::OnResourceCreated(const NzResource* resource, int index)
|
||||
if (it == m_textures.end())
|
||||
{
|
||||
NazaraInternalError("Invalid index (" + NzString::Number(index) + ')');
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -540,15 +540,17 @@ void NzGLSLProgram::OnResourceCreated(const NzResource* resource, int index)
|
||||
if (slot.texture != resource)
|
||||
{
|
||||
NazaraInternalError("Wrong texture at location #" + NzString::Number(index));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
slot.enabled = true;
|
||||
slot.updated = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzGLSLProgram::OnResourceDestroy(const NzResource* resource, int index)
|
||||
bool NzGLSLProgram::OnResourceDestroy(const NzResource* resource, int index)
|
||||
{
|
||||
NazaraUnused(resource);
|
||||
|
||||
@@ -558,7 +560,7 @@ void NzGLSLProgram::OnResourceDestroy(const NzResource* resource, int index)
|
||||
if (it == m_textures.end())
|
||||
{
|
||||
NazaraInternalError("Invalid index (" + NzString::Number(index) + ')');
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -568,19 +570,19 @@ void NzGLSLProgram::OnResourceDestroy(const NzResource* resource, int index)
|
||||
if (slot.texture != resource)
|
||||
{
|
||||
NazaraInternalError("Wrong texture at location #" + NzString::Number(index));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
slot.enabled = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzGLSLProgram::OnResourceReleased(const NzResource* resource, int index)
|
||||
{
|
||||
if (m_textures.erase(index) == 0)
|
||||
NazaraInternalError("Texture " + NzString::Pointer(resource) + " not found");
|
||||
|
||||
resource->RemoveResourceListener(this);
|
||||
}
|
||||
|
||||
void NzGLSLProgram::PreLinkage()
|
||||
|
||||
@@ -60,8 +60,8 @@ class NzGLSLProgram : public NzAbstractShaderProgram, NzResourceListener
|
||||
bool SendVector(int location, const NzVector4f& vector);
|
||||
|
||||
private:
|
||||
void OnResourceCreated(const NzResource* resource, int index) override;
|
||||
void OnResourceDestroy(const NzResource* resource, int index) override;
|
||||
bool OnResourceCreated(const NzResource* resource, int index) override;
|
||||
bool OnResourceDestroy(const NzResource* resource, int index) override;
|
||||
void OnResourceReleased(const NzResource* resource, int index) override;
|
||||
void PreLinkage();
|
||||
bool PostLinkage();
|
||||
|
||||
@@ -324,11 +324,12 @@ void NzRenderTexture::Destroy()
|
||||
{
|
||||
if (m_impl)
|
||||
{
|
||||
bool canFreeFBO = true;
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (NzContext::GetCurrent() != m_impl->context)
|
||||
{
|
||||
NazaraError("RenderTexture can only be used with it's creation context");
|
||||
return;
|
||||
NazaraWarning("RenderTexture should be destroyed by it's creation context, this will cause leaks");
|
||||
canFreeFBO = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -339,7 +340,7 @@ void NzRenderTexture::Destroy()
|
||||
if (attachment.isUsed)
|
||||
{
|
||||
if (attachment.isBuffer)
|
||||
glDeleteRenderbuffers(1, &attachment.buffer);
|
||||
glDeleteRenderbuffers(1, &attachment.buffer); // Les Renderbuffers sont partagés entre les contextes: Ne posera pas de problème
|
||||
else
|
||||
{
|
||||
attachment.texture->SetRenderTexture(nullptr);
|
||||
@@ -348,7 +349,8 @@ void NzRenderTexture::Destroy()
|
||||
}
|
||||
}
|
||||
|
||||
glDeleteFramebuffers(1, &m_impl->fbo);
|
||||
if (canFreeFBO)
|
||||
glDeleteFramebuffers(1, &m_impl->fbo);
|
||||
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
@@ -636,11 +638,15 @@ void NzRenderTexture::Desactivate() const
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void NzRenderTexture::OnResourceDestroy(const NzResource* resource, int index)
|
||||
bool NzRenderTexture::OnResourceDestroy(const NzResource* resource, int index)
|
||||
{
|
||||
if (resource == m_impl->context)
|
||||
// Notre context a été détruit, libérons la RenderTexture pour éviter un leak
|
||||
{
|
||||
// Notre contexte va être détruit, libérons la RenderTexture pour éviter un leak
|
||||
Destroy();
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Sinon, c'est une texture
|
||||
@@ -652,5 +658,7 @@ void NzRenderTexture::OnResourceDestroy(const NzResource* resource, int index)
|
||||
|
||||
m_impl->checked = false;
|
||||
m_impl->drawBuffersUpdated = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,6 +128,4 @@ void NzStaticMesh::OnResourceReleased(const NzResource* resource, int index)
|
||||
m_vertexBuffer = nullptr;
|
||||
else
|
||||
NazaraInternalError("Not listening to " + NzString::Pointer(resource));
|
||||
|
||||
resource->RemoveResourceListener(this);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user