Browse Source

Accept nullptr in AbstractResourceLoader::set().

Also implement setNotFound() using set() and make the code more
flexible.
pull/338/head
Vladimír Vondruš 7 years ago
parent
commit
eccebcbdd7
  1. 3
      doc/changelog.dox
  2. 37
      src/Magnum/AbstractResourceLoader.h
  3. 50
      src/Magnum/Test/ResourceManagerTest.cpp

3
doc/changelog.dox

@ -139,6 +139,9 @@ See also:
- The @ref ResourceManager class now accepts also - The @ref ResourceManager class now accepts also
@ref Corrade::Containers::Pointer instances in addition to raw pointers @ref Corrade::Containers::Pointer instances in addition to raw pointers
- The @ref AbstractResourceLoader::set() function now accepts also
@cpp nullptr @ce for explicitly setting @ref ResourceDataState::Loading or
@ref ResourceDataState::NotFound resources
@subsubsection changelog-latest-changes-animation Animation library @subsubsection changelog-latest-changes-animation Animation library

37
src/Magnum/AbstractResourceLoader.h

@ -130,10 +130,17 @@ template<class T> class AbstractResourceLoader {
/** /**
* @brief Set loaded resource to resource manager * @brief Set loaded resource to resource manager
* *
* Also increments count of loaded resources. Parameter @p state must * If @p data is @cpp nullptr @ce and @p state is
* be either @ref ResourceDataState::Mutable or * @ref ResourceDataState::NotFound, increments count of not found
* @ref ResourceDataState::Final. See @ref ResourceManager::set() for * resources. Otherwise, if @p data is not @cpp nullptr @ce, increments
* count of loaded resources. See @ref ResourceManager::set() for
* more information. * more information.
*
* Note that resource's state is automatically set to
* @ref ResourceDataState::Loading when it is requested from
* @ref ResourceManager and it's not loaded yet, so it's not needed to
* call this function. For marking a resource as not found you can also
* use the convenience @ref setNotFound() variant.
* @see @ref loadedCount() * @see @ref loadedCount()
*/ */
void set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy); void set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy);
@ -144,7 +151,7 @@ template<class T> class AbstractResourceLoader {
} }
/** @overload */ /** @overload */
template<class U> void set(ResourceKey key, U&& data, ResourceDataState state, ResourcePolicy policy) { template<class U, class = typename std::enable_if<!std::is_same<typename std::decay<U>::type, std::nullptr_t>::value>::type> void set(ResourceKey key, U&& data, ResourceDataState state, ResourcePolicy policy) {
set(key, new typename std::decay<U>::type(std::forward<U>(data)), state, policy); set(key, new typename std::decay<U>::type(std::forward<U>(data)), state, policy);
} }
@ -164,18 +171,21 @@ template<class T> class AbstractResourceLoader {
} }
/** @overload */ /** @overload */
template<class U> void set(ResourceKey key, U&& data) { template<class U, class = typename std::enable_if<!std::is_same<typename std::decay<U>::type, std::nullptr_t>::value>::type> void set(ResourceKey key, U&& data) {
set(key, new typename std::decay<U>::type(std::forward<U>(data))); set(key, new typename std::decay<U>::type(std::forward<U>(data)));
} }
/** /**
* @brief Mark resource as not found * @brief Mark resource as not found
* *
* Also increments count of not found resources. See also * A convenience function calling @ref set() with @cpp nullptr @ce
* @ref ResourceManager::set() for more information. * and @ref ResourceDataState::NotFound.
* @see @ref notFoundCount() * @see @ref notFoundCount()
*/ */
void setNotFound(ResourceKey key); void setNotFound(ResourceKey key) {
/** @todo What policy for notfound resources? */
set(key, nullptr, ResourceDataState::NotFound, ResourcePolicy::Resident);
}
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
private: private:
@ -222,18 +232,11 @@ template<class T> void AbstractResourceLoader<T>::load(ResourceKey key) {
} }
template<class T> void AbstractResourceLoader<T>::set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy) { template<class T> void AbstractResourceLoader<T>::set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy) {
CORRADE_ASSERT(state == ResourceDataState::Mutable || state == ResourceDataState::Final, if(data) ++_loadedCount;
"AbstractResourceLoader::set(): state must be either Mutable or Final", ); if(!data && state == ResourceDataState::NotFound) ++_notFoundCount;
++_loadedCount;
manager->set(key, data, state, policy); manager->set(key, data, state, policy);
} }
template<class T> inline void AbstractResourceLoader<T>::setNotFound(ResourceKey key) {
++_notFoundCount;
/** @todo What policy for notfound resources? */
manager->set(key, nullptr, ResourceDataState::NotFound, ResourcePolicy::Resident);
}
} }
#endif #endif

