mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-07-12 13:35:35 -04:00
a00fb1c05c
Roughly inspired by what I've learned from my work on Space Station 14, without some of the unnecessary cruft and complexity. Implementation is relatively simple once I figured out all the template order shenanigans.
115 lines
3.1 KiB
C++
115 lines
3.1 KiB
C++
#ifndef DUSK_CONFIG_HPP
|
|
#define DUSK_CONFIG_HPP
|
|
|
|
#include <stdexcept>
|
|
#include "nlohmann/json.hpp"
|
|
#include "config_var.hpp"
|
|
|
|
namespace dusk::config {
|
|
|
|
/**
|
|
* \brief Base class containing virtual functions used for save/load of CVars.
|
|
*/
|
|
class ConfigImplBase {
|
|
protected:
|
|
virtual ~ConfigImplBase() = default;
|
|
|
|
public:
|
|
/**
|
|
* \brief Load a JSON value into a CVar at the Value layer.
|
|
*/
|
|
virtual void loadFromJson(ConfigVarBase& cVar, const nlohmann::json& jsonValue) const = 0;
|
|
|
|
/**
|
|
* \brief Load a simple launch argument into the CVar at the Override layer.
|
|
*/
|
|
virtual void loadFromArg(ConfigVarBase& cVar, std::string_view stringValue) const = 0;
|
|
|
|
/**
|
|
* \brief Dump the value contained in the CVar to JSON.
|
|
*/
|
|
[[nodiscard]] virtual nlohmann::json dumpToJson(const ConfigVarBase& cVar) const = 0;
|
|
};
|
|
|
|
template<ConfigValue T>
|
|
class ConfigImpl : public ConfigImplBase {
|
|
// Just downcasting the references...
|
|
void loadFromJson(ConfigVarBase& cVar, const nlohmann::json& jsonValue) const final {
|
|
assert(typeid(cVar) == typeid(ConfigVar<T>));
|
|
loadFromJson(dynamic_cast<ConfigVar<T>&>(cVar), jsonValue);
|
|
}
|
|
|
|
void loadFromArg(ConfigVarBase& cVar, std::string_view stringValue) const final {
|
|
assert(typeid(cVar) == typeid(ConfigVar<T>));
|
|
loadFromArg(dynamic_cast<ConfigVar<T>&>(cVar), stringValue);
|
|
}
|
|
|
|
[[nodiscard]] nlohmann::json dumpToJson(const ConfigVarBase& cVar) const final {
|
|
assert(typeid(cVar) == typeid(ConfigVar<T>));
|
|
return dumpToJson(dynamic_cast<const ConfigVar<T>&>(cVar));
|
|
}
|
|
|
|
/**
|
|
* \brief Load a JSON value into a CVar at the Value layer.
|
|
*/
|
|
static void loadFromJson(ConfigVar<T>& cVar, const nlohmann::json& jsonValue);
|
|
|
|
/**
|
|
* \brief Load a simple launch argument into the CVar at the Override layer.
|
|
*/
|
|
static void loadFromArg(ConfigVar<T>& cVar, std::string_view stringValue);
|
|
|
|
/**
|
|
* \brief Dump the value contained in the CVar to JSON.
|
|
*/
|
|
[[nodiscard]] static nlohmann::json dumpToJson(const ConfigVar<T>& cVar);
|
|
};
|
|
|
|
/**
|
|
* \brief Thrown by config loading functions if the value provided is invalid for the CVar.
|
|
*/
|
|
class InvalidConfigError : public std::runtime_error {
|
|
public:
|
|
explicit InvalidConfigError(const char* what) : runtime_error(what) {}
|
|
};
|
|
|
|
/**
|
|
* \brief Register a CVar to make the config system aware of it.
|
|
*
|
|
* This must be done on startup *before* config has been loaded.
|
|
*/
|
|
void Register(ConfigVarBase& configVar);
|
|
|
|
/**
|
|
* \brief Indicate that all registrations have happened and everything should lock in.
|
|
*/
|
|
void FinishRegistration();
|
|
|
|
/**
|
|
* \brief Load config from the standard user preferences location.
|
|
*/
|
|
void LoadFromUserPreferences();
|
|
void LoadFromFileName(const char* path);
|
|
|
|
/**
|
|
* \brief Save the config to file.
|
|
*/
|
|
void Save();
|
|
|
|
/**
|
|
* \brief Get a registered CVar by name.
|
|
*
|
|
* @return null if the CVar does not exist.
|
|
*/
|
|
ConfigVarBase* GetConfigVar(std::string_view name);
|
|
|
|
template <ConfigValue T>
|
|
const ConfigImplBase* GetConfigImpl() {
|
|
static ConfigImpl<T> config;
|
|
return &config;
|
|
}
|
|
|
|
} // namespace dusk::config
|
|
|
|
#endif
|