Browse Source

Implement nlohmann::json arbitrary type conversion for settings

master
Riyyi 3 years ago
parent
commit
adc0848a23
  1. 28
      inferno/src/inferno/io/file.cpp
  2. 14
      inferno/src/inferno/io/file.h
  3. 87
      inferno/src/inferno/settings.cpp
  4. 16
      inferno/src/inferno/settings.h

28
inferno/src/inferno/io/file.cpp

@ -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;

14
inferno/src/inferno/io/file.h

@ -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();
}
}

87
inferno/src/inferno/settings.cpp

@ -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()
void Settings::destroy()
{
nlohmann::json json;
Settings::load(json);
}
if (!Json::hasProperty(json, "window")) {
warn() << "Settings has no window section, using default values";
return;
void Settings::load()
{
json object;
try {
File::ioRead(&object, m_path);
}
catch (...) {
warn() << "Settings invalid formatting, using default values";
}
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();
auto settings = Json::getPropertyValue<SettingsProperties>(object, json::value_t::object);
if (settings) {
m_properties = settings.value();
}
}
void Settings::destroy()
bool Settings::save()
{
json object = m_properties;
File::ioWrite(&object, m_path);
info() << "Settings saved";
return true;
}
bool Settings::load(nlohmann::json& json)
// -----------------------------------------
void to_json(json& object, const SettingsProperties& settings)
{
File::ioRead(json, m_path);
object = json {
{ "window", settings.window }
};
}
return true;
void from_json(const json& object, SettingsProperties& settings)
{
if (Json::hasProperty(object, "window")) object.at("window").get_to(settings.window);
}
bool Settings::save()
void to_json(json& object, const WindowProperties& window)
{
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);
info() << "Settings saved";
object = json {
{ "title", window.title },
{ "width", window.width },
{ "height", window.height },
{ "fullscreen", window.fullscreen },
{ "vsync", window.vsync },
};
}
return true;
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);
}
}

16
inferno/src/inferno/settings.h

@ -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

Loading…
Cancel
Save