aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-12-09 12:42:58 +0100
committerLoek Le Blansch <loek@pipeframe.xyz>2024-12-09 12:42:58 +0100
commite8e5412965f19d3966635a2c207d55ae1b12db51 (patch)
tree69ea4f5a6591e9f82e73651e6e728e0f7c003d65
parentb845376e270c060730d4f8b9b0946a63908871da (diff)
feature_savemgr
-rw-r--r--src/crepe/manager/SaveManager.cpp48
-rw-r--r--src/crepe/manager/SaveManager.h6
-rw-r--r--src/doc/feature/proxy.dox38
-rw-r--r--src/doc/feature/savemgr.dox80
-rw-r--r--src/doc/features.dox9
5 files changed, 153 insertions, 28 deletions
diff --git a/src/crepe/manager/SaveManager.cpp b/src/crepe/manager/SaveManager.cpp
index d4ed1c1..034a283 100644
--- a/src/crepe/manager/SaveManager.cpp
+++ b/src/crepe/manager/SaveManager.cpp
@@ -133,9 +133,32 @@ template void SaveManager::set(const string &, const float &);
template void SaveManager::set(const string &, const double &);
template <typename T>
+T SaveManager::get(const string & key) {
+ return this->deserialize<T>(this->get_db().get(key));
+}
+template uint8_t SaveManager::get(const string &);
+template int8_t SaveManager::get(const string &);
+template uint16_t SaveManager::get(const string &);
+template int16_t SaveManager::get(const string &);
+template uint32_t SaveManager::get(const string &);
+template int32_t SaveManager::get(const string &);
+template uint64_t SaveManager::get(const string &);
+template int64_t SaveManager::get(const string &);
+template float SaveManager::get(const string &);
+template double SaveManager::get(const string &);
+template string SaveManager::get(const string &);
+
+template <typename T>
ValueBroker<T> SaveManager::get(const string & key, const T & default_value) {
if (!this->has(key)) this->set<T>(key, default_value);
- return this->get<T>(key);
+ T value;
+ return {
+ [this, key](const T & target) { this->set<T>(key, target); },
+ [this, key, value]() mutable -> const T & {
+ value = this->get<T>(key);
+ return value;
+ },
+ };
}
template ValueBroker<uint8_t> SaveManager::get(const string &, const uint8_t &);
template ValueBroker<int8_t> SaveManager::get(const string &, const int8_t &);
@@ -148,26 +171,3 @@ template ValueBroker<int64_t> SaveManager::get(const string &, const int64_t &);
template ValueBroker<float> SaveManager::get(const string &, const float &);
template ValueBroker<double> SaveManager::get(const string &, const double &);
template ValueBroker<string> SaveManager::get(const string &, const string &);
-
-template <typename T>
-ValueBroker<T> SaveManager::get(const string & key) {
- T value;
- 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));
- return value;
- },
- };
-}
-template ValueBroker<uint8_t> SaveManager::get(const string &);
-template ValueBroker<int8_t> SaveManager::get(const string &);
-template ValueBroker<uint16_t> SaveManager::get(const string &);
-template ValueBroker<int16_t> SaveManager::get(const string &);
-template ValueBroker<uint32_t> SaveManager::get(const string &);
-template ValueBroker<int32_t> SaveManager::get(const string &);
-template ValueBroker<uint64_t> SaveManager::get(const string &);
-template ValueBroker<int64_t> SaveManager::get(const string &);
-template ValueBroker<float> SaveManager::get(const string &);
-template ValueBroker<double> SaveManager::get(const string &);
-template ValueBroker<string> SaveManager::get(const string &);
diff --git a/src/crepe/manager/SaveManager.h b/src/crepe/manager/SaveManager.h
index 3d8c852..e2ef005 100644
--- a/src/crepe/manager/SaveManager.h
+++ b/src/crepe/manager/SaveManager.h
@@ -33,17 +33,17 @@ public:
ValueBroker<T> get(const std::string & key, const T & default_value);
/**
- * \brief Get a read/write reference to a value
+ * \brief Get a value directly
*
* \param key The value key
*
- * \return Read/write reference to the value
+ * \return The value
*
* \note Attempting to read this value before it is initialized (i.e. set) will result in an
* exception
*/
template <typename T>
- ValueBroker<T> get(const std::string & key);
+ T get(const std::string & key);
/**
* \brief Set a value directly
diff --git a/src/doc/feature/proxy.dox b/src/doc/feature/proxy.dox
new file mode 100644
index 0000000..02ed4a5
--- /dev/null
+++ b/src/doc/feature/proxy.dox
@@ -0,0 +1,38 @@
+// vim:ft=doxygen
+namespace crepe {
+/**
+
+\defgroup feature_proxy Proxy utility
+\ingroup feature
+\brief Use ValueBroker as if it were a regular variable
+
+\todo Long description
+
+\see ValueBroker
+\see Proxy
+
+\par Example
+
+```cpp
+#include <crepe/util/Proxy.h>
+#include <crepe/ValueBroker.h>
+
+int calculation(int value) {
+ return 3 * value;
+}
+
+void anywhere() {
+ crepe::ValueBroker<int> foo_handle;
+ crepe::Proxy foo = foo_handle;
+
+ // implicitly calls .set()
+ foo += 10;
+
+ // implicitly calls .get()
+ int out = calculation(foo);
+}
+
+```
+
+*/
+}
diff --git a/src/doc/feature/savemgr.dox b/src/doc/feature/savemgr.dox
new file mode 100644
index 0000000..6aeab03
--- /dev/null
+++ b/src/doc/feature/savemgr.dox
@@ -0,0 +1,80 @@
+// vim:ft=doxygen
+namespace crepe {
+/**
+
+\defgroup feature_savemgr Save data
+\ingroup feature
+\brief Functions to persistently store and retrieve arbitrary values
+
+The SaveManager may be used to persistently store game state such as player
+progress, statistics, achievements, etc. It works like a key-value store, where
+the key is a string and the value is an arbitrary type.
+
+SaveManager implements the following:
+
+- Storage and retrieval of primitive types and strings.
+- Automatic initialization of the database using default values.
+- The underlying database format is journaled, which reduces the likelihood of
+ players losing save data when an unexpected crash occurs while the SaveManager
+ is writing to disk.
+
+\see SaveManager
+
+\par Example
+
+The SaveManager instance reference may be retrieved by calling \c
+get_save_manager(). This function is available---
+
+- Within (derivatives of) Script
+
+- \todo Within (derivatives of) Scene
+
+- \todo As a public member function of LoopManager
+
+```cpp
+// Retrieve save manager
+crepe::SaveManager & save_manager = get_save_manager();
+```
+
+SaveManager may be used *explicitly*, using the \ref SaveManager::set "set()",
+\ref SaveManager::get "get()" and \ref SaveManager::has "has()" methods:
+```cpp
+// Check if the key "foo" exists, and initialize it to 3 if it doesn't
+if (!save_manager.has("foo"))
+ save_manager.set<int>("foo", 3);
+// Get value of key "foo"
+int foo = save_manager.get<int>("foo");
+
+// ~~~ arbitrary game code ~~~
+foo += 10;
+// ~~~ arbitrary game code ~~~
+
+// Save "foo" back to database
+save_manager.set<int>("foo", foo);
+```
+
+Alternatively, SaveManager::get may be called with a default value as second
+parameter. This changes its return type to ValueBroker, which acts as a
+read/write handle to the specific key requested, and remembers the key and its
+value type for you:
+```cpp
+// Get a read/write handle to the value stored in key "foo", and initialize it
+// to 3 if it doesn't exist yet
+ValueBroker foo_handle = save_manager.get<int>("foo", 3);
+int foo = foo_handle.get();
+
+// ~~~ arbitrary game code ~~~
+foo += 10;
+// ~~~ arbitrary game code ~~~
+
+// Save back to database
+foo_handle.set(foo);
+```
+
+To further simplify game code, the return value of SaveManager::get may be
+implicitly cast to Proxy instead of ValueBroker. This allows the database value
+to be used as if it were a regular variable. This usage is detailed separately
+in \"\ref feature_proxy\".
+
+*/
+}
diff --git a/src/doc/features.dox b/src/doc/features.dox
index 3bcbffe..6734137 100644
--- a/src/doc/features.dox
+++ b/src/doc/features.dox
@@ -41,7 +41,7 @@ feature.
- \todo Particle effects
- Save data
- - \todo SaveManager usage
+ - \ref feature_savemgr \n\copybrief feature_savemgr
- Audio
- \todo Playing sound effects
@@ -58,6 +58,13 @@ feature.
- \todo Subscribing to *any* event inside Script
+ - \todo Creating and dispatching custom events
+
- \todo Replay
+- Utilities
+ - \todo Logging
+
+ - \ref feature_proxy \n\copybrief feature_proxy
+
*/