Implement nlohmann::json arbitrary type conversion for settings
This commit is contained in:
@@ -9,28 +9,18 @@ namespace Inferno {
|
|||||||
std::shared_ptr<char[]> File::raw(const std::string& path)
|
std::shared_ptr<char[]> File::raw(const std::string& path)
|
||||||
{
|
{
|
||||||
// Create input stream object and open file
|
// Create input stream object and open file
|
||||||
std::ifstream ifstream(path);
|
std::ifstream file(path);
|
||||||
ASSERT(ifstream.is_open(), "File could not open '{}'", path);
|
ASSERT(file.is_open(), "File could not open '{}'", path);
|
||||||
|
|
||||||
// Check if file exists
|
|
||||||
if (!ifstream.is_open()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get length of the file
|
// Get length of the file
|
||||||
int32_t length = File::length(path, ifstream);
|
int32_t length = File::length(path, file);
|
||||||
|
|
||||||
// Check for valid file length
|
|
||||||
if (length == -1) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allocate memory filled with zeros
|
// Allocate memory filled with zeros
|
||||||
auto buffer = std::shared_ptr<char[]>(new char[length + 1]);
|
auto buffer = std::shared_ptr<char[]>(new char[length + 1]);
|
||||||
|
|
||||||
// Fill buffer with file contents
|
// Fill buffer with file contents
|
||||||
ifstream.read(buffer.get(), length);
|
file.read(buffer.get(), length);
|
||||||
ifstream.close();
|
file.close();
|
||||||
|
|
||||||
// Null termination
|
// Null termination
|
||||||
buffer[length] = '\0';
|
buffer[length] = '\0';
|
||||||
@@ -44,11 +34,11 @@ namespace Inferno {
|
|||||||
return std::string(raw(path).get());
|
return std::string(raw(path).get());
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t File::length(const std::string& path, std::ifstream& ifstream)
|
int32_t File::length(const std::string& path, std::ifstream& file)
|
||||||
{
|
{
|
||||||
ifstream.seekg(0, std::ios::end);
|
file.seekg(0, std::ios::end);
|
||||||
int32_t length = ifstream.tellg();
|
int32_t length = file.tellg();
|
||||||
ifstream.seekg(0, std::ios::beg);
|
file.seekg(0, std::ios::beg);
|
||||||
ASSERT(length != -1, "File could not determine length '{}'", path);
|
ASSERT(length != -1, "File could not determine length '{}'", path);
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
|
|||||||
@@ -16,29 +16,29 @@ namespace Inferno {
|
|||||||
public:
|
public:
|
||||||
static std::shared_ptr<char[]> raw(const std::string& path);
|
static std::shared_ptr<char[]> raw(const std::string& path);
|
||||||
static std::string read(const std::string& path);
|
static std::string read(const std::string& path);
|
||||||
static int32_t length(const std::string& path, std::ifstream& ifstream);
|
static int32_t length(const std::string& path, std::ifstream& file);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static void ioRead(T& t, const std::string& path)
|
static void ioRead(T* t, const std::string& path)
|
||||||
{
|
{
|
||||||
std::ifstream file(path);
|
std::ifstream file(path);
|
||||||
ASSERT(file.is_open(), "File could not open! {}", path.c_str());
|
ASSERT(file.is_open(), "File could not open '{}'", path);
|
||||||
|
|
||||||
if (file.is_open()) {
|
if (file.is_open()) {
|
||||||
file >> t;
|
file >> *t;
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static void ioWrite(T& t, const std::string& path)
|
static void ioWrite(T* t, const std::string& path)
|
||||||
{
|
{
|
||||||
std::ofstream file (path);
|
std::ofstream file (path);
|
||||||
ASSERT(file.is_open(), "File could not open! {}", path.c_str());
|
ASSERT(file.is_open(), "File could not open! {}", path);
|
||||||
|
|
||||||
if (file.is_open()) {
|
if (file.is_open()) {
|
||||||
// Write file with single tabs, nicely formatted
|
// Write file with single tabs, nicely formatted
|
||||||
file << std::setfill ('\t') << std::setw(1) << t << std::endl;
|
file << std::setfill ('\t') << std::setw(1) << *t << std::endl;
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,67 +5,82 @@
|
|||||||
#include "inferno/io/log.h"
|
#include "inferno/io/log.h"
|
||||||
#include "inferno/settings.h"
|
#include "inferno/settings.h"
|
||||||
#include "inferno/util/json.h"
|
#include "inferno/util/json.h"
|
||||||
|
#include "inferno/window.h"
|
||||||
|
|
||||||
namespace Inferno {
|
namespace Inferno {
|
||||||
|
|
||||||
const char* Settings::m_path = "assets/settings.json";
|
const char* Settings::m_path { "assets/settings.json" };
|
||||||
SettingsProperties Settings::m_properties = {};
|
SettingsProperties Settings::m_properties {};
|
||||||
|
|
||||||
void Settings::initialize()
|
void Settings::initialize()
|
||||||
{
|
{
|
||||||
Settings::update();
|
Settings::load();
|
||||||
|
|
||||||
info() << "Settings initialized";
|
info() << "Settings initialized";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::update()
|
|
||||||
{
|
|
||||||
nlohmann::json json;
|
|
||||||
Settings::load(json);
|
|
||||||
|
|
||||||
if (!Json::hasProperty(json, "window")) {
|
|
||||||
warn() << "Settings has no window section, using default values";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto window = json["window"];
|
|
||||||
auto title = Json::parseStringProperty(window, "title", false);
|
|
||||||
auto width = Json::parseUnsignedProperty(window, "width", false);
|
|
||||||
auto height = Json::parseUnsignedProperty(window, "height", false);
|
|
||||||
auto fullscreen = Json::parseStringProperty(window, "fullscreen", false);
|
|
||||||
auto vsync = Json::parseBoolProperty(window, "vsync", false);
|
|
||||||
|
|
||||||
if (title) m_properties.window.title = title.value();
|
|
||||||
if (width) m_properties.window.width = width.value();
|
|
||||||
if (height) m_properties.window.height = height.value();
|
|
||||||
if (fullscreen) m_properties.window.fullscreen = fullscreen.value();
|
|
||||||
if (vsync) m_properties.window.vsync = vsync.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Settings::destroy()
|
void Settings::destroy()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Settings::load(nlohmann::json& json)
|
void Settings::load()
|
||||||
{
|
{
|
||||||
File::ioRead(json, m_path);
|
json object;
|
||||||
|
|
||||||
return true;
|
try {
|
||||||
|
File::ioRead(&object, m_path);
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
warn() << "Settings invalid formatting, using default values";
|
||||||
|
}
|
||||||
|
|
||||||
|
auto settings = Json::getPropertyValue<SettingsProperties>(object, json::value_t::object);
|
||||||
|
if (settings) {
|
||||||
|
m_properties = settings.value();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Settings::save()
|
bool Settings::save()
|
||||||
{
|
{
|
||||||
nlohmann::json json;
|
json object = m_properties;
|
||||||
json["window"]["title"] = m_properties.window.title;
|
File::ioWrite(&object, m_path);
|
||||||
json["window"]["width"] = m_properties.window.width;
|
|
||||||
json["window"]["height"] = m_properties.window.height;
|
|
||||||
json["window"]["fullscreen"] = m_properties.window.fullscreen;
|
|
||||||
json["window"]["vsync"] = m_properties.window.vsync;
|
|
||||||
|
|
||||||
File::ioWrite(json, m_path);
|
|
||||||
info() << "Settings saved";
|
info() << "Settings saved";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
|
||||||
|
void to_json(json& object, const SettingsProperties& settings)
|
||||||
|
{
|
||||||
|
object = json {
|
||||||
|
{ "window", settings.window }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void from_json(const json& object, SettingsProperties& settings)
|
||||||
|
{
|
||||||
|
if (Json::hasProperty(object, "window")) object.at("window").get_to(settings.window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void to_json(json& object, const WindowProperties& window)
|
||||||
|
{
|
||||||
|
object = json {
|
||||||
|
{ "title", window.title },
|
||||||
|
{ "width", window.width },
|
||||||
|
{ "height", window.height },
|
||||||
|
{ "fullscreen", window.fullscreen },
|
||||||
|
{ "vsync", window.vsync },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void from_json(const json& object, WindowProperties& window)
|
||||||
|
{
|
||||||
|
if (Json::hasProperty(object, "title")) object.at("title").get_to(window.title);
|
||||||
|
if (Json::hasProperty(object, "width")) object.at("width").get_to(window.width);
|
||||||
|
if (Json::hasProperty(object, "height")) object.at("height").get_to(window.height);
|
||||||
|
if (Json::hasProperty(object, "fullscreen")) object.at("fullscreen").get_to(window.fullscreen);
|
||||||
|
if (Json::hasProperty(object, "vsync")) object.at("vsync").get_to(window.vsync);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
#ifndef SETTINGS_H
|
#ifndef SETTINGS_H
|
||||||
#define SETTINGS_H
|
#define SETTINGS_H
|
||||||
|
|
||||||
#include "nlohmann/json.hpp"
|
#include "inferno/util/json.h"
|
||||||
|
|
||||||
#include "inferno/window.h"
|
#include "inferno/window.h"
|
||||||
|
|
||||||
namespace Inferno {
|
namespace Inferno {
|
||||||
@@ -14,10 +13,9 @@ namespace Inferno {
|
|||||||
class Settings {
|
class Settings {
|
||||||
public:
|
public:
|
||||||
static void initialize();
|
static void initialize();
|
||||||
static void update();
|
|
||||||
static void destroy();
|
static void destroy();
|
||||||
|
|
||||||
static bool load(nlohmann::json& json);
|
static void load();
|
||||||
static bool save();
|
static bool save();
|
||||||
|
|
||||||
static inline SettingsProperties& get() { return m_properties; }
|
static inline SettingsProperties& get() { return m_properties; }
|
||||||
@@ -27,6 +25,16 @@ namespace Inferno {
|
|||||||
static SettingsProperties m_properties;
|
static SettingsProperties m_properties;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
|
||||||
|
// nlohmann::json arbitrary type conversion functions
|
||||||
|
|
||||||
|
void to_json(json& object, const SettingsProperties& settings);
|
||||||
|
void from_json(const json& object, SettingsProperties& settings);
|
||||||
|
|
||||||
|
void to_json(json& object, const WindowProperties& window);
|
||||||
|
void from_json(const json& object, WindowProperties& window);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // SETTINGS_H
|
#endif // SETTINGS_H
|
||||||
|
|||||||
Reference in New Issue
Block a user