Browse Source

Implement nlohmann::json arbitrary type conversion for settings

master
Riyyi 4 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) 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;

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

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

87
inferno/src/inferno/settings.cpp

@ -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() void Settings::destroy()
{ {
nlohmann::json json; }
Settings::load(json);
if (!Json::hasProperty(json, "window")) { void Settings::load()
warn() << "Settings has no window section, using default values"; {
return; json object;
try {
File::ioRead(&object, m_path);
}
catch (...) {
warn() << "Settings invalid formatting, using default values";
} }
auto window = json["window"]; auto settings = Json::getPropertyValue<SettingsProperties>(object, json::value_t::object);
auto title = Json::parseStringProperty(window, "title", false); if (settings) {
auto width = Json::parseUnsignedProperty(window, "width", false); m_properties = settings.value();
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::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; object = json {
json["window"]["title"] = m_properties.window.title; { "title", window.title },
json["window"]["width"] = m_properties.window.width; { "width", window.width },
json["window"]["height"] = m_properties.window.height; { "height", window.height },
json["window"]["fullscreen"] = m_properties.window.fullscreen; { "fullscreen", window.fullscreen },
json["window"]["vsync"] = m_properties.window.vsync; { "vsync", window.vsync },
};
File::ioWrite(json, m_path); }
info() << "Settings saved";
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 #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

Loading…
Cancel
Save