diff --git a/src/AbstractResourceLoader.h b/src/AbstractResourceLoader.h index ee222d335..64fcbc8c2 100644 --- a/src/AbstractResourceLoader.h +++ b/src/AbstractResourceLoader.h @@ -47,39 +47,34 @@ each call to ResourceManager::get() will call load() implementation unless the resource is already loaded (or loading is in progress). Note that resources requested before the loader was added are not be affected by the loader. -Subclassing is done by implementing at least load() function. The loading can +Subclassing is done by implementing at least doLoad() function. The loading can be done synchronously or asynchronously (i.e., in another thread). The base implementation provides interface to ResourceManager and manages loading progress (which is then available through functions requestedCount(), loadedCount() and notFoundCount()). You shouldn't access the ResourceManager directly when loading the data. -Your load() implementation must call the base implementation at the beginning -so ResourceManager is informed about loading state. Then, after your resources -are loaded, call set() to pass them to ResourceManager or call setNotFound() -to indicate that the resource was not found. +In your doLoad() implementation, after your resources are loaded, call set() to +pass them to ResourceManager or call setNotFound() to indicate that the +resource was not found. You can also implement name() to provide meaningful names for resource keys. Example implementation for synchronous mesh loader: @code class MeshResourceLoader: public AbstractResourceLoader { - public: - void load(ResourceKey key) { - // Indicate that loading has begun - AbstractResourceLoader::load(key); - - // Load the mesh... - - // Not found - if(!found) { - setNotFound(key); - return; - } + void doLoad(ResourceKey key) override { + // Load the mesh... - // Found, pass it to resource manager - set(key, mesh, state, policy); + // Not found + if(!found) { + setNotFound(key); + return; } + + // Found, pass it to resource manager + set(key, mesh, state, policy); + } }; @endcode @@ -132,9 +127,9 @@ template class AbstractResourceLoader { * @brief %Resource name corresponding to given key * * If no such resource exists or the resource name is not available, - * returns empty string. Default implementation returns empty string. + * returns empty string. */ - virtual std::string name(ResourceKey key) const; + std::string name(ResourceKey key) const { return doName(key); } /** * @brief Request resource to be loaded @@ -144,12 +139,10 @@ template class AbstractResourceLoader { * requested features is incremented. Depending on implementation the * resource might be loaded synchronously or asynchronously. * - * See class documentation for reimplementation guide. - * * @see ResourceManager::state(), requestedCount(), notFoundCount(), * loadedCount() */ - virtual void load(ResourceKey key) = 0; + void load(ResourceKey key); protected: /** @@ -172,6 +165,25 @@ template class AbstractResourceLoader { */ void setNotFound(ResourceKey key); + #ifndef DOXYGEN_GENERATING_OUTPUT + private: + #else + protected: + #endif + /** + * @brief Implementation for name() + * + * Default implementation returns empty string. + */ + virtual std::string doName(ResourceKey key) const; + + /** + * @brief Implementation for load() + * + * See class documentation for reimplementation guide. + */ + virtual void doLoad(ResourceKey key) = 0; + private: Implementation::ResourceManagerData* manager; std::size_t _requestedCount; @@ -183,12 +195,14 @@ template AbstractResourceLoader::~AbstractResourceLoader() { if(manager) manager->_loader = nullptr; } -template std::string AbstractResourceLoader::name(ResourceKey) const { return {}; } +template std::string AbstractResourceLoader::doName(ResourceKey) const { return {}; } template void AbstractResourceLoader::load(ResourceKey key) { ++_requestedCount; /** @todo What policy for loading resources? */ manager->set(key, nullptr, ResourceDataState::Loading, ResourcePolicy::Resident); + + doLoad(key); } template void AbstractResourceLoader::set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy) { diff --git a/src/Test/ResourceManagerTest.cpp b/src/Test/ResourceManagerTest.cpp index a99956e6b..8235d2328 100644 --- a/src/Test/ResourceManagerTest.cpp +++ b/src/Test/ResourceManagerTest.cpp @@ -56,18 +56,6 @@ class Data { typedef Magnum::ResourceManager ResourceManager; -class IntResourceLoader: public AbstractResourceLoader { - public: - void load(ResourceKey key) override { - AbstractResourceLoader::load(key); - } - - void load() { - set("hello", new Int(773), ResourceDataState::Final, ResourcePolicy::Resident); - setNotFound("world"); - } -}; - size_t Data::count = 0; ResourceManagerTest::ResourceManagerTest() { @@ -239,18 +227,30 @@ void ResourceManagerTest::manualPolicy() { } void ResourceManagerTest::loader() { - ResourceManager rm; - IntResourceLoader loader; - rm.setLoader(&loader); + class IntResourceLoader: public AbstractResourceLoader { + public: - Resource data = rm.get("data"); - Resource hello = rm.get("hello"); - Resource world = rm.get("world"); + void load() { + set("hello", new Int(773), ResourceDataState::Final, ResourcePolicy::Resident); + setNotFound("world"); + } + + private: + void doLoad(ResourceKey) override {} + }; + + auto rm = new ResourceManager; + auto loader = new IntResourceLoader; + rm->setLoader(loader); + + Resource data = rm->get("data"); + Resource hello = rm->get("hello"); + Resource world = rm->get("world"); CORRADE_COMPARE(data.state(), ResourceState::NotLoaded); CORRADE_COMPARE(hello.state(), ResourceState::Loading); CORRADE_COMPARE(world.state(), ResourceState::Loading); - loader.load(); + loader->load(); CORRADE_COMPARE(hello.state(), ResourceState::Final); CORRADE_COMPARE(*hello, 773); CORRADE_COMPARE(world.state(), ResourceState::NotFound);