Files
edgetx-gx12/companion/src/firmwares/edgetx/yaml_logicalswitchdata.cpp
T

212 lines
5.3 KiB
C++

/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* 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_logicalswitchdata.h"
#include "yaml_rawswitch.h"
#include "yaml_rawsource.h"
static const YamlLookupTable funcLut = {
{LS_FN_OFF, "FUNC_NONE"},
{LS_FN_VEQUAL, "FUNC_VEQUAL"},
{LS_FN_VALMOSTEQUAL, "FUNC_VALMOSTEQUAL"},
{LS_FN_VPOS, "FUNC_VPOS"},
{LS_FN_VNEG, "FUNC_VNEG"},
{LS_FN_APOS, "FUNC_APOS"},
{LS_FN_ANEG, "FUNC_ANEG"},
{LS_FN_AND, "FUNC_AND"},
{LS_FN_OR, "FUNC_OR"},
{LS_FN_XOR, "FUNC_XOR"},
{LS_FN_EDGE, "FUNC_EDGE"},
{LS_FN_EQUAL, "FUNC_EQUAL"},
{LS_FN_GREATER, "FUNC_GREATER"},
{LS_FN_LESS, "FUNC_LESS"},
{LS_FN_DPOS, "FUNC_DIFFEGREATER"},
{LS_FN_DAPOS, "FUNC_ADIFFEGREATER"},
{LS_FN_TIMER, "FUNC_TIMER"},
{LS_FN_STICKY, "FUNC_STICKY"},
};
static int timerValue2lsw(uint32_t t)
{
if (t < 20) {
return t - 129;
} else if (t < 600) {
return t / 5 - 113;
} else {
return t / 10 - 53;
}
}
// val = [-129,-110] => [0,19] (step 1)
// val = [-109,6] => [20,595] (step 5)
// val = [7,122] => [600,1750] (step 10)
//
static int lswTimerValue(int val)
{
return (val < -109 ? 129+val : (val < 7 ? (113+val)*5 : (53+val)*10));
}
namespace YAML
{
Node convert<LogicalSwitchData>::encode(const LogicalSwitchData& rhs)
{
Node node;
node["func"] = funcLut << rhs.func;
std::string def;
switch (rhs.getFunctionFamily()) {
case LS_FAMILY_VBOOL:
case LS_FAMILY_STICKY: {
def += YamlRawSwitchEncode(RawSwitch(rhs.val1));
def += ",";
def += YamlRawSwitchEncode(RawSwitch(rhs.val2));
} break;
case LS_FAMILY_EDGE: {
def += YamlRawSwitchEncode(RawSwitch(rhs.val1));
def += ",";
def += std::to_string(lswTimerValue(rhs.val2));
def += ",";
if (rhs.val3 < 0) {
def += '<';
} else if (rhs.val3 == 0) {
def += '-';
} else {
def += std::to_string(lswTimerValue(rhs.val2 + rhs.val3));
}
} break;
case LS_FAMILY_VCOMP: {
def += YamlRawSourceEncode(RawSource(rhs.val1));
def += ",";
def += YamlRawSourceEncode(RawSource(rhs.val2));
} break;
case LS_FAMILY_TIMER: {
def += std::to_string(lswTimerValue(rhs.val1));
def += ",";
def += std::to_string(lswTimerValue(rhs.val2));
} break;
default: {
def += YamlRawSourceEncode(RawSource(rhs.val1));
def += ",";
def += std::to_string(rhs.val2);
} break;
}
node["def"] = def;
node["delay"] = rhs.delay;
node["duration"] = rhs.duration;
node["andsw"] = YamlRawSwitchEncode(RawSwitch(rhs.andsw));
node["lsPersist"] = (int)rhs.lsPersist;
node["lsState"] = (int)rhs.lsState;
return node;
}
bool convert<LogicalSwitchData>::decode(const Node& node,
LogicalSwitchData& rhs)
{
node["func"] >> funcLut >> rhs.func;
std::string def_str;
node["def"] >> def_str;
std::stringstream def(def_str);
switch (rhs.getFunctionFamily()) {
case LS_FAMILY_VBOOL:
case LS_FAMILY_STICKY: {
std::string sw_str;
getline(def, sw_str, ',');
rhs.val1 = YamlRawSwitchDecode(sw_str).toValue();
getline(def, sw_str);
rhs.val2 = YamlRawSwitchDecode(sw_str).toValue();
} break;
case LS_FAMILY_EDGE: {
std::string sw_str;
getline(def, sw_str, ',');
rhs.val1 = YamlRawSwitchDecode(sw_str).toValue();
int v2=0, v3=0;
def >> v2;
rhs.val2 = timerValue2lsw(v2);
def.ignore();
if (def.peek() == '<') {
rhs.val3 = -1;
} else if (def.peek() == '-') {
rhs.val3 = 0;
} else {
def >> v3;
v3 = timerValue2lsw(v3);
rhs.val3 = v3 - rhs.val2;
}
} break;
case LS_FAMILY_VCOMP: {
std::string src_str;
getline(def, src_str, ',');
if (def_str.size() >= 4 && def_str.substr(0, 4) == "lua(") {
std::string tmp_str;
getline(def, tmp_str, ',');
src_str += ("," + tmp_str);
}
rhs.val1 = YamlRawSourceDecode(src_str).toValue();
getline(def, src_str);
rhs.val2 = YamlRawSourceDecode(src_str).toValue();
} break;
case LS_FAMILY_TIMER: {
int v1=0, v2=0;
def >> v1;
rhs.val1 = timerValue2lsw(v1);
def.ignore();
def >> v2;
rhs.val2 = timerValue2lsw(v2);
} break;
default: {
std::string src_str;
getline(def, src_str, ',');
if (def_str.size() >= 4 && def_str.substr(0, 4) == "lua(") {
std::string tmp_str;
getline(def, tmp_str, ',');
src_str += ("," + tmp_str);
}
rhs.val1 = YamlRawSourceDecode(src_str).toValue();
def >> rhs.val2;
} break;
}
node["delay"] >> rhs.delay;
node["duration"] >> rhs.duration;
RawSwitch andsw;
node["andsw"] >> andsw;
rhs.andsw = andsw.toValue();
node["lsPersist"] >> rhs.lsPersist;
node["lsState"] >> rhs.lsState;
return true;
}
} // namespace YAML