diff options
| -rw-r--r-- | src/crepe/Resource.h | 3 | ||||
| -rw-r--r-- | src/crepe/api/Asset.cpp | 4 | ||||
| -rw-r--r-- | src/crepe/api/Asset.h | 7 | ||||
| -rw-r--r-- | src/crepe/api/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/crepe/api/ResourceManager.cpp | 27 | ||||
| -rw-r--r-- | src/crepe/api/ResourceManager.h | 4 | ||||
| -rw-r--r-- | src/crepe/api/ResourceManager.hpp | 27 | ||||
| -rw-r--r-- | src/crepe/facade/Sound.cpp | 5 | ||||
| -rw-r--r-- | src/crepe/facade/Sound.h | 2 | ||||
| -rw-r--r-- | src/crepe/util/OptionalRef.hpp | 2 | ||||
| -rw-r--r-- | src/test/OptionalRefTest.cpp | 24 | ||||
| -rw-r--r-- | src/test/ResourceManagerTest.cpp | 36 | ||||
| -rw-r--r-- | src/test/main.cpp | 15 | 
13 files changed, 109 insertions, 48 deletions
| diff --git a/src/crepe/Resource.h b/src/crepe/Resource.h index 95b4d06..a0c8859 100644 --- a/src/crepe/Resource.h +++ b/src/crepe/Resource.h @@ -1,7 +1,5 @@  #pragma once -#include <memory> -  namespace crepe {  class ResourceManager; @@ -14,6 +12,7 @@ class Asset;  class Resource {  public:  	Resource(const Asset & src); +	virtual ~Resource() = default;  private:  	/** diff --git a/src/crepe/api/Asset.cpp b/src/crepe/api/Asset.cpp index 1887814..5271cf7 100644 --- a/src/crepe/api/Asset.cpp +++ b/src/crepe/api/Asset.cpp @@ -48,6 +48,10 @@ string Asset::whereami() const noexcept {  	return path;  } +bool Asset::operator==(const Asset & other) const noexcept { +	return this->src == other.src; +} +  size_t std::hash<const Asset>::operator()(const Asset & asset) const noexcept {  	return std::hash<string>{}(asset.get_path());  }; diff --git a/src/crepe/api/Asset.h b/src/crepe/api/Asset.h index 0f6b0b3..05dccba 100644 --- a/src/crepe/api/Asset.h +++ b/src/crepe/api/Asset.h @@ -29,6 +29,13 @@ public:  	 */  	const std::string & get_path() const noexcept; +	/** +	 * \brief Comparison operator +	 * \param other Possibly different instance of \c Asset to test equality against +	 * \return True if \c this and \c other are equal +	 */ +	bool operator == (const Asset & other) const noexcept; +  private:  	//! path to asset  	const std::string src; diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt index 70f1527..b452f37 100644 --- a/src/crepe/api/CMakeLists.txt +++ b/src/crepe/api/CMakeLists.txt @@ -37,7 +37,6 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES  	Color.h  	Texture.h   	ResourceManager.h  -	ResourceManager.hpp  	SaveManager.h  	Scene.h  	Metadata.h diff --git a/src/crepe/api/ResourceManager.cpp b/src/crepe/api/ResourceManager.cpp index 6eb4afd..7877ed9 100644 --- a/src/crepe/api/ResourceManager.cpp +++ b/src/crepe/api/ResourceManager.cpp @@ -1,11 +1,11 @@ +#include <stdexcept> +  #include "util/Log.h"  #include "ResourceManager.h" -// default resource cache functions -#include "../facade/Sound.h" -  using namespace crepe; +using namespace std;  ResourceManager & ResourceManager::get_instance() {  	static ResourceManager instance; @@ -19,8 +19,23 @@ void ResourceManager::clear() {  	this->resources.clear();  } -template <> -Sound & ResourceManager::cache<Sound>(const Asset & asset) { -	return this->cache<Sound>(asset); +template <typename T> +T & ResourceManager::cache(const Asset & asset) { +	dbg_trace(); +	static_assert(is_base_of<Resource, T>::value, "cache must recieve a derivative class of Resource"); + +	if (!this->resources.contains(asset)) +		this->resources[asset] = make_unique<T>(asset); + +	Resource * resource = this->resources.at(asset).get(); +	T * concrete_resource = dynamic_cast<T *>(resource); + +	if (concrete_resource == nullptr) +		throw runtime_error(format("ResourceManager: mismatch between requested type and actual type of resource ({})", asset.get_path())); + +	return *concrete_resource;  } +#include "../facade/Sound.h" +template Sound & ResourceManager::cache(const Asset &); + diff --git a/src/crepe/api/ResourceManager.h b/src/crepe/api/ResourceManager.h index 468af16..efdd5c5 100644 --- a/src/crepe/api/ResourceManager.h +++ b/src/crepe/api/ResourceManager.h @@ -65,9 +65,5 @@ public:  	void clear();  }; -template <> -Sound & ResourceManager::cache<Sound>(const Asset & asset); -  } // namespace crepe -#include "ResourceManager.hpp" diff --git a/src/crepe/api/ResourceManager.hpp b/src/crepe/api/ResourceManager.hpp deleted file mode 100644 index 62cac20..0000000 --- a/src/crepe/api/ResourceManager.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include <stdexcept> -#include <format> - -#include "ResourceManager.h" - -namespace crepe { - -template <typename T> -T & ResourceManager::cache(const Asset & asset) { -	using namespace std; -	static_assert(is_base_of<Resource, T>::value, "cache must recieve a derivative class of Resource"); - -	if (!this->resources.contains(asset)) -		this->resources[asset] = make_unique<T>(asset); - -	Resource * resource = this->resources.at(asset).get(); -	T * concrete_resource = dynamic_cast<T *>(resource); - -	if (concrete_resource == nullptr) -		throw runtime_error(format("ResourceManager: mismatch between requested type and actual type of resource ({})", asset.get_path())); - -	return *concrete_resource; -} - -} // namespace crepe diff --git a/src/crepe/facade/Sound.cpp b/src/crepe/facade/Sound.cpp index 4eefcda..b589759 100644 --- a/src/crepe/facade/Sound.cpp +++ b/src/crepe/facade/Sound.cpp @@ -11,6 +11,7 @@ Sound::Sound(const Asset & src) : Resource(src) {  	this->sample.load(src.get_path().c_str());  	dbg_trace();  } +Sound::~Sound() { dbg_trace(); }  void Sound::play() {  	SoundContext & ctx = this->context.get(); @@ -52,3 +53,7 @@ void Sound::set_looping(bool looping) {  	ctx.engine.setLooping(this->handle, this->looping);  } +void Sound::set_context(SoundContext & ctx) { +	this->context = ctx; +} + diff --git a/src/crepe/facade/Sound.h b/src/crepe/facade/Sound.h index 6f8462a..94b1996 100644 --- a/src/crepe/facade/Sound.h +++ b/src/crepe/facade/Sound.h @@ -1,6 +1,5 @@  #pragma once -#include <memory>  #include <soloud/soloud.h>  #include <soloud/soloud_wav.h> @@ -20,6 +19,7 @@ class SoundContext;  class Sound : public Resource {  public:  	Sound(const Asset & src); +	~Sound(); // dbg_trace  	/**  	 * \brief Pause this sample  	 * diff --git a/src/crepe/util/OptionalRef.hpp b/src/crepe/util/OptionalRef.hpp index e603a25..7b201b0 100644 --- a/src/crepe/util/OptionalRef.hpp +++ b/src/crepe/util/OptionalRef.hpp @@ -60,7 +60,7 @@ OptionalRef<T> & OptionalRef<T>::operator=(T & ref) {  template <typename T>  OptionalRef<T>::operator bool() const noexcept { -	return this->ref == nullptr; +	return this->ref != nullptr;  }  } diff --git a/src/test/OptionalRefTest.cpp b/src/test/OptionalRefTest.cpp index 65bd816..219ccca 100644 --- a/src/test/OptionalRefTest.cpp +++ b/src/test/OptionalRefTest.cpp @@ -9,8 +9,30 @@ using namespace testing;  TEST(OptionalRefTest, Explicit) {  	string value = "foo";  	OptionalRef<string> ref; +	EXPECT_FALSE(ref); +	ASSERT_THROW(ref.get(), runtime_error); + +	ref.set(value); +	EXPECT_TRUE(ref); +	ASSERT_NO_THROW(ref.get()); + +	ref.clear(); +	EXPECT_FALSE(ref); +	ASSERT_THROW(ref.get(), runtime_error); +} + +TEST(OptionalRefTest, Implicit) { +	string value = "foo"; +	OptionalRef<string> ref = value; +	EXPECT_TRUE(ref); +	ASSERT_NO_THROW(ref.get()); -	EXPECT_FALSE(bool(ref)); +	ref.clear(); +	EXPECT_FALSE(ref);  	ASSERT_THROW(ref.get(), runtime_error); + +	ref = value; +	EXPECT_TRUE(ref); +	ASSERT_NO_THROW(ref.get());  } diff --git a/src/test/ResourceManagerTest.cpp b/src/test/ResourceManagerTest.cpp index 42b6b5d..5d1ae7a 100644 --- a/src/test/ResourceManagerTest.cpp +++ b/src/test/ResourceManagerTest.cpp @@ -1,5 +1,7 @@  #include <gtest/gtest.h> +#include <crepe/util/Log.h> +#include <crepe/api/Config.h>  #include <crepe/api/ResourceManager.h>  using namespace std; @@ -8,14 +10,42 @@ using namespace testing;  class ResourceManagerTest : public Test {  public: -	ResourceManager & manager = ResourceManager::get_instance(); +	ResourceManager & resman = ResourceManager::get_instance(); +	Config & cfg = Config::get_instance();  	void SetUp() override { -		this->manager.clear(); +		cfg.log.level = Log::Level::TRACE; +		resman.clear();  	}  };  TEST_F(ResourceManagerTest, Main) { -	Sound & sound = this->manager.cache<Sound>("mwe/audio/sfx1.wav"); +	Asset path1 = "mwe/audio/sfx1.wav"; +	Asset path2 = "mwe/audio/sfx1.wav"; +	ASSERT_EQ(path1, path2); + +	Sound * ptr1 = nullptr; +	Sound * ptr2 = nullptr; +	{ +		Log::logf(Log::Level::DEBUG, "Get first sound (constructor call)"); +		Sound & sound = resman.cache<Sound>(path1); +		ptr1 = &sound; +	} +	{ +		Log::logf(Log::Level::DEBUG, "Get same sound (NO constructor call)"); +		Sound & sound = resman.cache<Sound>(path2); +		ptr2 = &sound; +	} +	EXPECT_EQ(ptr1, ptr2); + +	Log::logf(Log::Level::DEBUG, "Clear cache (destructor call)"); +	resman.clear(); + +	Log::logf(Log::Level::DEBUG, "Get first sound again (constructor call)"); +	Sound & sound = resman.cache<Sound>(path1); + +	// NOTE: there is no way (that I know of) to ensure the above statement +	// allocates the new Sound instance in a different location than the first, +	// so this test was verified using the above print statements.  } diff --git a/src/test/main.cpp b/src/test/main.cpp index 241015d..19a8d6e 100644 --- a/src/test/main.cpp +++ b/src/test/main.cpp @@ -5,11 +5,22 @@  using namespace crepe;  using namespace testing; +class GlobalConfigReset : public EmptyTestEventListener { +public: +	Config & cfg = Config::get_instance(); + +	// This function is called before each test +	void OnTestStart(const TestInfo &) override { +		cfg.log.level = Log::Level::WARNING; +	} +}; +  int main(int argc, char ** argv) {  	InitGoogleTest(&argc, argv); -	auto & cfg = Config::get_instance(); -	cfg.log.level = Log::Level::ERROR; +	UnitTest & ut = *UnitTest::GetInstance(); +	ut.listeners().Append(new GlobalConfigReset);  	return RUN_ALL_TESTS();  } + |