107 lines
2.6 KiB
C++
107 lines
2.6 KiB
C++
#include "config.h"
|
|
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <algorithm>
|
|
|
|
#include <stdlib.h> // realpath
|
|
#include <libgen.h> // dirname
|
|
|
|
#include <nlohmann/json.hpp>
|
|
using json = nlohmann::json;
|
|
|
|
#include <Log.h>
|
|
|
|
template<typename T>
|
|
static void readVector(std::vector<T>& v, const json& j) {
|
|
v.clear();
|
|
v.reserve(j.size());
|
|
std::copy(j.begin(), j.end(), std::insert_iterator<std::vector<T>>(v, v.begin()));
|
|
}
|
|
|
|
Config::Config(const std::string binaryArgument) {
|
|
char* buff = realpath(binaryArgument.c_str(), NULL); // buff needs free !
|
|
//ssize_t read = readlink(binaryArgument.c_str(), buf, MAXBUF);
|
|
if(buff) {
|
|
// success
|
|
char* binPath = dirname(buff);
|
|
binaryPath = std::string(binPath) + '/';
|
|
free(buff);
|
|
} else {
|
|
// error
|
|
Log::error << "unable to read path of the binaryFile";
|
|
}
|
|
}
|
|
|
|
Config::~Config() {
|
|
}
|
|
|
|
void from_json(const json& j, Config::AudioConfig& ac) {
|
|
readVector(ac.devices, j.value("devices", json::array()));
|
|
}
|
|
|
|
void from_json(const json& j, Config::SampleConfig& sc) {
|
|
sc.file = j.value("file", "");
|
|
sc.offset = j.value("offset", 0);
|
|
sc.length = j.value("length", 0);
|
|
sc.volume = j.value("volume", 1.f);
|
|
}
|
|
|
|
void from_json(const json& j, Config::ButtonConfig& bc) {
|
|
bc.name = j.value("name", "");
|
|
bc.key = j.value("key", "");
|
|
bc.width = j.value("width", 6);
|
|
|
|
// make it possible to volume control all samples from one value
|
|
float volume = j.value("value", 1.0);
|
|
|
|
if(j.contains("samples")) {
|
|
// sample liste
|
|
readVector(bc.samples, j["samples"]);
|
|
for(Config::SampleConfig& sc : bc.samples) {
|
|
sc.volume *= volume;
|
|
}
|
|
} else if(j.contains("file")) {
|
|
bc.samples.push_back(j); // implizit cast
|
|
}
|
|
}
|
|
|
|
void from_json(const json& j, Config::RootConfig& rc) {
|
|
rc.audio = j.value<Config::AudioConfig>("audio", {});
|
|
json barr = j.value("buttons", json::array());
|
|
if(barr.is_array() && !barr.empty()) {
|
|
rc.buttons.reserve(barr.size());
|
|
for(const json& line : barr) {
|
|
std::vector<Config::ButtonConfig> btns;
|
|
readVector(btns, line);
|
|
rc.buttons.push_back(btns);
|
|
}
|
|
}
|
|
rc.audioPath = j.value("audioPath", "");
|
|
}
|
|
|
|
bool Config::SampleConfig::isValid() const {
|
|
return !file.empty();
|
|
}
|
|
|
|
bool Config::ButtonConfig::isValid() const {
|
|
bool validfound = std::any_of(samples.begin(), samples.end(), [](const SampleConfig& sc){ return sc.isValid(); });
|
|
return !samples.empty() && !name.empty() && validfound;
|
|
}
|
|
|
|
void Config::load() {
|
|
std::ifstream stream(binaryPath + file);
|
|
json json;
|
|
if(stream) {
|
|
try {
|
|
stream >> json;
|
|
rootConfig = json;
|
|
} catch(nlohmann::detail::parse_error& pe) {
|
|
std::cout << "json error: " << pe.what() << std::endl;
|
|
return;
|
|
}
|
|
} else {
|
|
Log::error << "config File not found";
|
|
}
|
|
}
|