WiP: write GeneralSettings to YAML
This commit is contained in:
@@ -33,6 +33,7 @@ set(firmwares_SRCS
|
||||
edgetx/yaml_ops.cpp
|
||||
edgetx/yaml_generalsettings.cpp
|
||||
edgetx/yaml_calibdata.cpp
|
||||
edgetx/yaml_trainerdata.cpp
|
||||
edgetx/yaml_switchconfig.cpp
|
||||
edgetx/yaml_modeldata.cpp
|
||||
edgetx/yaml_rawswitch.cpp
|
||||
|
||||
@@ -31,6 +31,14 @@ static YAML::Node loadYamlFromByteArray(const QByteArray& data)
|
||||
return YAML::Load(data_istream);
|
||||
}
|
||||
|
||||
static void writeYamlToByteArray(const YAML::Node& node, QByteArray& data)
|
||||
{
|
||||
// TODO: use real streaming to avoid memory copies
|
||||
std::stringstream data_ostream;
|
||||
data_ostream << node;
|
||||
data = QByteArray::fromStdString(data_ostream.str());
|
||||
}
|
||||
|
||||
bool loadModelsListFromYaml(std::vector<CategoryData> categories,
|
||||
EtxModelfiles& modelFiles,
|
||||
const QByteArray& data)
|
||||
@@ -98,5 +106,8 @@ bool writeModelToYaml(const ModelData& model, QByteArray& data)
|
||||
|
||||
bool writeRadioSettingsToYaml(const GeneralSettings& settings, QByteArray& data)
|
||||
{
|
||||
return false;
|
||||
YAML::Node node;
|
||||
node = settings;
|
||||
writeYamlToByteArray(node, data);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -37,5 +37,5 @@ bool loadModelsListFromYaml(std::vector<CategoryData> categories,
|
||||
bool loadModelFromYaml(ModelData& model, const QByteArray& data);
|
||||
bool loadRadioSettingsFromYaml(GeneralSettings& settings, const QByteArray& data);
|
||||
|
||||
bool writeModelToByteArray(const ModelData& model, QByteArray& data);
|
||||
bool writeRadioSettingsToByteArray(const GeneralSettings& settings, QByteArray& data);
|
||||
bool writeModelToYaml(const ModelData& model, QByteArray& data);
|
||||
bool writeRadioSettingsToYaml(const GeneralSettings& settings, QByteArray& data);
|
||||
|
||||
@@ -39,11 +39,109 @@ namespace YAML {
|
||||
template<>
|
||||
struct convert<GeneralSettings> {
|
||||
|
||||
// static YAML::Node encode(const GeneralSettings& rhs) {
|
||||
// Node node;
|
||||
// // TODO: convert struct into Node
|
||||
// return node;
|
||||
// }
|
||||
static YAML::Node encode(const GeneralSettings& rhs) {
|
||||
Node node;
|
||||
|
||||
node["version"] = rhs.version;
|
||||
|
||||
// Radio calib
|
||||
// YamlCalibData calib;
|
||||
// node["calib"] = calib;
|
||||
// calib.copy(rhs.calibMid, rhs.calibSpanNeg, rhs.calibSpanPos);
|
||||
|
||||
node["currModel"] = rhs.currModelIndex;
|
||||
node["currModelFilename"] = rhs.currModelFilename;
|
||||
node["contrast"] = rhs.contrast;
|
||||
node["vBatWarn"] = rhs.vBatWarn;
|
||||
node["txVoltageCalibration"] = rhs.txVoltageCalibration;
|
||||
|
||||
node["vBatMin"] = rhs.vBatMin + 90;
|
||||
node["vBatMax"] = rhs.vBatMax + 120;
|
||||
|
||||
node["backlightMode"] = backlightModeLut << rhs.backlightMode;
|
||||
node["trainer"] = rhs.trainer;
|
||||
node["view"] = rhs.view;
|
||||
node["fai"] = rhs.fai;
|
||||
node["disableMemoryWarning"] = rhs.disableMemoryWarning;
|
||||
node["beepMode"] = rhs.beeperMode;
|
||||
node["disableAlarmWarning"] = rhs.disableAlarmWarning;
|
||||
node["disableRssiPoweroffAlarm"] = rhs.disableRssiPoweroffAlarm;
|
||||
node["USBMode"] = rhs.usbMode;
|
||||
node["jackMode"] = rhs.jackMode;
|
||||
node["hapticMode"] = rhs.hapticMode;
|
||||
node["stickMode"] = rhs.stickMode;
|
||||
node["timezone"] = rhs.timezone;
|
||||
node["adjustRTC"] = rhs.adjustRTC;
|
||||
node["inactivityTimer"] = rhs.inactivityTimer;
|
||||
node["telemetryBaudrate"] = rhs.telemetryBaudrate; // TODO: conversion???
|
||||
node["splashMode"] = rhs.splashMode; // TODO: B&W only
|
||||
node["templateSetup"] = rhs.templateSetup;
|
||||
node["hapticLength"] = rhs.hapticLength + 2;
|
||||
node["speakerPitch"] = rhs.speakerPitch * 15;
|
||||
node["hapticStrength"] = rhs.hapticStrength + 2;
|
||||
node["beepLength"] = rhs.beeperLength + 2;
|
||||
node["gpsFormat"] = rhs.gpsFormat;
|
||||
node["speakerVolume"] = rhs.speakerVolume + 12 ;
|
||||
node["backlightBright"] = rhs.backlightBright;
|
||||
node["switchesDelay"] = rhs.switchesDelay;
|
||||
node["globalTimer"] = rhs.globalTimer;
|
||||
node["bluetoothName"] = rhs.bluetoothName;
|
||||
node["bluetoothBaudrate"] = rhs.bluetoothBaudrate;
|
||||
node["bluetoothMode"] = bluetoothModeLut << rhs.bluetoothMode;
|
||||
node["countryCode"] = rhs.countryCode;
|
||||
node["jitterFilter"] = rhs.jitterFilter;
|
||||
node["disableRtcWarning"] = rhs.rtcCheckDisable; // TODO: verify
|
||||
node["keysBacklight"] = rhs.keysBacklight;
|
||||
node["imperial"] = rhs.imperial;
|
||||
node["ttsLanguage"] = rhs.ttsLanguage;
|
||||
node["beepVolume"] = rhs.beepVolume + 2;
|
||||
node["wavVolume"] = rhs.wavVolume + 2;
|
||||
node["varioVolume"] = rhs.varioVolume + 2;
|
||||
node["varioPitch"] = rhs.varioPitch * 10;
|
||||
node["varioRange"] = rhs.varioRange * 15;
|
||||
node["varioRepeat"] = rhs.varioRepeat;
|
||||
node["backgroundVolume"] = rhs.backgroundVolume + 2;
|
||||
node["auxSerialMode"] = uartModeLut << rhs.auxSerialMode;
|
||||
node["aux2SerialMode"] = uartModeLut << rhs.aux2SerialMode;
|
||||
node["antennaMode"] = antennaModeLut << rhs.antennaMode;
|
||||
node["backlightColor"] = rhs.backlightColor;
|
||||
|
||||
// if (node["customFn"]) {
|
||||
// const YAML::Node& cfn = node["customFn"];
|
||||
// for (int i = 0; i < CPN_MAX_SPECIAL_FUNCTIONS; i++) {
|
||||
// cfn[i] = rhs.customFn[i];
|
||||
// }
|
||||
// }
|
||||
|
||||
// YamlStickConfig stickConfig;
|
||||
// node["sticksConfig"] = stickConfig;
|
||||
|
||||
// YamlSwitchConfig switchConfig;
|
||||
// node["switchConfig"] = switchConfig;
|
||||
// switchConfig.copy(rhs.switchName, rhs.switchConfig);
|
||||
|
||||
// YamlPotConfig potsConfig;
|
||||
// node["potsConfig"] = potsConfig;
|
||||
// potsConfig.copy(rhs.potName, rhs.potConfig);
|
||||
|
||||
// YamlSliderConfig slidersConfig;
|
||||
// node["slidersConfig"] = slidersConfig;
|
||||
// slidersConfig.copy(rhs.sliderName, rhs.sliderConfig);
|
||||
|
||||
// Color lcd theme settings are not used in EdgeTx
|
||||
// RadioTheme::ThemeData themeData;
|
||||
|
||||
node["ownerRegistrationID"] = rhs.registrationId;
|
||||
|
||||
// Gyro (for now only xlites)
|
||||
node["gyroMax"] = rhs.gyroMax;
|
||||
node["gyroOffset"] = rhs.gyroOffset;
|
||||
|
||||
// OneBit sampling (X9D only?)
|
||||
node["uartSampleMode"] = rhs.uartSampleMode;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static bool decode(const Node& node, GeneralSettings& rhs) {
|
||||
|
||||
@@ -138,6 +236,7 @@ namespace YAML {
|
||||
|
||||
YamlStickConfig stickConfig;
|
||||
node["sticksConfig"] >> stickConfig;
|
||||
stickConfig.copy(rhs.stickName);
|
||||
|
||||
YamlSwitchConfig switchConfig;
|
||||
node["switchConfig"] >> switchConfig;
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
*/
|
||||
|
||||
#include "yaml_ops.h"
|
||||
#include <algorithm>
|
||||
|
||||
YAML::Node operator >> (const YAML::Node& node, const YamlLookupTable& lut)
|
||||
{
|
||||
@@ -54,3 +53,21 @@ void operator >> (const YAML::Node& node, bool& value)
|
||||
value = node.as<int>();
|
||||
}
|
||||
}
|
||||
|
||||
namespace YAML {
|
||||
|
||||
Node operator << (const YamlLookupTable& lut, const int& value)
|
||||
{
|
||||
const auto& it =
|
||||
find_if(lut.begin(), lut.end(), [=](const YamlLookupTableElmt& elmt) {
|
||||
if (elmt.first == value) return true;
|
||||
return false;
|
||||
});
|
||||
|
||||
if (it != lut.end()) {
|
||||
return Node(it->second);
|
||||
}
|
||||
return Node();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <yaml-cpp/yaml.h>
|
||||
#include <algorithm>
|
||||
#include <QString>
|
||||
|
||||
typedef std::pair<int, std::string> YamlLookupTableElmt;
|
||||
@@ -59,7 +60,6 @@ private:
|
||||
T factor;
|
||||
};
|
||||
|
||||
|
||||
YAML::Node operator >> (const YAML::Node& node, const YamlLookupTable& lut);
|
||||
void operator >> (const YAML::Node& node, const ioffset_int& value);
|
||||
|
||||
@@ -111,17 +111,40 @@ void operator>>(const YAML::Node& node, T (&value)[N])
|
||||
//return true;
|
||||
}
|
||||
|
||||
namespace YAML {
|
||||
|
||||
Node operator << (const YamlLookupTable& lut, const int& value);
|
||||
|
||||
template <typename T, const YamlLookupTable& lut>
|
||||
struct convert_enum
|
||||
{
|
||||
static YAML::Node encode(const T& rhs)
|
||||
{
|
||||
return lut << rhs;
|
||||
}
|
||||
static bool decode(const YAML::Node& node, T& rhs)
|
||||
{
|
||||
if (node) {
|
||||
YAML::Node conv = node >> lut;
|
||||
if (conv.IsScalar()) {
|
||||
rhs = (T)conv.as<int>();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#define ENUM_CONVERTER(enum_type, lut) \
|
||||
template <> \
|
||||
struct convert<enum_type> { \
|
||||
static YAML::Node encode(const enum_type& rhs) \
|
||||
{ \
|
||||
return convert_enum<enum_type, lut>::encode(rhs); \
|
||||
} \
|
||||
static bool decode(const YAML::Node& node, enum_type& rhs) \
|
||||
{ \
|
||||
if (node) { \
|
||||
YAML::Node conv = node >> lut; \
|
||||
if (conv.IsScalar()) { \
|
||||
rhs = (enum_type)conv.as<int>(); \
|
||||
} \
|
||||
} \
|
||||
return true; \
|
||||
return convert_enum<enum_type, lut>::decode(node, rhs); \
|
||||
} \
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "yaml_trainerdata.h"
|
||||
#include "generalsettings.h"
|
||||
|
||||
const YamlLookupTable trainerMixMode = {
|
||||
{TrainerMix::TRN_MIX_MODE_OFF, "OFF"},
|
||||
{TrainerMix::TRN_MIX_MODE_ADD, "ADD"},
|
||||
{TrainerMix::TRN_MIX_MODE_SUBST, "REPL"},
|
||||
};
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
|
||||
Node convert<TrainerMix>::encode(const TrainerMix& rhs)
|
||||
{
|
||||
Node node;
|
||||
// TODO: convert struct into Node
|
||||
return node;
|
||||
}
|
||||
|
||||
bool convert<TrainerMix>::decode(const Node& node, TrainerMix& rhs)
|
||||
{
|
||||
node["srcChn"] >> rhs.src;
|
||||
// node["mode"] >> rhs.mode; // TODO: string mapping
|
||||
node["studWeight"] >> rhs.weight;
|
||||
return true;
|
||||
}
|
||||
|
||||
Node convert<TrainerData>::encode(const TrainerData& rhs)
|
||||
{
|
||||
Node node;
|
||||
// TODO: convert struct into Node
|
||||
return node;
|
||||
}
|
||||
|
||||
bool convert<TrainerData>::decode(const Node& node, TrainerData& rhs)
|
||||
{
|
||||
if (node["calib"]) {
|
||||
const Node& calib = node["calib"];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
calib[i] >> rhs.calib[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (node["mix"]) {
|
||||
const Node& mix = node["mix"];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
mix[i] >> rhs.mix[i];
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace YAML
|
||||
@@ -21,51 +21,19 @@
|
||||
#include "yaml_ops.h"
|
||||
#include "generalsettings.h"
|
||||
|
||||
namespace YAML {
|
||||
extern const YamlLookupTable trainerMixMode;
|
||||
|
||||
template<>
|
||||
struct convert<TrainerMix> {
|
||||
namespace YAML
|
||||
{
|
||||
template <>
|
||||
struct convert<TrainerMix> {
|
||||
static Node encode(const TrainerMix& rhs);
|
||||
static bool decode(const Node& node, TrainerMix& rhs);
|
||||
};
|
||||
|
||||
// static YAML::Node encode(const TrainerMix& rhs) {
|
||||
// Node node;
|
||||
// // TODO: convert struct into Node
|
||||
// return node;
|
||||
// }
|
||||
|
||||
static bool decode(const YAML::Node& node, TrainerMix& rhs)
|
||||
{
|
||||
node["srcChn"] >> rhs.src;
|
||||
//node["mode"] >> rhs.mode; // TODO: string mapping
|
||||
node["studWeight"] >> rhs.weight;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct convert<TrainerData> {
|
||||
|
||||
// static YAML::Node encode(const TrainerData& rhs) {
|
||||
// Node node;
|
||||
// // TODO: convert struct into Node
|
||||
// return node;
|
||||
// }
|
||||
|
||||
static bool decode(const YAML::Node& node, TrainerData& rhs)
|
||||
{
|
||||
if (node["calib"]) {
|
||||
const YAML::Node& calib = node["calib"];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
calib[i] >> rhs.calib[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (node["mix"]) {
|
||||
const YAML::Node& mix = node["mix"];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
mix[i] >> rhs.mix[i];
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
template <>
|
||||
struct convert<TrainerData> {
|
||||
static Node encode(const TrainerData& rhs);
|
||||
static bool decode(const Node& node, TrainerData& rhs);
|
||||
};
|
||||
} // namespace YAML
|
||||
|
||||
@@ -220,13 +220,6 @@ bool CategorizedStorageFormat::loadYaml(RadioData & radioData)
|
||||
qDebug() << tr("Found %1").arg(filename);
|
||||
}
|
||||
|
||||
// setError(tr("Error: Yaml format ignored - under development"));
|
||||
// return false; // force failure until fully developed
|
||||
|
||||
/*
|
||||
This code a copy of loadBin with yaml file extensions ONLY
|
||||
*/
|
||||
|
||||
QByteArray radioSettingsBuffer;
|
||||
if (!loadFile(radioSettingsBuffer, "RADIO/radio.yml")) {
|
||||
setError(tr("Can't extract RADIO/radio.yml"));
|
||||
@@ -291,6 +284,10 @@ bool CategorizedStorageFormat::loadYaml(RadioData & radioData)
|
||||
|
||||
bool CategorizedStorageFormat::writeYaml(const RadioData & radioData)
|
||||
{
|
||||
setError("Error: Yaml format ignored - under development");
|
||||
return false; // force failure until fully developed
|
||||
QByteArray radioSettingsBuffer;
|
||||
if (!writeRadioSettingsToYaml(radioData.generalSettings, radioSettingsBuffer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return writeFile(radioSettingsBuffer, "RADIO/radio.yml");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user