From f19f37ae3eff84161f86e62a26fbd8b68f8f91a9 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Sat, 7 Dec 2024 15:29:33 +0100
Subject: make SaveManager no longer a singleton

---
 src/test/CMakeLists.txt      |  1 +
 src/test/SaveManagerTest.cpp | 41 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)
 create mode 100644 src/test/SaveManagerTest.cpp

(limited to 'src/test')

diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt
index c9cbac5..734e3ee 100644
--- a/src/test/CMakeLists.txt
+++ b/src/test/CMakeLists.txt
@@ -17,4 +17,5 @@ target_sources(test_main PUBLIC
 	ScriptEventTest.cpp
 	ScriptSceneTest.cpp
 	Profiling.cpp
+	SaveManagerTest.cpp
 )
diff --git a/src/test/SaveManagerTest.cpp b/src/test/SaveManagerTest.cpp
new file mode 100644
index 0000000..a1efc33
--- /dev/null
+++ b/src/test/SaveManagerTest.cpp
@@ -0,0 +1,41 @@
+#include <gtest/gtest.h>
+
+#include <crepe/manager/SaveManager.h>
+#include <crepe/facade/DB.h>
+#include <crepe/ValueBroker.h>
+
+using namespace std;
+using namespace crepe;
+using namespace testing;
+
+class SaveManagerTest : public Test {
+	Mediator m;
+	class TestSaveManager : public SaveManager {
+		using SaveManager::SaveManager;
+
+		// in-memory database for testing
+		DB db{};
+		virtual DB & get_db() override { return this->db; }
+	};
+
+public:
+	TestSaveManager mgr{m};
+};
+
+TEST_F(SaveManagerTest, ReadWrite) {
+	ASSERT_FALSE(mgr.has("foo"));
+	mgr.set<string>("foo", "bar");
+	ASSERT_TRUE(mgr.has("foo"));
+
+	ValueBroker value = mgr.get<string>("foo");
+	EXPECT_EQ(value.get(), "bar");
+}
+
+TEST_F(SaveManagerTest, DefaultValue) {
+	ValueBroker value = mgr.get<int>("foo", 3);
+
+	ASSERT_EQ(value.get(), 3);
+	value.set(5);
+	ASSERT_EQ(value.get(), 5);
+}
+
-- 
cgit v1.2.3


From 2e6fcb1d048edd13a2ec69ddd226fc8ebabc2389 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Sat, 7 Dec 2024 16:01:19 +0100
Subject: add SaveManager to Script

---
 src/crepe/api/Script.cpp           | 11 +++++++----
 src/crepe/api/Script.h             |  4 ++++
 src/crepe/api/Script.hpp           |  6 ++----
 src/crepe/util/OptionalRef.h       | 10 +++++++++-
 src/crepe/util/OptionalRef.hpp     |  7 +++++++
 src/test/CMakeLists.txt            |  1 +
 src/test/ScriptSaveManagerTest.cpp | 36 ++++++++++++++++++++++++++++++++++++
 7 files changed, 66 insertions(+), 9 deletions(-)
 create mode 100644 src/test/ScriptSaveManagerTest.cpp

(limited to 'src/test')

diff --git a/src/crepe/api/Script.cpp b/src/crepe/api/Script.cpp
index 4091fd4..961e6e7 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,11 @@ 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 d99ab0e..024f1d7 100644
--- a/src/crepe/api/Script.h
+++ b/src/crepe/api/Script.h
@@ -7,6 +7,7 @@
 #include "../system/CollisionSystem.h"
 #include "../types.h"
 #include "../util/OptionalRef.h"
