From 88af94b9877f7e00870b5c09a3501537e4b58117 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 7 Jan 2015 23:47:09 +0100 Subject: [PATCH] Added ResourceConstListener I don't know yet if it's a good idea but at least it's an idea Former-commit-id: b034a787d8d8ccce0804f1276958b32c9e149147 --- include/Nazara/Core/Resource.hpp | 6 ++ include/Nazara/Core/ResourceConstListener.hpp | 26 ++++++++ src/Nazara/Core/Resource.cpp | 63 +++++++++++++++++++ src/Nazara/Core/ResourceConstListener.cpp | 39 ++++++++++++ 4 files changed, 134 insertions(+) create mode 100644 include/Nazara/Core/ResourceConstListener.hpp create mode 100644 src/Nazara/Core/ResourceConstListener.cpp diff --git a/include/Nazara/Core/Resource.hpp b/include/Nazara/Core/Resource.hpp index adf0eace2..e82b33fad 100644 --- a/include/Nazara/Core/Resource.hpp +++ b/include/Nazara/Core/Resource.hpp @@ -17,6 +17,7 @@ #include #endif +class NzResourceConstListener; class NzResourceListener; class NAZARA_API NzResource @@ -25,6 +26,7 @@ class NAZARA_API NzResource NzResource(bool persistent = true); virtual ~NzResource(); + void AddResourceConstListener(const NzResourceConstListener* listener, int index = 0) const; void AddResourceListener(NzResourceListener* listener, int index = 0) const; void AddResourceReference() const; @@ -32,6 +34,7 @@ class NAZARA_API NzResource bool IsPersistent() const; + void RemoveResourceConstListener(const NzResourceConstListener* listener) const; void RemoveResourceListener(NzResourceListener* listener) const; bool RemoveResourceReference() const; @@ -43,13 +46,16 @@ class NAZARA_API NzResource void NotifyModified(unsigned int code); private: + using ResourceConstListenerMap = std::unordered_map>; using ResourceListenerMap = std::unordered_map>; + void RemoveResourceConstListenerIterator(ResourceConstListenerMap::iterator iterator) const; void RemoveResourceListenerIterator(ResourceListenerMap::iterator iterator) const; NazaraMutexAttrib(m_mutex, mutable) // Je fais précéder le nom par 'resource' pour éviter les éventuels conflits de noms + mutable ResourceConstListenerMap m_resourceConstListeners; mutable ResourceListenerMap m_resourceListeners; std::atomic_bool m_resourcePersistent; mutable std::atomic_uint m_resourceReferenceCount; diff --git a/include/Nazara/Core/ResourceConstListener.hpp b/include/Nazara/Core/ResourceConstListener.hpp new file mode 100644 index 000000000..7113c3c94 --- /dev/null +++ b/include/Nazara/Core/ResourceConstListener.hpp @@ -0,0 +1,26 @@ +// Copyright (C) 2015 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_RESOURCECONSTLISTENER_HPP +#define NAZARA_RESOURCECONSTLISTENER_HPP + +#include + +class NzResource; + +class NAZARA_API NzResourceConstListener +{ + public: + NzResourceConstListener() = default; + virtual ~NzResourceConstListener(); + + virtual bool OnResourceCreated(const NzResource* resource, int index) const; + virtual bool OnResourceDestroy(const NzResource* resource, int index) const; + virtual bool OnResourceModified(const NzResource* resource, int index, unsigned int code) const; + virtual void OnResourceReleased(const NzResource* resource, int index) const; +}; + +#endif // NAZARA_RESOURCECONSTLISTENER_HPP diff --git a/src/Nazara/Core/Resource.cpp b/src/Nazara/Core/Resource.cpp index 5610d9d13..fbdaf1853 100644 --- a/src/Nazara/Core/Resource.cpp +++ b/src/Nazara/Core/Resource.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_RESOURCE @@ -34,6 +35,19 @@ NzResource::~NzResource() #endif } +void NzResource::AddResourceConstListener(const NzResourceConstListener* listener, int index) const +{ + ///DOC: Est ignoré si appelé depuis un évènement + NazaraLock(m_mutex) + + if (!m_resourceListenersLocked) + { + auto pair = m_resourceConstListeners.insert(std::make_pair(listener, std::make_pair(index, 1U))); + if (!pair.second) + pair.first->second.second++; + } +} + void NzResource::AddResourceListener(NzResourceListener* listener, int index) const { ///DOC: Est ignoré si appelé depuis un évènement @@ -62,6 +76,19 @@ bool NzResource::IsPersistent() const return m_resourcePersistent; } +void NzResource::RemoveResourceConstListener(const NzResourceConstListener* listener) const +{ + ///DOC: Est ignoré si appelé depuis un évènement + NazaraLock(m_mutex); + + if (!m_resourceListenersLocked) + { + ResourceConstListenerMap::iterator it = m_resourceConstListeners.find(listener); + if (it != m_resourceConstListeners.end()) + RemoveResourceConstListenerIterator(it); + } +} + void NzResource::RemoveResourceListener(NzResourceListener* listener) const { ///DOC: Est ignoré si appelé depuis un évènement @@ -115,6 +142,15 @@ void NzResource::NotifyCreated() m_resourceListenersLocked = true; + auto constIt = m_resourceConstListeners.begin(); + while (constIt != m_resourceConstListeners.end()) + { + if (!constIt->first->OnResourceCreated(this, constIt->second.first)) + RemoveResourceConstListenerIterator(constIt++); + else + ++constIt; + } + auto it = m_resourceListeners.begin(); while (it != m_resourceListeners.end()) { @@ -133,6 +169,15 @@ void NzResource::NotifyDestroy() m_resourceListenersLocked = true; + auto constIt = m_resourceConstListeners.begin(); + while (constIt != m_resourceConstListeners.end()) + { + if (!constIt->first->OnResourceDestroy(this, constIt->second.first)) + RemoveResourceConstListenerIterator(constIt++); + else + ++constIt; + } + auto it = m_resourceListeners.begin(); while (it != m_resourceListeners.end()) { @@ -151,6 +196,15 @@ void NzResource::NotifyModified(unsigned int code) m_resourceListenersLocked = true; + auto constIt = m_resourceConstListeners.begin(); + while (constIt != m_resourceConstListeners.end()) + { + if (!constIt->first->OnResourceModified(this, constIt->second.first, code)) + RemoveResourceConstListenerIterator(constIt++); + else + ++constIt; + } + auto it = m_resourceListeners.begin(); while (it != m_resourceListeners.end()) { @@ -163,6 +217,15 @@ void NzResource::NotifyModified(unsigned int code) m_resourceListenersLocked = false; } +void NzResource::RemoveResourceConstListenerIterator(ResourceConstListenerMap::iterator iterator) const +{ + unsigned int& referenceCount = iterator->second.second; + if (referenceCount == 1) + m_resourceConstListeners.erase(iterator); + else + referenceCount--; +} + void NzResource::RemoveResourceListenerIterator(ResourceListenerMap::iterator iterator) const { unsigned int& referenceCount = iterator->second.second; diff --git a/src/Nazara/Core/ResourceConstListener.cpp b/src/Nazara/Core/ResourceConstListener.cpp new file mode 100644 index 000000000..ebcbdc0ec --- /dev/null +++ b/src/Nazara/Core/ResourceConstListener.cpp @@ -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 +#include + +NzResourceConstListener::~NzResourceConstListener() = default; + +bool NzResourceConstListener::OnResourceCreated(const NzResource* resource, int index) const +{ + NazaraUnused(resource); + NazaraUnused(index); + + return true; +} + +bool NzResourceConstListener::OnResourceDestroy(const NzResource* resource, int index) const +{ + NazaraUnused(resource); + NazaraUnused(index); + + return true; +} + +bool NzResourceConstListener::OnResourceModified(const NzResource* resource, int index, unsigned int code) const +{ + NazaraUnused(resource); + NazaraUnused(index); + NazaraUnused(code); + + return true; +} + +void NzResourceConstListener::OnResourceReleased(const NzResource* resource, int index) const +{ + NazaraUnused(resource); + NazaraUnused(index); +}