aboutsummaryrefslogtreecommitdiff
path: root/src/crepe
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-12-11 13:58:19 +0100
committerLoek Le Blansch <loek@pipeframe.xyz>2024-12-11 13:58:19 +0100
commitd228d4b3856606ad4395723b2703759a0ebe9832 (patch)
treebfd3019ca2c9bec258fffca9a9204ddc88768264 /src/crepe
parent770496ee9d0e45480c0e0f8951adb8eee247bfe1 (diff)
parentc45b60941b82dec2097d958b396a117b1634eada (diff)
Merge branch 'master' into loek/replay
Diffstat (limited to 'src/crepe')
-rw-r--r--src/crepe/api/LoopManager.h3
-rw-r--r--src/crepe/api/Script.cpp8
-rw-r--r--src/crepe/api/Script.h3
-rw-r--r--src/crepe/api/Script.hpp3
-rw-r--r--src/crepe/manager/Mediator.h4
-rw-r--r--src/crepe/manager/SaveManager.cpp35
-rw-r--r--src/crepe/manager/SaveManager.h33
-rw-r--r--src/crepe/util/OptionalRef.h10
-rw-r--r--src/crepe/util/OptionalRef.hpp7
9 files changed, 57 insertions, 49 deletions
diff --git a/src/crepe/api/LoopManager.h b/src/crepe/api/LoopManager.h
index 1ac6a39..1183a4d 100644
--- a/src/crepe/api/LoopManager.h
+++ b/src/crepe/api/LoopManager.h
@@ -4,6 +4,7 @@
#include "../manager/ComponentManager.h"
#include "../manager/ResourceManager.h"
#include "../manager/SceneManager.h"
+#include "../manager/SaveManager.h"
#include "../system/System.h"
#include "LoopTimer.h"
@@ -68,6 +69,8 @@ private:
SceneManager scene_manager{mediator};
//! Resource manager instance
ResourceManager resource_manager{mediator};
+ //! Save manager instance
+ SaveManager save_manager{mediator};
//! SDL context \todo no more singletons!
SDLContext & sdl_context = SDLContext::get_instance();
diff --git a/src/crepe/api/Script.cpp b/src/crepe/api/Script.cpp
index 4091fd4..753a9e3 100644
--- a/src/crepe/api/Script.cpp
+++ b/src/crepe/api/Script.cpp
@@ -8,8 +8,7 @@ using namespace crepe;
using namespace std;
Script::~Script() {
- Mediator & mediator = this->mediator;
- EventManager & mgr = mediator.event_manager;
+ EventManager & mgr = this->mediator->event_manager;
for (auto id : this->listeners) {
mgr.unsubscribe(id);
}
@@ -21,7 +20,8 @@ void Script::subscribe(const EventHandler<CollisionEvent> & callback) {
}
void Script::set_next_scene(const string & name) {
- Mediator & mediator = this->mediator;
- SceneManager & mgr = mediator.scene_manager;
+ SceneManager & mgr = this->mediator->scene_manager;
mgr.set_next_scene(name);
}
+
+SaveManager & Script::get_save_manager() const { return this->mediator->save_manager; }
diff --git a/src/crepe/api/Script.h b/src/crepe/api/Script.h
index 49bdcf5..668e5d1 100644
--- a/src/crepe/api/Script.h
+++ b/src/crepe/api/Script.h
@@ -132,6 +132,9 @@ protected:
*/
void set_next_scene(const std::string & name);
+ //! Retrieve SaveManager reference
+ SaveManager & get_save_manager() const;
+
//! \}
private:
diff --git a/src/crepe/api/Script.hpp b/src/crepe/api/Script.hpp
index 16e0dc5..225a51c 100644
--- a/src/crepe/api/Script.hpp
+++ b/src/crepe/api/Script.hpp
@@ -31,8 +31,7 @@ void Script::logf(Args &&... args) {
template <typename EventType>
void Script::subscribe_internal(const EventHandler<EventType> & callback,
event_channel_t channel) {
- Mediator & mediator = this->mediator;
- EventManager & mgr = mediator.event_manager;
+ EventManager & mgr = this->mediator->event_manager;
subscription_t listener = mgr.subscribe<EventType>(
[this, callback](const EventType & data) -> bool {
bool & active = this->active;
diff --git a/src/crepe/manager/Mediator.h b/src/crepe/manager/Mediator.h
index ba0b41f..35ac181 100644
--- a/src/crepe/manager/Mediator.h
+++ b/src/crepe/manager/Mediator.h
@@ -5,13 +5,13 @@
// TODO: remove these singletons:
#include "../facade/SDLContext.h"
#include "EventManager.h"
-#include "SaveManager.h"
#include "api/LoopTimer.h"
namespace crepe {
class ComponentManager;
class SceneManager;
+class SaveManager;
class ResourceManager;
/**
@@ -29,7 +29,7 @@ class ResourceManager;
struct Mediator {
OptionalRef<ComponentManager> component_manager;
OptionalRef<SceneManager> scene_manager;
- OptionalRef<SaveManager> save_manager = SaveManager::get_instance();
+ OptionalRef<SaveManager> save_manager;
OptionalRef<EventManager> event_manager = EventManager::get_instance();
OptionalRef<ResourceManager> resource_manager;
OptionalRef<SDLContext> sdl_context = SDLContext::get_instance();
diff --git a/src/crepe/manager/SaveManager.cpp b/src/crepe/manager/SaveManager.cpp
index d4ed1c1..39b92d4 100644
--- a/src/crepe/manager/SaveManager.cpp
+++ b/src/crepe/manager/SaveManager.cpp
@@ -1,13 +1,27 @@
#include "../ValueBroker.h"
#include "../api/Config.h"
#include "../facade/DB.h"
-#include "../util/Log.h"
#include "SaveManager.h"
using namespace std;
using namespace crepe;
+SaveManager::SaveManager(Mediator & mediator) : Manager(mediator) {
+ mediator.save_manager = *this;
+}
+
+DB & SaveManager::get_db() {
+ if (this->db == nullptr) {
+ Config & cfg = Config::get_instance();
+ this->db = {
+ new DB(cfg.savemgr.location),
+ [](void * db){ delete static_cast<DB *>(db); }
+ };
+ }
+ return *static_cast<DB *>(this->db.get());
+}
+
template <>
string SaveManager::serialize(const string & value) const noexcept {
return value;
@@ -90,22 +104,6 @@ int32_t SaveManager::deserialize(const string & value) const noexcept {
return deserialize<int64_t>(value);
}
-SaveManager::SaveManager() { dbg_trace(); }
-
-SaveManager & SaveManager::get_instance() {
- dbg_trace();
- static SaveManager instance;
- return instance;
-}
-
-DB & SaveManager::get_db() {
- Config & cfg = Config::get_instance();
- // TODO: make this path relative to XDG_DATA_HOME on Linux and whatever the
- // default equivalent is on Windows using some third party library
- static DB db(cfg.savemgr.location);
- return db;
-}
-
bool SaveManager::has(const string & key) {
DB & db = this->get_db();
return db.has(key);
@@ -155,7 +153,8 @@ ValueBroker<T> SaveManager::get(const string & key) {
return {
[this, key](const T & target) { this->set<T>(key, target); },
[this, key, value]() mutable -> const T & {
- value = this->deserialize<T>(this->get_db().get(key));
+ DB & db = this->get_db();
+ value = this->deserialize<T>(db.get(key));
return value;
},
};
diff --git a/src/crepe/manager/SaveManager.h b/src/crepe/manager/SaveManager.h
index 3d8c852..27e625c 100644
--- a/src/crepe/manager/SaveManager.h
+++ b/src/crepe/manager/SaveManager.h
@@ -1,9 +1,12 @@
#pragma once
#include <memory>
+#include <functional>
#include "../ValueBroker.h"
+#include "Manager.h"
+
namespace crepe {
class DB;
@@ -18,7 +21,7 @@ class DB;
*
* The underlying database is a key-value store.
*/
-class SaveManager {
+class SaveManager : public Manager {
public:
/**
* \brief Get a read/write reference to a value and initialize it if it does not yet exist
@@ -63,8 +66,8 @@ public:
*/
bool has(const std::string & key);
-private:
- SaveManager();
+public:
+ SaveManager(Mediator & mediator);
virtual ~SaveManager() = default;
private:
@@ -89,26 +92,12 @@ private:
template <typename T>
T deserialize(const std::string & value) const noexcept;
-public:
- // singleton
- static SaveManager & get_instance();
- SaveManager(const SaveManager &) = delete;
- SaveManager(SaveManager &&) = delete;
- SaveManager & operator=(const SaveManager &) = delete;
- SaveManager & operator=(SaveManager &&) = delete;
-
+protected:
+ //! Create or return DB
+ virtual DB & get_db();
private:
- /**
- * \brief Create an instance of DB and return its reference
- *
- * \returns DB instance
- *
- * This function exists because DB is a facade class, which can't directly be used in the API
- * without workarounds
- *
- * TODO: better solution
- */
- static DB & get_db();
+ //! Database
+ std::unique_ptr<void, std::function<void(void*)>> db = nullptr;
};
} // namespace crepe
diff --git a/src/crepe/util/OptionalRef.h b/src/crepe/util/OptionalRef.h
index 3201667..1b2cb3f 100644
--- a/src/crepe/util/OptionalRef.h
+++ b/src/crepe/util/OptionalRef.h
@@ -25,7 +25,7 @@ public:
*/
OptionalRef<T> & operator=(T & ref);
/**
- * \brief Retrieve this reference
+ * \brief Retrieve this reference (cast)
*
* \returns Internal reference if it is set
*
@@ -33,6 +33,14 @@ public:
*/
operator T &() const;
/**
+ * \brief Retrieve this reference (member access)
+ *
+ * \returns Internal reference if it is set
+ *
+ * \throws std::runtime_error if this function is called while the reference it not set
+ */
+ T * operator->() const;
+ /**
* \brief Check if this reference is not empty
*
* \returns `true` if reference is set, or `false` if it is not
diff --git a/src/crepe/util/OptionalRef.hpp b/src/crepe/util/OptionalRef.hpp
index 4608c9e..5e36b3a 100644
--- a/src/crepe/util/OptionalRef.hpp
+++ b/src/crepe/util/OptionalRef.hpp
@@ -19,6 +19,13 @@ OptionalRef<T>::operator T &() const {
}
template <typename T>
+T * OptionalRef<T>::operator->() const {
+ if (this->ref == nullptr)
+ throw std::runtime_error("OptionalRef: attempt to dereference nullptr");
+ return this->ref;
+}
+
+template <typename T>
OptionalRef<T> & OptionalRef<T>::operator=(T & ref) {
this->ref = &ref;
return *this;