From 072cff9524b590f66c83f514f11d5c7cb1e0f50a Mon Sep 17 00:00:00 2001 From: HRS Date: Sun, 15 Feb 2026 10:27:21 +0100 Subject: [PATCH 1/3] Make getter return value optional --- examples/basic/src/main.cpp | 12 ++++++------ src/SlvCtrlProtocol.h | 25 ++++++++++++------------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/examples/basic/src/main.cpp b/examples/basic/src/main.cpp index b6ce69d..f3aa94e 100644 --- a/examples/basic/src/main.cpp +++ b/examples/basic/src/main.cpp @@ -13,20 +13,20 @@ static const char* mode = "off"; // --------- getters/setters (C function pointers) ---------- // Note: your attribute classes use function pointers: T(*)(void*), not lambdas. -static int32_t getSpeed(void*) { return speed; } +static std::optional getSpeed(void*) { return speed; } static SlvCtrlParseError setSpeed(void*, int32_t v) { speed = v; return SlvCtrlParseError::Ok; } -static int32_t getMaxSpeed(void*) { return maxSpeed; } +static std::optional getMaxSpeed(void*) { return maxSpeed; } static SlvCtrlParseError setMaxSpeed(void*, int32_t v) { maxSpeed = v; return SlvCtrlParseError::Ok; } -static int32_t getState(void*) { return state; } +static std::optional getState(void*) { return state; } static SlvCtrlParseError setState(void*, int32_t v) { state = v; return SlvCtrlParseError::Ok; } -static bool getReady(void*) { return ready; } +static std::optional getReady(void*) { return ready; } -static int32_t getBaud(void*) { return baud; } +static std::optional getBaud(void*) { return baud; } -static const char* getMode(void*) { return mode; } +static std::optional getMode(void*) { return mode; } static SlvCtrlParseError setMode(void*, const char* v) { mode = v; return SlvCtrlParseError::Ok; } // --------- attributes ---------- diff --git a/src/SlvCtrlProtocol.h b/src/SlvCtrlProtocol.h index 07a206a..06dc129 100644 --- a/src/SlvCtrlProtocol.h +++ b/src/SlvCtrlProtocol.h @@ -1,8 +1,9 @@ #pragma once +#include +#include #include #include -#include #include #include #include @@ -79,7 +80,7 @@ struct IAttribute { template class BaseAttribute : public IAttribute { public: - using Getter = T (*)(void* ctx); + using Getter = std::optional (*)(void* ctx); using Setter = SlvCtrlParseError (*)(void* ctx, T value); BaseAttribute(const char* name, Getter g, Setter s, void* ctx = nullptr) : name_(name), ctx_(ctx), getter_(g), setter_(s) { @@ -97,8 +98,8 @@ class BaseAttribute : public IAttribute { return SlvCtrlAccess::INVALID; } - T getValue() const { - return getter_ ? getter_(ctx_) : T{}; + std::optional getValue() const { + return getter_ ? getter_(ctx_) : std::nullopt; } SlvCtrlParseError setValue(T value) { @@ -107,7 +108,10 @@ class BaseAttribute : public IAttribute { } void writeValue(ISlvCtrlOut& out) const override { - out.write(this->getValue()); + auto val = getValue(); + if (val.has_value()) { + out.write(val.value()); + } } private: @@ -120,7 +124,7 @@ class BaseAttribute : public IAttribute { class IntAttribute : public BaseAttribute { public: IntAttribute(const char* name, Getter getter, Setter setter, void* ctx = nullptr) - : BaseAttribute(name, getter, setter, ctx) {} + : BaseAttribute(name, getter, setter, ctx) {} SlvCtrlParseError setFromCString(const char* s) override { if (!s) return SlvCtrlParseError::MissingValue; @@ -140,7 +144,7 @@ class IntAttribute : public BaseAttribute { class FloatAttribute : public BaseAttribute { public: FloatAttribute(const char* name, Getter getter, Setter setter, void* ctx = nullptr) - : BaseAttribute(name, getter, setter, ctx) {} + : BaseAttribute(name, getter, setter, ctx) {} SlvCtrlParseError setFromCString(const char* s) override { if (!s) return SlvCtrlParseError::MissingValue; @@ -159,7 +163,7 @@ class FloatAttribute : public BaseAttribute { class BoolAttribute : public BaseAttribute { public: BoolAttribute(const char* name, Getter getter, Setter setter, void* ctx = nullptr) - : BaseAttribute(name, getter, setter, ctx) {} + : BaseAttribute(name, getter, setter, ctx) {} SlvCtrlParseError setFromCString(const char* s) override { if (!s) return SlvCtrlParseError::MissingValue; @@ -340,11 +344,6 @@ class StrAttribute : public BaseAttribute { out.write(slvCtrlAccessToString(access())); out.write("[str]"); } - - void writeValue(ISlvCtrlOut& out) const override { - const char* s = this->getValue(); - out.write(s ? s : ""); - } }; // ---- Protocol ---- From 02abeaad9c5f72d33a2989090a1ea94d867e3eb5 Mon Sep 17 00:00:00 2001 From: HRS Date: Sun, 15 Feb 2026 10:37:06 +0100 Subject: [PATCH 2/3] Fix outdated writeValue for BoolAttribute --- src/SlvCtrlProtocol.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/SlvCtrlProtocol.h b/src/SlvCtrlProtocol.h index 06dc129..5a0f312 100644 --- a/src/SlvCtrlProtocol.h +++ b/src/SlvCtrlProtocol.h @@ -178,7 +178,9 @@ class BoolAttribute : public BaseAttribute { } void writeValue(ISlvCtrlOut& out) const override { - out.write(this->getValue() ? "true" : "false"); + auto val = this->getValue(); + if (!val.has_value()) return; + out.write(val.value() ? "true" : "false"); } }; From 176aff286c95804cbd9732858905a0afb932e134 Mon Sep 17 00:00:00 2001 From: HRS Date: Sun, 15 Feb 2026 11:07:42 +0100 Subject: [PATCH 3/3] Add an optional example --- examples/basic/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/basic/src/main.cpp b/examples/basic/src/main.cpp index f3aa94e..1866a02 100644 --- a/examples/basic/src/main.cpp +++ b/examples/basic/src/main.cpp @@ -19,7 +19,7 @@ static SlvCtrlParseError setSpeed(void*, int32_t v) { speed = v; return SlvCtrlP static std::optional getMaxSpeed(void*) { return maxSpeed; } static SlvCtrlParseError setMaxSpeed(void*, int32_t v) { maxSpeed = v; return SlvCtrlParseError::Ok; } -static std::optional getState(void*) { return state; } +static std::optional getState(void*) { return ready ? std::make_optional(state) : std::nullopt; } static SlvCtrlParseError setState(void*, int32_t v) { state = v; return SlvCtrlParseError::Ok; } static std::optional getReady(void*) { return ready; }