diff --git a/simgear/misc/ResourceManager.cxx b/simgear/misc/ResourceManager.cxx index 178cc96e..71d83928 100644 --- a/simgear/misc/ResourceManager.cxx +++ b/simgear/misc/ResourceManager.cxx @@ -20,11 +20,17 @@ #include #include +#include namespace simgear { -static ResourceManager* static_manager = NULL; +static ResourceManager* static_manager = nullptr; + +ResourceProvider::~ResourceProvider() +{ + // pin to this compilation unit +} ResourceManager::ResourceManager() { @@ -40,13 +46,20 @@ ResourceManager* ResourceManager::instance() return static_manager; } +ResourceManager::~ResourceManager() +{ + assert(this == static_manager); + static_manager = nullptr; + std::for_each(_providers.begin(), _providers.end(), + [](ResourceProvider* p) { delete p; }); +} /** * trivial provider using a fixed base path */ class BasePathProvider : public ResourceProvider { public: - BasePathProvider(const SGPath& aBase, int aPriority) : + BasePathProvider(const SGPath& aBase, ResourceManager::Priority aPriority) : ResourceProvider(aPriority), _base(aBase) { @@ -69,6 +82,8 @@ void ResourceManager::addBasePath(const SGPath& aPath, Priority aPriority) void ResourceManager::addProvider(ResourceProvider* aProvider) { + assert(aProvider); + ProviderVec::iterator it = _providers.begin(); for (; it != _providers.end(); ++it) { if (aProvider->priority() > (*it)->priority()) { @@ -81,6 +96,16 @@ void ResourceManager::addProvider(ResourceProvider* aProvider) _providers.push_back(aProvider); } +void ResourceManager::removeProvider(ResourceProvider* aProvider) +{ + assert(aProvider); + auto it = std::find(_providers.begin(), _providers.end(), aProvider); + if (it == _providers.end()) { + SG_LOG(SG_GENERAL, SG_DEV_ALERT, "unknown provider doing remove"); + return; + } +} + SGPath ResourceManager::findPath(const std::string& aResource, SGPath aContext) { if (!aContext.isNull()) { @@ -90,9 +115,8 @@ SGPath ResourceManager::findPath(const std::string& aResource, SGPath aContext) } } - ProviderVec::iterator it = _providers.begin(); - for (; it != _providers.end(); ++it) { - SGPath path = (*it)->resolve(aResource, aContext); + for (auto provider : _providers) { + SGPath path = provider->resolve(aResource, aContext); if (!path.isNull()) { return path; } diff --git a/simgear/misc/ResourceManager.hxx b/simgear/misc/ResourceManager.hxx index bfaa5310..a15aaf15 100644 --- a/simgear/misc/ResourceManager.hxx +++ b/simgear/misc/ResourceManager.hxx @@ -36,6 +36,8 @@ class ResourceProvider; class ResourceManager { public: + ~ResourceManager(); + typedef enum { PRIORITY_DEFAULT = 0, PRIORITY_FALLBACK = -100, @@ -55,6 +57,8 @@ public: */ void addProvider(ResourceProvider* aProvider); + void removeProvider(ResourceProvider* aProvider); + /** * given a resource name (or path), find the appropriate real resource * path. @@ -75,17 +79,19 @@ class ResourceProvider public: virtual SGPath resolve(const std::string& aResource, SGPath& aContext) const = 0; - virtual int priority() const + virtual ~ResourceProvider(); + + virtual ResourceManager::Priority priority() const { return _priority; } protected: - ResourceProvider(int aPriority) : + ResourceProvider(ResourceManager::Priority aPriority) : _priority(aPriority) {} - int _priority; + ResourceManager::Priority _priority = ResourceManager::PRIORITY_DEFAULT; }; } // of simgear namespace