finish settings
settings can now be saved / loaded at runtime settings is part of blt::graphics due to it's singular usage, TODO: is to add this to bltmain
parent
9f94b167d3
commit
f5bff5661d
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include "traits.h"
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
@ -22,31 +22,63 @@ namespace blt::graphics {
|
|||
|
||||
class Settings {
|
||||
public:
|
||||
typedef std::variant<int32_t, float, bool, std::string> property_t;
|
||||
typedef std::variant<int32_t, int64_t, float, bool, std::string> property_t;
|
||||
Settings() = default;
|
||||
Settings(std::initializer_list<std::pair<properties_t, property_t>> default_properties){
|
||||
for (const auto& v : default_properties)
|
||||
setProperty(v.first, v.second);
|
||||
}
|
||||
|
||||
~Settings() = default;
|
||||
|
||||
[[nodiscard]] const property_t* getProperty(properties_t property) const {
|
||||
[[nodiscard]] inline const property_t* getProperty(properties_t property) const {
|
||||
if (values.size() <= static_cast<int>(property))
|
||||
return nullptr;
|
||||
return &values[static_cast<int>(property)];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
[[nodiscard]] const T* getProperty(properties_t property) const {
|
||||
[[nodiscard]] inline const T* getProperty(properties_t property) const {
|
||||
if ((int)values.size() <= static_cast<int>(property))
|
||||
return nullptr;
|
||||
return &get<T>(values[static_cast<int>(property)]);
|
||||
}
|
||||
|
||||
void setProperty(properties_t property, property_t value) {
|
||||
inline void setProperty(properties_t property, property_t value) {
|
||||
if (values.capacity() <= static_cast<int>(property))
|
||||
values.resize(static_cast<int>(property) * 2);
|
||||
values[static_cast<int>(property)] = std::move(value);
|
||||
}
|
||||
|
||||
bool save(std::ofstream& out);
|
||||
bool load(std::ifstream& in);
|
||||
|
||||
private:
|
||||
std::vector<property_t> values;
|
||||
// handles saving of the variant's value
|
||||
class property_saver {
|
||||
private:
|
||||
std::ofstream& out;
|
||||
public:
|
||||
explicit property_saver(std::ofstream& out): out(out){}
|
||||
inline void operator()(int32_t i) {
|
||||
out << i;
|
||||
}
|
||||
inline void operator()(int64_t l){
|
||||
out << l;
|
||||
out << "l";
|
||||
}
|
||||
inline void operator()(float f){
|
||||
out << f;
|
||||
out << "f";
|
||||
}
|
||||
inline void operator()(bool b){
|
||||
out << b;
|
||||
out << "b";
|
||||
}
|
||||
inline void operator()(const std::string& s) {
|
||||
out << s;
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,5 +1,69 @@
|
|||
#include "blt/app.h"
|
||||
#include <blt/std/string.h>
|
||||
#include <algorithm>
|
||||
|
||||
namespace blt::graphics {
|
||||
|
||||
bool Settings::save(std::ofstream& out) {
|
||||
BLT_DEBUG("Saving settings");
|
||||
out << "# Warning: this file does not allow for comments or any form of manual modification!\n";
|
||||
out << "# All comments will be ignored, however changes will be accepted assuming the application is not running.\n";
|
||||
property_saver saver(out);
|
||||
try {
|
||||
for (size_t i = 0; i < values.size(); i++) {
|
||||
out << static_cast<int>(i);
|
||||
out << " = ";
|
||||
std::visit(saver, values[i]);
|
||||
out << '\n';
|
||||
}
|
||||
} catch (std::exception& e){
|
||||
BLT_ERROR("Error in settings save (%s)!", e.what());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Settings::load(std::ifstream& in) {
|
||||
BLT_DEBUG("Loading settings");
|
||||
try {
|
||||
size_t currentLine = 0;
|
||||
while(!(in.eof() || in.fail())){
|
||||
currentLine++;
|
||||
std::string line;
|
||||
std::getline(in, line);
|
||||
blt::string::trim(line);
|
||||
|
||||
if (line.starts_with('#') || line.empty())
|
||||
continue;
|
||||
|
||||
auto propertyToValue = blt::string::split(line, "=");
|
||||
for (auto& s : propertyToValue)
|
||||
blt::string::trim(s);
|
||||
|
||||
if (propertyToValue.size() < 2) {
|
||||
BLT_WARN("Improperly formed key = value pair! Ignoring line %d ('%s')", currentLine, line.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
auto property = static_cast<properties_t>(std::stoi(propertyToValue[0]));
|
||||
auto& value = propertyToValue[1];
|
||||
|
||||
if (std::any_of(value.begin(), value.end(), ::isdigit)){
|
||||
if (value.ends_with('l')) {
|
||||
setProperty(property, std::stoll(value.substr(0, value.size()-1)));
|
||||
} else if (value.ends_with('f')) {
|
||||
setProperty(property, std::stof(value.substr(0, value.size()-1)));
|
||||
} else if (value.ends_with('b')) {
|
||||
setProperty(property, static_cast<bool>(std::stoi(value.substr(0, value.size()-1))));
|
||||
} else
|
||||
setProperty(property, std::stoi(value));
|
||||
} else
|
||||
setProperty(property, value);
|
||||
}
|
||||
} catch (std::exception& e){
|
||||
BLT_ERROR("Error in settings load (%s)!", e.what());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue