From b53552b360392a8879cccd49798a448a68d930b3 Mon Sep 17 00:00:00 2001 From: Balazs Racz Date: Sun, 28 Jan 2024 21:41:27 +0100 Subject: [PATCH] Adds support for Offset(n) attribute in the CDI (#765) Adds support for Offset(n) attribute in the CDI for individual entries, including groups, atoms (like string) or number entries. It is also supported to declare a negative offset, which is a typical use- case when the entries are displayed out of order, or when one source data needs to be displayed in two ways. Previous Offset() was only supported on segments, which are a form of groups. With this PR, the declaration is moved up to the root class of all config entries. From then on every entry must have some form of definition. Also adjusts how the c++ constexpr generates the offset() attribute to take this into account. --- src/openlcb/ConfigRenderer.hxx | 36 ++++++++++++++++++++++++---- src/openlcb/ConfigRepresentation.hxx | 3 ++- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/openlcb/ConfigRenderer.hxx b/src/openlcb/ConfigRenderer.hxx index a401d1365..c32e55783 100644 --- a/src/openlcb/ConfigRenderer.hxx +++ b/src/openlcb/ConfigRenderer.hxx @@ -37,6 +37,7 @@ #include #include +#include #include "openlcb/SimpleNodeInfoDefs.hxx" #include "utils/OptionalArgs.hxx" @@ -52,7 +53,8 @@ struct AtomConfigDefs DECLARE_OPTIONALARG(Description, description, const char *, 1, nullptr); DECLARE_OPTIONALARG(MapValues, mapvalues, const char *, 2, nullptr); DECLARE_OPTIONALARG(SkipInit, skip_init, int, 15, 0); - using Base = OptionalArg; + DECLARE_OPTIONALARG(Offset, offset, int, 10, 0); + using Base = OptionalArg; }; /// Configuration implementation class for CDI Atom elements (strings, events @@ -72,6 +74,10 @@ public: /// When set to true, the event initializers will be skipped in this event /// or group. DEFINE_OPTIONALARG(SkipInit, skip_init, int); + /// Represents the 'offset' attribute for groups and elements and the + /// 'origin' attribute for segments. + DEFINE_OPTIONALARG(Offset, offset, int); + void render_cdi(std::string *r) const { @@ -115,6 +121,11 @@ public: { *s += StringPrintf(" size=\'%u\'", size_); } + int ofs = AtomConfigOptions(args...).offset(); + if (ofs != 0) + { + *s += StringPrintf(" offset=\'%d\'", ofs); + } *s += ">\n"; AtomConfigOptions(args...).render_cdi(s); *s += StringPrintf("\n", tag_); @@ -136,7 +147,7 @@ struct NumericConfigDefs : public AtomConfigDefs DECLARE_OPTIONALARG(Max, maxvalue, int, 7, INT_MAX); DECLARE_OPTIONALARG(Default, defaultvalue, int, 8, INT_MAX); using Base = OptionalArg; + Min, Max, Default, SkipInit, Offset>; }; /// Definitions for the options for numeric CDI entries. @@ -157,6 +168,7 @@ public: DEFINE_OPTIONALARG(Max, maxvalue, int); DEFINE_OPTIONALARG(Default, defaultvalue, int); DEFINE_OPTIONALARG(SkipInit, skip_init, int); + DEFINE_OPTIONALARG(Offset, offset, int); void render_cdi(std::string *r) const { @@ -222,6 +234,11 @@ public: { *s += StringPrintf(" size=\'%u\'", size_); } + int ofs = NumericConfigOptions(args...).offset(); + if (ofs != 0) + { + *s += StringPrintf(" offset=\'%d\'", ofs); + } *s += ">\n"; NumericConfigOptions(args...).render_cdi(s); *s += StringPrintf("\n", tag_); @@ -241,13 +258,12 @@ struct GroupConfigDefs : public AtomConfigDefs { // This is needed for inheriting declarations. using AtomConfigDefs::check_arguments_are_valid; - DECLARE_OPTIONALARG(Offset, offset, int, 10, INT_MAX); DECLARE_OPTIONALARG(Segment, segment, int, 11, -1); DECLARE_OPTIONALARG(RepName, repname, const char*, 12, nullptr); DECLARE_OPTIONALARG(FixedSize, fixed_size, unsigned, 13, 0); DECLARE_OPTIONALARG(Hidden, hidden, int, 14, 0); using Base = OptionalArg