+#include "../ValueBroker.h"
 
 namespace crepe {
 
@@ -113,6 +114,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 45f1ff1..23d69d9 100644
--- a/src/crepe/api/Script.hpp
+++ b/src/crepe/api/Script.hpp
@@ -20,8 +20,7 @@ T & Script::get_component() const {
 
 template <typename T>
 RefVector<T> Script::get_components() const {
-	Mediator & mediator = this->mediator;
-	ComponentManager & mgr = mediator.component_manager;
+	ComponentManager & mgr = this->mediator->component_manager;
 
 	return mgr.get_components_by_id<T>(this->game_object_id);
 }
@@ -34,8 +33,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/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,13 +25,21 @@ public:
 	 */
 	OptionalRef<T> & operator=(T & ref);
 	/**
-	 * \brief Retrieve this reference
+	 * \brief Retrieve this reference (cast)
 	 *
 	 * \returns Internal reference if it is set
 	 *
 	 * \throws std::runtime_error if this function is called while the reference it not set
 	 */
 	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
 	 *
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
@@ -18,6 +18,13 @@ OptionalRef<T>::operator T &() const {
 	return *this->ref;
 }
 
+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;
diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt
index 734e3ee..2cb7c7a 100644
--- a/src/test/CMakeLists.txt
+++ b/src/test/CMakeLists.txt
@@ -18,4 +18,5 @@ target_sources(test_main PUBLIC
 	ScriptSceneTest.cpp
 	Profiling.cpp
 	SaveManagerTest.cpp
+	ScriptSaveManagerTest.cpp
 )
diff --git a/src/test/ScriptSaveManagerTest.cpp b/src/test/ScriptSaveManagerTest.cpp
new file mode 100644
index 0000000..098afa0
--- /dev/null
+++ b/src/test/ScriptSaveManagerTest.cpp
@@ -0,0 +1,36 @@
+#include <gtest/gtest.h>
+
+// stupid hack to allow access to private/protected members under test
+#define private public
+#define protected public
+
+#include <crepe/manager/SaveManager.h>
+#include <crepe/facade/DB.h>
+
+#include "ScriptTest.h"
+
+using namespace std;
+using namespace crepe;
+using namespace testing;
+
+class ScriptSaveManagerTest : public ScriptTest {
+public:
+	class TestSaveManager : public SaveManager {
+		using SaveManager::SaveManager;
+
+		// in-memory database for testing
+		DB db{};
+		virtual DB & get_db() override { return this->db; }
+	};
+
+	TestSaveManager save_mgr{mediator};
+};
+
+TEST_F(ScriptSaveManagerTest, GetSaveManager) {
+	MyScript & script = this->script;
+
+	SaveManager & mgr = script.get_save_manager();
+
+	EXPECT_EQ(&mgr, &save_mgr);
+}
+
-- 
cgit v1.2.3


From dd8bbe2fde97786ab29490bc7ba9962deb08fb4c Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Sat, 7 Dec 2024 16:01:59 +0100
Subject: `make format`

---
 src/crepe/api/Script.cpp           | 5 +----
 src/crepe/api/Script.h             | 2 +-
 src/test/SaveManagerTest.cpp       | 5 ++---
 src/test/ScriptSaveManagerTest.cpp | 3 +--
 4 files changed, 5 insertions(+), 10 deletions(-)

(limited to 'src/test')

diff --git a/src/crepe/api/Script.cpp b/src/crepe/api/Script.cpp
index 961e6e7..753a9e3 100644
--- a/src/crepe/api/Script.cpp
+++ b/src/crepe/api/Script.cpp
@@ -24,7 +24,4 @@ void Script::set_next_scene(const string & name) {
 	mgr.set_next_scene(name);
 }
 
-SaveManager & Script::get_save_manager() const {
-	return this->mediator->save_manager;
-}
-
+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 024f1d7..0d59ab6 100644
--- a/src/crepe/api/Script.h
+++ b/src/crepe/api/Script.h
@@ -2,12 +2,12 @@
 
 #include <vector>
 
+#include "../ValueBroker.h"
 #include "../manager/EventManager.h"
 #include "../manager/Mediator.h"
 #include "../system/CollisionSystem.h"
 #include "../types.h"
 #include "../util/OptionalRef.h"
-#include "../ValueBroker.h"
 
 namespace crepe {
 
diff --git a/src/test/SaveManagerTest.cpp b/src/test/SaveManagerTest.cpp
index a1efc33..e9b0c29 100644
--- a/src/test/SaveManagerTest.cpp
+++ b/src/test/SaveManagerTest.cpp
@@ -1,8 +1,8 @@
 #include <gtest/gtest.h>
 
-#include <crepe/manager/SaveManager.h>
-#include <crepe/facade/DB.h>
 #include <crepe/ValueBroker.h>
+#include <crepe/facade/DB.h>
+#include <crepe/manager/SaveManager.h>
 
 using namespace std;
 using namespace crepe;
@@ -38,4 +38,3 @@ TEST_F(SaveManagerTest, DefaultValue) {
 	value.set(5);
 	ASSERT_EQ(value.get(), 5);
 }
-
diff --git a/src/test/ScriptSaveManagerTest.cpp b/src/test/ScriptSaveManagerTest.cpp
index 098afa0..64403c4 100644
--- a/src/test/ScriptSaveManagerTest.cpp
+++ b/src/test/ScriptSaveManagerTest.cpp
@@ -4,8 +4,8 @@
 #define private public
 #define protected public
 
-#include <crepe/manager/SaveManager.h>
 #include <crepe/facade/DB.h>
+#include <crepe/manager/SaveManager.h>
 
 #include "ScriptTest.h"
 
@@ -33,4 +33,3 @@ TEST_F(ScriptSaveManagerTest, GetSaveManager) {
 
 	EXPECT_EQ(&mgr, &save_mgr);
 }
-
-- 
cgit v1.2.3