50
src/Magnum/Test/ResourceManagerTest.cpp

@ -44,7 +44,9 @@ struct ResourceManagerTest: TestSuite::Tester {
void defaults(); void defaults();
void clear(); void clear();
void clearWhileReferenced(); void clearWhileReferenced();
void loader(); void loader();
void loaderSetNullptr();
void debugResourceState(); void debugResourceState();
}; };
@ -71,7 +73,9 @@ ResourceManagerTest::ResourceManagerTest() {
&ResourceManagerTest::defaults, &ResourceManagerTest::defaults,
&ResourceManagerTest::clear, &ResourceManagerTest::clear,
&ResourceManagerTest::clearWhileReferenced, &ResourceManagerTest::clearWhileReferenced,
&ResourceManagerTest::loader, &ResourceManagerTest::loader,
&ResourceManagerTest::loaderSetNullptr,
&ResourceManagerTest::debugResourceState}); &ResourceManagerTest::debugResourceState});
} }
@ -333,6 +337,52 @@ void ResourceManagerTest::loader() {
CORRADE_COMPARE(Data::count, 0); CORRADE_COMPARE(Data::count, 0);
} }
void ResourceManagerTest::loaderSetNullptr() {
class IntResourceLoader: public AbstractResourceLoader<Int> {
public:
void load() {
set("hello", 1337, ResourceDataState::Final, ResourcePolicy::Resident);
set("world", 42, ResourceDataState::Final, ResourcePolicy::Resident);
}
private:
void doLoad(ResourceKey key) override {
/* Verify that calling load() with nullptr + Loading works */
set(key, nullptr, ResourceDataState::Loading, ResourcePolicy::Resident);
set("world", nullptr, ResourceDataState::Loading, ResourcePolicy::Resident);
}
};
ResourceManager rm;
Containers::Pointer<IntResourceLoader> loaderPtr{Containers::InPlaceInit};
IntResourceLoader& loader = *loaderPtr;
rm.setLoader<Int>(std::move(loaderPtr));
CORRADE_COMPARE(rm.state<Int>("hello"), ResourceState::NotLoaded);
CORRADE_COMPARE(rm.state<Int>("world"), ResourceState::NotLoaded);
/* Loading "hello" triggers a load of "world" as well */
Resource<Int> hello = rm.get<Int>("hello");
CORRADE_COMPARE(hello.state(), ResourceState::Loading);
CORRADE_COMPARE(rm.state<Int>("world"), ResourceState::Loading);
CORRADE_COMPARE(loader.requestedCount(), 1);
CORRADE_COMPARE(loader.loadedCount(), 0);
CORRADE_COMPARE(loader.notFoundCount(), 0);
/* Load the things */
loader.load();
CORRADE_COMPARE(hello.state(), ResourceState::Final);
CORRADE_COMPARE(*hello, 1337);
CORRADE_COMPARE(loader.requestedCount(), 1);
CORRADE_COMPARE(loader.loadedCount(), 2);
CORRADE_COMPARE(loader.notFoundCount(), 0);
/* World is now loaded as well as a side-effect */
Resource<Int> world = rm.get<Int>("world");
CORRADE_COMPARE(world.state(), ResourceState::Final);
CORRADE_COMPARE(*world, 42);
}
void ResourceManagerTest::debugResourceState() { void ResourceManagerTest::debugResourceState() {
std::ostringstream out; std::ostringstream out;
Debug{&out} << ResourceState::Loading << ResourceState(0xbe); Debug{&out} << ResourceState::Loading << ResourceState(0xbe);

Loading…
Cancel
Save