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
@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

37
src/Magnum/AbstractResourceLoader.h

@ -130,10 +130,17 @@ template<class T> class AbstractResourceLoader {
/**
* @brief Set loaded resource to resource manager
*
* Also increments count of loaded resources. Parameter @p state must
* be either @ref ResourceDataState::Mutable or
* @ref ResourceDataState::Final. See @ref ResourceManager::set() for
* If @p data is @cpp nullptr @ce and @p state is
* @ref ResourceDataState::NotFound, increments count of not found
* resources. Otherwise, if @p data is not @cpp nullptr @ce, increments
* count of loaded resources. See @ref ResourceManager::set() for
* 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()
*/
void set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy);
@ -144,7 +151,7 @@ template<class T> class AbstractResourceLoader {
}
/** @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);
}
@ -164,18 +171,21 @@ template<class T> class AbstractResourceLoader {
}
/** @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)));
}
/**
* @brief Mark resource as not found
*
* Also increments count of not found resources. See also
* @ref ResourceManager::set() for more information.
* A convenience function calling @ref set() with @cpp nullptr @ce
* and @ref ResourceDataState::NotFound.
* @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
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) {
CORRADE_ASSERT(state == ResourceDataState::Mutable || state == ResourceDataState::Final,
"AbstractResourceLoader::set(): state must be either Mutable or Final", );
++_loadedCount;
if(data) ++_loadedCount;
if(!data && state == ResourceDataState::NotFound) ++_notFoundCount;
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

50
src/Magnum/Test/ResourceManagerTest.cpp

@ -44,7 +44,9 @@ struct ResourceManagerTest: TestSuite::Tester {
void defaults();
void clear();
void clearWhileReferenced();
void loader();
void loaderSetNullptr();
void debugResourceState();
};
@ -71,7 +73,9 @@ ResourceManagerTest::ResourceManagerTest() {
&ResourceManagerTest::defaults,
&ResourceManagerTest::clear,
&ResourceManagerTest::clearWhileReferenced,
&ResourceManagerTest::loader,
&ResourceManagerTest::loaderSetNullptr,
&ResourceManagerTest::debugResourceState});
}
@ -333,6 +337,52 @@ void ResourceManagerTest::loader() {
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() {
std::ostringstream out;
Debug{&out} << ResourceState::Loading << ResourceState(0xbe);

Loading…
Cancel
Save