Improved mixer source (de-)serialization

This commit is contained in:
Raphael Coeffic
2021-11-10 11:07:02 +01:00
parent b7640a830f
commit 4ee58045e1
35 changed files with 394 additions and 131 deletions
@@ -70,15 +70,108 @@ static bool in_write_weight(const YamlNode* node, uint32_t val, yaml_writer_func
extern const struct YamlIdStr enum_MixSources[];
// TODO sources: parse/output
// - lua(script#,n): LUA mix outputs
// - ls(n): logical switches
// - tr(n): trainer input
// - ch(n): channels
// - gv(n): gvars
// - tele(n): telemetry
//
static uint32_t r_mixSrcRaw(const YamlNode* node, const char* val, uint8_t val_len)
{
if (val_len > 0 && val[0] == 'I') {
return yaml_str2uint(val+1, val_len-1) + MIXSRC_FIRST_INPUT;
} else if (val_len > 4 &&
val[0] == 'l' &&
val[1] == 'u' &&
val[2] == 'a' &&
val[3] == '(') {
// parse int and ignore ','
val += 4; val_len -= 4;
uint8_t script = yaml_str2uint(val, val_len);
if (!val_len) return MIXSRC_NONE;
val++; val_len--;
// parse int and ignore closing ')'
return yaml_str2uint(val, val_len) + MIXSRC_FIRST_LUA +
script * MAX_SCRIPT_OUTPUTS;
} else if (val_len > 3 &&
val[0] == 'l' &&
val[1] == 's' &&
val[2] == '(') {
val += 3; val_len -= 3;
// parse int and ignore closing ')'
return yaml_str2uint(val, val_len) + MIXSRC_FIRST_LOGICAL_SWITCH;
} else if (val_len > 3 &&
val[0] == 't' &&
val[1] == 'r' &&
val[2] == '(') {
val += 3; val_len -= 3;
// parse int and ignore closing ')'
return yaml_str2uint(val, val_len) + MIXSRC_FIRST_TRAINER;
} else if (val_len > 3 &&
val[0] == 'c' &&
val[1] == 'h' &&
val[2] == '(') {
val += 3; val_len -= 3;
// parse int and ignore closing ')'
return yaml_str2uint_ref(val, val_len) + MIXSRC_FIRST_CH;
} else if (val_len > 3 &&
val[0] == 'g' &&
val[1] == 'v' &&
val[2] == '(') {
val += 3; val_len -= 3;
// parse int and ignore closing ')'
return yaml_str2uint_ref(val, val_len) + MIXSRC_FIRST_GVAR;
} else if (val_len > 5 &&
val[0] == 't' &&
val[1] == 'e' &&
val[2] == 'l' &&
val[3] == 'e' &&
val[4] == '(') {
val += 5; val_len -= 5;
// parse sign
uint8_t sign = 0;
if (*val == '-') {
sign = 1;
val++; val_len--;
} else if (*val == '+') {
sign = 2;
val++; val_len--;
}
// parse int and ignore closing ')'
return yaml_str2uint_ref(val, val_len) * 3 + sign + MIXSRC_FIRST_TELEM;
}
return yaml_parse_enum(enum_MixSources, val, val_len);
}
static constexpr char closing_parenthesis[] = ")";
static bool output_source_1_param(const char* src_prefix, size_t src_len, uint32_t n,
yaml_writer_func wf, void* opaque)
{
if (!wf(opaque, src_prefix, src_len)) return false;
const char* str = yaml_unsigned2str(n);
if (!wf(opaque, str, strlen(str))) return false;
return true;
}
static bool w_mixSrcRaw(const YamlNode* node, uint32_t val, yaml_writer_func wf, void* opaque)
{
const char* str = nullptr;
@@ -91,6 +184,69 @@ static bool w_mixSrcRaw(const YamlNode* node, uint32_t val, yaml_writer_func wf,
str = yaml_unsigned2str(val - MIXSRC_FIRST_INPUT);
}
#if defined(LUA_INPUTS)
else if (val >= MIXSRC_FIRST_LUA
&& val <= MIXSRC_LAST_LUA) {
if (!wf(opaque, "lua(", 4)) return false;
val -= MIXSRC_FIRST_LUA;
uint32_t script = val / MAX_SCRIPT_OUTPUTS;
if (!output_source_1_param("lua(", 4, script, wf, opaque)) return false;
if (!wf(opaque, ",", 1)) return false;
val = val % MAX_SCRIPT_OUTPUTS;
str = yaml_unsigned2str(val);
if (!wf(opaque, str, strlen(str))) return false;
str = closing_parenthesis;
}
#endif
else if (val >= MIXSRC_FIRST_LOGICAL_SWITCH
&& val <= MIXSRC_LAST_LOGICAL_SWITCH) {
val -= MIXSRC_FIRST_LOGICAL_SWITCH;
if (!output_source_1_param("ls(", 3, val, wf, opaque)) return false;
str = closing_parenthesis;
}
else if (val >= MIXSRC_FIRST_TRAINER
&& val <= MIXSRC_LAST_TRAINER) {
val -= MIXSRC_FIRST_TRAINER;
if (!output_source_1_param("tr(", 3, val, wf, opaque)) return false;
str = closing_parenthesis;
}
else if (val >= MIXSRC_FIRST_CH
&& val <= MIXSRC_LAST_CH) {
val -= MIXSRC_FIRST_CH;
if (!output_source_1_param("ch(", 3, val, wf, opaque)) return false;
str = closing_parenthesis;
}
else if (val >= MIXSRC_FIRST_GVAR
&& val <= MIXSRC_LAST_GVAR) {
val -= MIXSRC_FIRST_GVAR;
if (!output_source_1_param("gv(", 3, val, wf, opaque)) return false;
str = closing_parenthesis;
}
else if (val >= MIXSRC_FIRST_TELEM
&& val <= MIXSRC_LAST_TELEM) {
val -= MIXSRC_FIRST_TELEM;
uint8_t sign = val % 3;
val = val / 3;
if (!wf(opaque, "tele(", 5)) return false;
if (sign == 1) {
if (!wf(opaque, "-", 1)) return false;
} else if (sign == 2) {
if (!wf(opaque, "+", 1)) return false;
}
str = yaml_unsigned2str(val);
if (!wf(opaque, str, strlen(str))) return false;
str = closing_parenthesis;
}
else {
str = yaml_output_enum(val, enum_MixSources);
}