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)
|
||||
{
|
||||
// Create input stream object and open file
|
||||
std::ifstream ifstream(path);
|
||||
ASSERT(ifstream.is_open(), "File could not open '{}'", path);
|
||||
|
||||
// Check if file exists
|
||||
if (!ifstream.is_open()) {
|
||||
return nullptr;
|
||||
}
|
||||
std::ifstream file(path);
|
||||
ASSERT(file.is_open(), "File could not open '{}'", path);
|
||||
|
||||
// Get length of the file
|
||||
int32_t length = File::length(path, ifstream);
|
||||
|
||||
// Check for valid file length
|
||||
if (length == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
int32_t length = File::length(path, file);
|
||||
|
||||
// Allocate memory filled with zeros
|
||||
auto buffer = std::shared_ptr<char[]>(new char[length + 1]);
|
||||
|
||||
// Fill buffer with file contents
|
||||
ifstream.read(buffer.get(), length);
|
||||
ifstream.close();
|
||||
file.read(buffer.get(), length);
|
||||
file.close();
|
||||
|
||||
// Null termination
|
||||
buffer[length] = '\0';
|
||||
@@ -44,11 +34,11 @@ namespace Inferno {
|
||||
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);
|
||||
int32_t length = ifstream.tellg();
|
||||
ifstream.seekg(0, std::ios::beg);
|
||||
file.seekg(0, std::ios::end);
|
||||
int32_t length = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
ASSERT(length != -1, "File could not determine length '{}'", path);
|
||||
|
||||
return length;
|
||||
|
||||
@@ -16,29 +16,29 @@ namespace Inferno {
|
||||
public:
|
||||
static std::shared_ptr<char[]> raw(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>
|
||||
static void ioRead(T& t, const std::string& path)
|
||||
static void ioRead(T* t, const std::string& 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()) {
|
||||
file >> t;
|
||||
file >> *t;
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
ASSERT(file.is_open(), "File could not open! {}", path.c_str());
|
||||
ASSERT(file.is_open(), "File could not open! {}", path);
|
||||
|
||||
if (file.is_open()) {
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,67 +5,82 @@
|
||||
#include "inferno/io/log.h"
|
||||
#include "inferno/settings.h"
|
||||
#include "inferno/util/json.h"
|
||||
#include "inferno/window.h"
|
||||
|
||||
namespace Inferno {
|
||||
|
||||
const char* Settings::m_path = "assets/settings.json";
|
||||
SettingsProperties Settings::m_properties = {};
|
||||
const char* Settings::m_path { "assets/settings.json" };
|
||||
SettingsProperties Settings::m_properties {};
|
||||
|
||||
void Settings::initialize()
|
||||
{
|
||||
Settings::update();
|
||||
Settings::load();
|
||||
|
||||
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()
|
||||
{
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
nlohmann::json json;
|
||||
json["window"]["title"] = m_properties.window.title;
|
||||
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);
|
||||
json object = m_properties;
|
||||
File::ioWrite(&object, m_path);
|
||||
info() << "Settings saved";
|
||||
|
||||
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
|
||||
#define SETTINGS_H
|
||||
|
||||
#include "nlohmann/json.hpp"
|
||||
|
||||
#include "inferno/util/json.h"
|
||||
#include "inferno/window.h"
|
||||
|
||||
namespace Inferno {
|
||||
@@ -14,10 +13,9 @@ namespace Inferno {
|
||||
class Settings {
|
||||
public:
|
||||
static void initialize();
|
||||
static void update();
|
||||
static void destroy();
|
||||
|
||||
static bool load(nlohmann::json& json);
|
||||
static void load();
|
||||
static bool save();
|
||||
|
||||
static inline SettingsProperties& get() { return m_properties; }
|
||||
@@ -27,6 +25,16 @@ namespace Inferno {
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user