Browse Source

Don't forbid setting resources by copy/move.

It adds much more convenience. Only some resources can't be moved around
(i.e. those with someone pointing at them), which isn't excuse for
forbidding copy/move altogether.

Finally it is possible to do convenient things like this again:

    DebugTools::ResourceManager::instance()->set("red",
        DebugTools::ShapeRendererOptions().setColor({1.0f, 0.0f, 0.0f}));
pull/23/head
Vladimír Vondruš 13 years ago
parent
commit
68638969f3
  1. 10
      src/AbstractResourceLoader.h
  2. 17
      src/ResourceManager.h
  3. 15
      src/Test/ResourceManagerTest.cpp

10
src/AbstractResourceLoader.h

@ -161,6 +161,11 @@ template<class T> class AbstractResourceLoader {
*/
void set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy);
/** @overload */
template<class U> void set(ResourceKey key, U&& data, ResourceDataState state, ResourcePolicy policy) {
set(key, new typename std::remove_cv<typename std::remove_reference<U>::type>::type(std::forward<U>(data)), state, policy);
}
/**
* @brief Set loaded resource to resource manager
*
@ -171,6 +176,11 @@ template<class T> class AbstractResourceLoader {
set(key, data, ResourceDataState::Final, ResourcePolicy::Resident);
}
/** @overload */
template<class U> void set(ResourceKey key, U&& data) {
set(key, new typename std::remove_cv<typename std::remove_reference<U>::type>::type(std::forward<U>(data)));
}
/**
* @brief Mark resource as not found
*

17
src/ResourceManager.h

@ -313,17 +313,27 @@ template<class... Types> class ResourceManager: private Implementation::Resource
return *this;
}
/** @overload */
template<class U> ResourceManager<Types...>& set(ResourceKey key, U&& data, ResourceDataState state, ResourcePolicy policy) {
return set(key, new typename std::remove_cv<typename std::remove_reference<U>::type>::type(std::forward<U>(data)), state, policy);
}
/**
* @brief Set resource data
* @return Reference to self (for method chaining)
*
* Same as above function with state set to @ref ResourceDataState "ResourceDataState::Final"
* Same as above with state set to @ref ResourceDataState "ResourceDataState::Final"
* and policy to @ref ResourcePolicy "ResourcePolicy::Resident".
*/
template<class T> ResourceManager<Types...>& set(ResourceKey key, T* data) {
return set(key, data, ResourceDataState::Final, ResourcePolicy::Resident);
}
/** @overload */
template<class U> ResourceManager<Types...>& set(ResourceKey key, U&& data) {
return set(key, new typename std::remove_cv<typename std::remove_reference<U>::type>::type(std::forward<U>(data)));
}
/** @brief Fallback for not found resources */
template<class T> T* fallback() {
return this->Implementation::ResourceManagerData<T>::fallback();
@ -343,6 +353,11 @@ template<class... Types> class ResourceManager: private Implementation::Resource
return *this;
}
/** @overload */
template<class U> ResourceManager<Types...>& setFallback(U&& data) {
return setFallback(new typename std::remove_cv<typename std::remove_reference<U>::type>::type(std::forward<U>(data)));
}
/**
* @brief Free all resources of given type which are not referenced
* @return Reference to self (for method chaining)

15
src/Test/ResourceManagerTest.cpp

@ -129,8 +129,7 @@ void ResourceManagerTest::stateDisallowed() {
std::ostringstream out;
Error::setOutput(&out);
Data d;
rm.set("data", &d, ResourceDataState::Loading, ResourcePolicy::Resident);
rm.set("data", Data(), ResourceDataState::Loading, ResourcePolicy::Resident);
CORRADE_COMPARE(out.str(), "ResourceManager::set(): data should be null if and only if state is NotFound or Loading\n");
out.str({});
@ -144,8 +143,8 @@ void ResourceManagerTest::basic() {
/* One mutable, one final */
ResourceKey questionKey("the-question");
ResourceKey answerKey("the-answer");
rm.set(questionKey, new Int(10), ResourceDataState::Mutable, ResourcePolicy::Resident);
rm.set(answerKey, new Int(42), ResourceDataState::Final, ResourcePolicy::Resident);
rm.set(questionKey, 10, ResourceDataState::Mutable, ResourcePolicy::Resident);
rm.set(answerKey, 42, ResourceDataState::Final, ResourcePolicy::Resident);
Resource<Int> theQuestion = rm.get<Int>(questionKey);
Resource<Int> theAnswer = rm.get<Int>(answerKey);
@ -159,12 +158,12 @@ void ResourceManagerTest::basic() {
/* Cannot change already final resource */
std::ostringstream out;
Error::setOutput(&out);
rm.set(answerKey, new Int(43), ResourceDataState::Mutable, ResourcePolicy::Resident);
rm.set(answerKey, 43, ResourceDataState::Mutable, ResourcePolicy::Resident);
CORRADE_COMPARE(*theAnswer, 42);
CORRADE_COMPARE(out.str(), "ResourceManager::set(): cannot change already final resource " + answerKey.hexString() + '\n');
/* But non-final can be changed */
rm.set(questionKey, new Int(20), ResourceDataState::Final, ResourcePolicy::Resident);
rm.set(questionKey, 20, ResourceDataState::Final, ResourcePolicy::Resident);
CORRADE_COMPARE(theQuestion.state(), ResourceState::Final);
CORRADE_COMPARE(*theQuestion, 20);
}
@ -250,7 +249,7 @@ void ResourceManagerTest::clearWhileReferenced() {
Error::setOutput(&out);
ResourceManager rm;
rm.set("blah", new Int);
rm.set("blah", Int());
/** @todo this will leak, is there any better solution without hitting
assertion in decrementReferenceCount()? */
new Resource<Int>(rm.get<Int>("blah"));
@ -265,7 +264,7 @@ void ResourceManagerTest::loader() {
IntResourceLoader(): resource(ResourceManager::instance().get<Data>("data")) {}
void load() {
set("hello", new Int(773), ResourceDataState::Final, ResourcePolicy::Resident);
set("hello", 773, ResourceDataState::Final, ResourcePolicy::Resident);
setNotFound("world");
}

Loading…
Cancel
Save