179 lines
5.6 KiB
C++
179 lines
5.6 KiB
C++
/* +------------------------------------------------------+
|
|
____/ \____ /| - Open source game framework licensed to freely use, |
|
|
\ / / | copy, modify and sell without restriction |
|
|
+--\ ^__^ /--+ | |
|
|
| ~/ \~ | | - created for <https://foam.shampoo.ooo> |
|
|
| ~~~~~~~~~~~~ | +------------------------------------------------------+
|
|
| SPACE ~~~~~ | /
|
|
| ~~~~~~~ BOX |/
|
|
+-------------*/
|
|
|
|
#pragma once
|
|
|
|
#include <fstream>
|
|
#include <ostream>
|
|
#include <iomanip>
|
|
#include "json/json.hpp"
|
|
#include "filesystem.hpp"
|
|
#include "Node.hpp"
|
|
#include "Animation.hpp"
|
|
#include "Log.hpp"
|
|
#include "extension.hpp"
|
|
|
|
class Configuration : public Node
|
|
{
|
|
|
|
private:
|
|
|
|
Animation auto_refresher = Animation(&Configuration::refresh, this);
|
|
fs::file_time_type config_file_modification_time;
|
|
nlohmann::json config;
|
|
fs::path file_to_refresh;
|
|
|
|
/*!
|
|
* Fill the config JSON with default values set by the framework.
|
|
*/
|
|
void set_defaults();
|
|
|
|
public:
|
|
|
|
/*!
|
|
* Construct a Configuration object. The path argument is the location to look for a user configuration. If valid JSON is found,
|
|
* it will be merged into the hard-coded default assignments, overwriting any existing key/value pairs. The path will be watched
|
|
* for changes if auto refresh is turned on.
|
|
*
|
|
* @param parent SPACEBOX Node rooted at the Game object
|
|
*/
|
|
Configuration(Node* parent);
|
|
|
|
/*!
|
|
* Get a writable JSON object corresponding to a key in the configuration.
|
|
*
|
|
* The JSON object's value can be used directly if it can be implictly type-cast, and it can be assigned a new value. See
|
|
* https://nlohmann.github.io/json/api/basic_json/ for further information on how to read and write the JSON object.
|
|
*
|
|
* @param key Top level key corresponding to a section of the SPACEBOX configuration JSON
|
|
* @return
|
|
*/
|
|
nlohmann::json& operator[](const std::string& key);
|
|
|
|
/*!
|
|
* Get a read-only JSON object corresponding to a key in configuration.
|
|
*
|
|
* The JSON object's value can be used directly if it can be implictly type-cast. Otherwise, use the JSON object's
|
|
* get method with a template parameter. See https://nlohmann.github.io/json/api/basic_json/ for further information.
|
|
*
|
|
* @param key Top level key corresponding to a section of the SPACEBOX configuration JSON
|
|
* @return Read-only JSON object
|
|
*/
|
|
const nlohmann::json& operator[](const std::string& key) const;
|
|
|
|
/*!
|
|
* Get a read-only JSON object reference to the entire configuration. Can be used, for example, for iterating over the
|
|
* configuration keys.
|
|
*
|
|
* @return Read-only JSON object reference to the full configuration
|
|
*/
|
|
const nlohmann::json& operator()() const;
|
|
|
|
/*!
|
|
* Merge new SPACEBOX configuration JSON with the JSON already in memory, overwriting any existing key/value pairs.
|
|
*
|
|
* @param incoming JSON object populated with SPACEBOX configuration settings
|
|
*/
|
|
void merge(const nlohmann::json& incoming);
|
|
|
|
/*!
|
|
* Merge new SPACEBOX configuration from a given path to a JSON file.
|
|
*
|
|
* @param path JSON file path with new configuration values
|
|
*/
|
|
void merge(const fs::path& path);
|
|
|
|
/*!
|
|
* @overload void Configuration::merge(fs::path path)
|
|
*/
|
|
void merge(const std::string& path);
|
|
|
|
/*!
|
|
* @overload void Configuration::merge(fs::path path)
|
|
*/
|
|
void merge(const char* path);
|
|
|
|
/*!
|
|
* Enable auto refresh. Auto refresh watches the file at the given path for changes and loads them automatically every interval given
|
|
* in seconds.
|
|
*
|
|
* @param file_to_refresh path to a configuration JSON
|
|
* @param interval amount of seconds between each refresh
|
|
*/
|
|
void enable_auto_refresh(const fs::path& file_to_refresh, float interval);
|
|
|
|
/*!
|
|
* Disable auto refresh. The file previously set with Configuration::enable_auto_refresh will no longer be watched for changes.
|
|
*/
|
|
void disable_auto_refresh();
|
|
|
|
/*!
|
|
* Check if the user config file was modified and merge if so.
|
|
*/
|
|
void refresh();
|
|
|
|
/*!
|
|
* Update the auto refresher with the given timestamp, which should be the timestamp passed to Game::update.
|
|
*
|
|
* @param timestamp seconds elapsed since the program started
|
|
*/
|
|
void update(float timestamp);
|
|
|
|
};
|
|
|
|
/* Extend GLM so nlohmann::json can read and write glm::vec2 */
|
|
namespace glm
|
|
{
|
|
template <typename T>
|
|
void to_json(nlohmann::json& j, const vec<2, T, defaultp>& v)
|
|
{
|
|
j = nlohmann::json{v.x, v.y};
|
|
}
|
|
|
|
template <typename T>
|
|
void from_json(const nlohmann::json& j, vec<2, T, defaultp>& v)
|
|
{
|
|
j.at(0).get_to(v.x);
|
|
j.at(1).get_to(v.y);
|
|
}
|
|
}
|
|
|
|
/* Extend std::filesystem so nlohmann::json can read and write std::filesystem::path */
|
|
#if defined(__MINGW32__)
|
|
namespace std::experimental::filesystem
|
|
#else
|
|
namespace std::filesystem
|
|
#endif
|
|
{
|
|
template <typename T>
|
|
void to_json(nlohmann::json& j, const path& p)
|
|
{
|
|
j = nlohmann::json{p};
|
|
}
|
|
|
|
template <typename T>
|
|
void from_json(const nlohmann::json& j, path& p)
|
|
{
|
|
j.at(0).get_to(p);
|
|
}
|
|
}
|
|
|
|
namespace std
|
|
{
|
|
/*!
|
|
* Add the entire JSON when the stream operator is called.
|
|
*
|
|
* @param out Output stream
|
|
* @param configuration Configuration object being output to the stream
|
|
* @return A reference to the input stream
|
|
*/
|
|
std::ostream& operator<<(std::ostream& out, const Configuration& configuration);
|
|
}
|