diff options
-rw-r--r-- | src/crepe/Asset.cpp | 18 | ||||
-rw-r--r-- | src/crepe/Asset.h | 2 | ||||
-rw-r--r-- | src/crepe/Component.h | 2 | ||||
-rw-r--r-- | src/crepe/Resource.h | 33 | ||||
-rw-r--r-- | src/crepe/api/AudioSource.cpp | 21 | ||||
-rw-r--r-- | src/crepe/api/AudioSource.h | 34 | ||||
-rw-r--r-- | src/crepe/facade/Sound.cpp | 30 | ||||
-rw-r--r-- | src/crepe/facade/Sound.h | 14 | ||||
-rw-r--r-- | src/crepe/facade/SoundContext.cpp | 5 | ||||
-rw-r--r-- | src/crepe/facade/SoundContext.h | 5 | ||||
-rw-r--r-- | src/crepe/system/AudioSystem.cpp | 22 | ||||
-rw-r--r-- | src/crepe/system/AudioSystem.h | 19 | ||||
-rw-r--r-- | src/crepe/system/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/crepe/system/ScriptSystem.cpp | 3 | ||||
-rw-r--r-- | src/crepe/system/System.cpp | 7 | ||||
-rw-r--r-- | src/crepe/system/System.h | 10 | ||||
-rw-r--r-- | src/test/AudioTest.cpp | 24 | ||||
-rw-r--r-- | src/test/CMakeLists.txt | 5 | ||||
-rw-r--r-- | src/test/audio.cpp | 10 | ||||
-rw-r--r-- | src/test/dummy.cpp | 3 |
20 files changed, 188 insertions, 82 deletions
diff --git a/src/crepe/Asset.cpp b/src/crepe/Asset.cpp index 8a2a11c..3d4df53 100644 --- a/src/crepe/Asset.cpp +++ b/src/crepe/Asset.cpp @@ -1,16 +1,20 @@ #include <filesystem> #include "Asset.h" +#include "Exception.h" using namespace crepe; +using namespace std; -Asset::Asset(const std::string & src) { - // FIXME: restore this - // this->src = std::filesystem::canonical(src); - this->src = src; - this->file = std::ifstream(this->src, std::ios::in | std::ios::binary); +Asset::Asset(const string & src) : src(src) { + try { + this->src = filesystem::canonical(src); + } catch (filesystem::filesystem_error & e) { + throw Exception("Asset error: %s", e.what()); + } + this->file = ifstream(this->src, ios::in | ios::binary); } -const std::istream & Asset::read() { return this->file; } +const istream & Asset::read() { return this->file; } -const char * Asset::canonical() { return this->src.c_str(); } +const char * Asset::canonical() const { return this->src.c_str(); } diff --git a/src/crepe/Asset.h b/src/crepe/Asset.h index 0cb5834..d4e4ba1 100644 --- a/src/crepe/Asset.h +++ b/src/crepe/Asset.h @@ -23,7 +23,7 @@ public: //! Get an input stream to the contents of this resource const std::istream & read(); //! Get the canonical path to this resource - const char * canonical(); + const char * canonical() const; private: std::string src; diff --git a/src/crepe/Component.h b/src/crepe/Component.h index 0fe60b2..e8d18d9 100644 --- a/src/crepe/Component.h +++ b/src/crepe/Component.h @@ -2,8 +2,6 @@ #include "types.h" -#include <cstdint> - namespace crepe { class ComponentManager; diff --git a/src/crepe/Resource.h b/src/crepe/Resource.h new file mode 100644 index 0000000..dcf3dbd --- /dev/null +++ b/src/crepe/Resource.h @@ -0,0 +1,33 @@ +#pragma once + +#include <memory> + +namespace crepe { + +class ResourceManager; +class Asset; + +/** + * Resource is an interface class used to represent a (deserialized) game + * resource (e.g. textures, sounds). + */ +class Resource { +private: + /** + * \brief Prototype pattern clone function. + * + * \param src Source file of new resource (abstraction for file saved on + * disk) + * + * \returns New instance of concrete resource + */ + virtual std::unique_ptr<Resource> clone(const Asset & src) const = 0; + /** + * The resource manager uses \c clone to create new instances of the concrete + * resource class. This may be used to inherit references to classes that + * would otherwise need to be implemented as singletons. + */ + friend class ResourceManager; +}; + +} // namespace crepe diff --git a/src/crepe/api/AudioSource.cpp b/src/crepe/api/AudioSource.cpp index 63fd0d7..b0cf28c 100644 --- a/src/crepe/api/AudioSource.cpp +++ b/src/crepe/api/AudioSource.cpp @@ -1,23 +1,22 @@ #include <memory> -#include "../facade/Sound.h" - #include "AudioSource.h" using namespace crepe; +using namespace std; -AudioSource::AudioSource(std::unique_ptr<Asset> audio_clip) { - this->sound = std::make_unique<crepe::Sound>(std::move(audio_clip)); -} - -void AudioSource::play() { return this->play(false); } +AudioSource::AudioSource(game_object_id_t id, unique_ptr<Asset> audio_clip) : + Component(id), + audio_clip(std::move(audio_clip)) +{ } void AudioSource::play(bool looping) { - this->sound->set_looping(looping); - this->sound->play(); + this->loop = looping; + this->playing = true; } void AudioSource::stop() { - this->sound->pause(); - this->sound->rewind(); + this->playing = false; + this->rewind = true; } + diff --git a/src/crepe/api/AudioSource.h b/src/crepe/api/AudioSource.h index 1e24ae8..5bc70f9 100644 --- a/src/crepe/api/AudioSource.h +++ b/src/crepe/api/AudioSource.h @@ -4,36 +4,48 @@ #include "../Asset.h" #include "../Component.h" +#include "../types.h" namespace crepe { -class Sound; - //! Audio source component class AudioSource : public Component { public: - AudioSource(std::unique_ptr<Asset> audio_clip); + AudioSource(game_object_id_t id, const Asset & source); virtual ~AudioSource() = default; public: //! Start or resume this audio source - void play(); - void play(bool looping); + void play(bool looping = false); //! Stop this audio source void stop(); public: //! Sample file location - std::unique_ptr<Asset> audio_clip; - //! TODO: ????? - bool play_on_awake; + const std::unique_ptr<Asset> audio_clip; + //! Play when this component becomes active + bool play_on_awake = false; //! Repeat the current audio clip during playback - bool loop; + bool loop = false; //! Normalized volume (0.0 - 1.0) - float volume; + float volume = 1.0; + +private: + //! If this source is playing audio + bool playing = false; + //! Rewind the sample location + bool rewind = false; private: - std::unique_ptr<Sound> sound; + //! Value of \c active after last system update + bool last_active = false; + //! Value of \c playing after last system update + bool last_playing = false; + //! Value of \c volume after last system update + float last_volume = 1.0; + //! Value of \c loop after last system update + bool last_loop = false; }; } // namespace crepe + diff --git a/src/crepe/facade/Sound.cpp b/src/crepe/facade/Sound.cpp index 648ec81..b8ea71a 100644 --- a/src/crepe/facade/Sound.cpp +++ b/src/crepe/facade/Sound.cpp @@ -1,26 +1,24 @@ +#include <memory> + +#include "../Asset.h" #include "../util/log.h" #include "Sound.h" #include "SoundContext.h" using namespace crepe; +using namespace std; -Sound::Sound(std::unique_ptr<Asset> res) { - dbg_trace(); - this->load(std::move(res)); -} - -Sound::Sound(const char * src) { - dbg_trace(); - this->load(std::make_unique<Asset>(src)); -} +Sound::Sound(SoundContext & ctx) : context(ctx) { dbg_trace(); } -void Sound::load(std::unique_ptr<Asset> res) { - this->sample.load(res->canonical()); +unique_ptr<Resource> Sound::clone(const Asset & src) const { + auto instance = make_unique<Sound>(*this); + instance->sample.load(src.canonical()); + return instance; } void Sound::play() { - SoundContext & ctx = SoundContext::get_instance(); + SoundContext & ctx = this->context; if (ctx.engine.getPause(this->handle)) { // resume if paused ctx.engine.setPause(this->handle, false); @@ -32,13 +30,13 @@ void Sound::play() { } void Sound::pause() { - SoundContext & ctx = SoundContext::get_instance(); + SoundContext & ctx = this->context; if (ctx.engine.getPause(this->handle)) return; ctx.engine.setPause(this->handle, true); } void Sound::rewind() { - SoundContext & ctx = SoundContext::get_instance(); + SoundContext & ctx = this->context; if (!ctx.engine.isValidVoiceHandle(this->handle)) return; ctx.engine.seek(this->handle, 0); } @@ -46,7 +44,7 @@ void Sound::rewind() { void Sound::set_volume(float volume) { this->volume = volume; - SoundContext & ctx = SoundContext::get_instance(); + SoundContext & ctx = this->context; if (!ctx.engine.isValidVoiceHandle(this->handle)) return; ctx.engine.setVolume(this->handle, this->volume); } @@ -54,7 +52,7 @@ void Sound::set_volume(float volume) { void Sound::set_looping(bool looping) { this->looping = looping; - SoundContext & ctx = SoundContext::get_instance(); + SoundContext & ctx = this->context; if (!ctx.engine.isValidVoiceHandle(this->handle)) return; ctx.engine.setLooping(this->handle, this->looping); } diff --git a/src/crepe/facade/Sound.h b/src/crepe/facade/Sound.h index 183bd7c..e5b2f19 100644 --- a/src/crepe/facade/Sound.h +++ b/src/crepe/facade/Sound.h @@ -4,11 +4,13 @@ #include <soloud/soloud.h> #include <soloud/soloud_wav.h> -#include "../Asset.h" +#include "../Resource.h" namespace crepe { -class Sound { +class SoundContext; + +class Sound : public Resource { public: /** * \brief Pause this sample @@ -64,15 +66,13 @@ public: bool get_looping() const { return this->looping; } public: - Sound(const char * src); - Sound(std::unique_ptr<Asset> res); - -private: - void load(std::unique_ptr<Asset> res); + Sound(SoundContext & ctx); + std::unique_ptr<Resource> clone(const Asset & src) const override; private: SoLoud::Wav sample; SoLoud::handle handle; + SoundContext & context; float volume = 1.0f; bool looping = false; diff --git a/src/crepe/facade/SoundContext.cpp b/src/crepe/facade/SoundContext.cpp index 5e5a3a9..b5f3db3 100644 --- a/src/crepe/facade/SoundContext.cpp +++ b/src/crepe/facade/SoundContext.cpp @@ -4,11 +4,6 @@ using namespace crepe; -SoundContext & SoundContext::get_instance() { - static SoundContext instance; - return instance; -} - SoundContext::SoundContext() { dbg_trace(); engine.init(); diff --git a/src/crepe/facade/SoundContext.h b/src/crepe/facade/SoundContext.h index d3123d2..8d9e396 100644 --- a/src/crepe/facade/SoundContext.h +++ b/src/crepe/facade/SoundContext.h @@ -7,12 +7,10 @@ namespace crepe { class SoundContext { -private: +public: SoundContext(); virtual ~SoundContext(); - // singleton - static SoundContext & get_instance(); SoundContext(const SoundContext &) = delete; SoundContext(SoundContext &&) = delete; SoundContext & operator=(const SoundContext &) = delete; @@ -20,6 +18,7 @@ private: private: SoLoud::Soloud engine; + //! Sound directly calls methods on \c engine friend class Sound; }; diff --git a/src/crepe/system/AudioSystem.cpp b/src/crepe/system/AudioSystem.cpp new file mode 100644 index 0000000..9fdd7eb --- /dev/null +++ b/src/crepe/system/AudioSystem.cpp @@ -0,0 +1,22 @@ +#include "AudioSystem.h" +#include "ComponentManager.h" + +#include "../api/AudioSource.h" + +using namespace crepe; +using namespace std; + +AudioSystem::AudioSystem(SoundContext & ctx) : ctx(ctx) {} + +void AudioSystem::update() { + vector<reference_wrapper<AudioSource>> components = this->compmgr.get_components_by_type<AudioSource>(); + + for (auto component_ref : components) { + AudioSource & component = component_ref.get(); + if (!component.active) continue; + + // TODO: fetch Sound instance from resourcemanager + // TODO: lots of state diffing + } +} + diff --git a/src/crepe/system/AudioSystem.h b/src/crepe/system/AudioSystem.h new file mode 100644 index 0000000..e037f51 --- /dev/null +++ b/src/crepe/system/AudioSystem.h @@ -0,0 +1,19 @@ +#pragma once + +#include "../facade/SoundContext.h" + +#include "System.h" + +namespace crepe { + +class AudioSystem : public System { +public: + using System::System; + void update() override; + +private: + SoundContext context {}; +}; + +} // namespace crepe + diff --git a/src/crepe/system/CMakeLists.txt b/src/crepe/system/CMakeLists.txt index 4c18b87..f507b90 100644 --- a/src/crepe/system/CMakeLists.txt +++ b/src/crepe/system/CMakeLists.txt @@ -1,9 +1,11 @@ target_sources(crepe PUBLIC + System.cpp ParticleSystem.cpp ScriptSystem.cpp PhysicsSystem.cpp CollisionSystem.cpp RenderSystem.cpp + AudioSystem.cpp AnimatorSystem.cpp ) @@ -13,5 +15,6 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES PhysicsSystem.h CollisionSystem.h RenderSystem.h + AudioSystem.h AnimatorSystem.h ) diff --git a/src/crepe/system/ScriptSystem.cpp b/src/crepe/system/ScriptSystem.cpp index f2673e7..68fbb02 100644 --- a/src/crepe/system/ScriptSystem.cpp +++ b/src/crepe/system/ScriptSystem.cpp @@ -22,9 +22,8 @@ void ScriptSystem::update() { forward_list<Script *> ScriptSystem::get_scripts() { forward_list<Script *> scripts = {}; - ComponentManager & mgr = ComponentManager::get_instance(); vector<reference_wrapper<BehaviorScript>> behavior_scripts - = mgr.get_components_by_type<BehaviorScript>(); + = this->compmgr.get_components_by_type<BehaviorScript>(); for (auto behavior_script_ref : behavior_scripts) { BehaviorScript & behavior_script = behavior_script_ref.get(); diff --git a/src/crepe/system/System.cpp b/src/crepe/system/System.cpp new file mode 100644 index 0000000..fa51d2f --- /dev/null +++ b/src/crepe/system/System.cpp @@ -0,0 +1,7 @@ +#include "System.h" + +using namespace crepe; + +// TODO: ComponentManager shouldn't be a singleton +System::System() : compmgr(ComponentManager::get_instance()) {} + diff --git a/src/crepe/system/System.h b/src/crepe/system/System.h index 3b81bef..5091977 100644 --- a/src/crepe/system/System.h +++ b/src/crepe/system/System.h @@ -1,14 +1,22 @@ #pragma once +#include "../ComponentManager.h" + namespace crepe { +//! ECS system base class class System { public: + //! Process components belonging to this system virtual void update() = 0; public: - System() = default; + System(); virtual ~System() = default; + +public: + //! Reference to component manager + ComponentManager & compmgr; }; } // namespace crepe diff --git a/src/test/AudioTest.cpp b/src/test/AudioTest.cpp new file mode 100644 index 0000000..a9d5e6c --- /dev/null +++ b/src/test/AudioTest.cpp @@ -0,0 +1,24 @@ +#include "system/AudioSystem.h" +#include <gtest/gtest.h> + +#include <crepe/ComponentManager.h> +#include <crepe/api/AudioSource.h> + +using namespace std; +using namespace crepe; +using namespace testing; + +class AudioTest : public Test { +public: + ComponentManager component_manager{}; + AudioSystem system {component_manager}; + + void SetUp() override { + auto & mgr = this->component_manager; + GameObject entity = mgr.new_object("name"); + } +}; + +TEST_F(AudioTest, Default) { +} + diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index acab388..f63a733 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -1,7 +1,6 @@ target_sources(test_main PUBLIC - dummy.cpp - # audio.cpp # PhysicsTest.cpp - ParticleTest.cpp + # ParticleTest.cpp + AudioTest.cpp ) diff --git a/src/test/audio.cpp b/src/test/audio.cpp deleted file mode 100644 index d6ff689..0000000 --- a/src/test/audio.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include <gtest/gtest.h> - -using namespace std; -using namespace std::chrono_literals; - -// using namespace crepe; - -// TODO: mock internal audio class - -TEST(audio, play) { ASSERT_TRUE(true); } diff --git a/src/test/dummy.cpp b/src/test/dummy.cpp deleted file mode 100644 index a00a9c6..0000000 --- a/src/test/dummy.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include <gtest/gtest.h> - -TEST(dummy, foo) { ASSERT_TRUE(1); } |