aboutsummaryrefslogtreecommitdiff
path: root/src/crepe
diff options
context:
space:
mode:
Diffstat (limited to 'src/crepe')
-rw-r--r--src/crepe/api/AudioSource.h11
-rw-r--r--src/crepe/facade/Sound.h4
-rw-r--r--src/crepe/system/AudioSystem.cpp17
-rw-r--r--src/crepe/system/AudioSystem.h21
-rw-r--r--src/crepe/util/CMakeLists.txt3
-rw-r--r--src/crepe/util/Private.cpp29
-rw-r--r--src/crepe/util/Private.h34
-rw-r--r--src/crepe/util/Private.hpp31
8 files changed, 139 insertions, 11 deletions
diff --git a/src/crepe/api/AudioSource.h b/src/crepe/api/AudioSource.h
index 0950129..9d76f0b 100644
--- a/src/crepe/api/AudioSource.h
+++ b/src/crepe/api/AudioSource.h
@@ -2,6 +2,7 @@
#include "../Component.h"
#include "../types.h"
+#include "../util/Private.h"
#include "GameObject.h"
#include "Asset.h"
@@ -47,14 +48,8 @@ private:
bool rewind = false;
private:
- //! 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;
+ //! AudioSystem::ComponentPrivate
+ Private private_data;
};
} // namespace crepe
diff --git a/src/crepe/facade/Sound.h b/src/crepe/facade/Sound.h
index b0b80f8..f33ee58 100644
--- a/src/crepe/facade/Sound.h
+++ b/src/crepe/facade/Sound.h
@@ -9,6 +9,10 @@ namespace crepe {
class SoundContext;
+struct SoundHandle {
+ SoLoud::handle handle;
+};
+
/**
* \brief Sound resource facade
*
diff --git a/src/crepe/system/AudioSystem.cpp b/src/crepe/system/AudioSystem.cpp
index 97cf966..0f943be 100644
--- a/src/crepe/system/AudioSystem.cpp
+++ b/src/crepe/system/AudioSystem.cpp
@@ -1,6 +1,5 @@
#include "AudioSystem.h"
-#include "../api/AudioSource.h"
#include "../manager/ComponentManager.h"
#include "../manager/ResourceManager.h"
#include "../types.h"
@@ -13,12 +12,24 @@ void AudioSystem::update() {
ResourceManager & resource_manager = this->mediator.resource_manager;
RefVector<AudioSource> components = component_manager.get_components_by_type<AudioSource>();
- for (auto component_ref : components) {
- AudioSource & component = component_ref.get();
+ for (AudioSource & component : components) {
if (!component.active) continue;
Sound & sound = resource_manager.get<Sound>(component.source);
+ if (component.private_data.empty())
+ component.private_data.set<ComponentPrivate>();
+ auto & data = component.private_data.get<ComponentPrivate>();
// TODO: lots of state diffing
+
+
+ this->update_private(component, data);
}
}
+void AudioSystem::update_private(const AudioSource & component, ComponentPrivate & data) {
+ data.last_active = component.active;
+ data.last_loop = component.loop;
+ data.last_playing = component.playing;
+ data.last_volume = component.volume;
+}
+
diff --git a/src/crepe/system/AudioSystem.h b/src/crepe/system/AudioSystem.h
index e037f51..7f41fda 100644
--- a/src/crepe/system/AudioSystem.h
+++ b/src/crepe/system/AudioSystem.h
@@ -1,6 +1,7 @@
#pragma once
#include "../facade/SoundContext.h"
+#include "../api/AudioSource.h"
#include "System.h"
@@ -12,6 +13,26 @@ public:
void update() override;
private:
+ /**
+ * \brief Private data stored by AudioSystem on AudioSource component
+ */
+ struct ComponentPrivate {
+ //! This sample's voice handle
+ SoLoud::handle handle;
+
+ //! 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;
+ };
+
+ void update_private(const AudioSource & component, ComponentPrivate & data);
+
+private:
SoundContext context {};
};
diff --git a/src/crepe/util/CMakeLists.txt b/src/crepe/util/CMakeLists.txt
index 94ed906..f49d851 100644
--- a/src/crepe/util/CMakeLists.txt
+++ b/src/crepe/util/CMakeLists.txt
@@ -1,6 +1,7 @@
target_sources(crepe PUBLIC
LogColor.cpp
Log.cpp
+ Private.cpp
)
target_sources(crepe PUBLIC FILE_SET HEADERS FILES
@@ -11,5 +12,7 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES
Proxy.hpp
OptionalRef.h
OptionalRef.hpp
+ Private.h
+ Private.hpp
)
diff --git a/src/crepe/util/Private.cpp b/src/crepe/util/Private.cpp
new file mode 100644
index 0000000..c5b5b30
--- /dev/null
+++ b/src/crepe/util/Private.cpp
@@ -0,0 +1,29 @@
+#include "Private.h"
+
+using namespace crepe;
+
+bool Private::empty() const noexcept {
+ return this->instance == nullptr;
+}
+
+Private::~Private() {
+ if (this->instance == nullptr) return;
+ this->destructor(this->instance);
+}
+
+Private::Private(Private && other) {
+ *this = std::move(other);
+}
+
+Private & Private::operator=(Private && other) {
+ // TODO: ideally this function checks for self-assignment
+ this->instance = other.instance;
+ this->destructor = other.destructor;
+ this->type = other.type;
+
+ other.instance = nullptr;
+ other.destructor = [](void*){};
+
+ return *this;
+}
+
diff --git a/src/crepe/util/Private.h b/src/crepe/util/Private.h
new file mode 100644
index 0000000..fc3728f
--- /dev/null
+++ b/src/crepe/util/Private.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <typeindex>
+#include <functional>
+
+namespace crepe {
+
+class Private {
+public:
+ Private() = default;
+ ~Private();
+ Private(Private &&);
+ Private & operator=(Private &&);
+ Private(const Private &) = delete;
+ Private & operator=(const Private &) = delete;
+
+ template <typename T>
+ T & get();
+
+ template <typename T, typename... Args>
+ void set(Args &&... args);
+
+ bool empty() const noexcept;
+
+private:
+ std::function<void(void *)> destructor;
+ std::type_index type = typeid(void);
+ void * instance = nullptr;
+};
+
+}
+
+#include "Private.hpp"
+
diff --git a/src/crepe/util/Private.hpp b/src/crepe/util/Private.hpp
new file mode 100644
index 0000000..30c8146
--- /dev/null
+++ b/src/crepe/util/Private.hpp
@@ -0,0 +1,31 @@
+#pragma once
+
+#include <stdexcept>
+#include <format>
+
+#include "Private.h"
+
+namespace crepe {
+
+template <typename T, typename... Args>
+void Private::set(Args &&... args) {
+ T * instance = new T(std::forward<Args>(args)...);
+ this->instance = static_cast<void*>(instance);
+ this->destructor = [](void * instance) {
+ delete static_cast<T*>(instance);
+ };
+ this->type = typeid(T);
+}
+
+template <typename T>
+T & Private::get() {
+ using namespace std;
+ if (this->empty())
+ throw out_of_range("Private: get() called on empty object");
+ type_index requested_type = typeid(T);
+ if (this->type != requested_type)
+ throw logic_error(format("Private: get() called with [T = {}] (actual is [T = {}])", requested_type.name(), this->type.name()));
+ return *static_cast<T*>(this->instance);
+}
+
+}