From ef2584991caa86c3a6a5cd940fe4709684b11a5c Mon Sep 17 00:00:00 2001 From: Martin Henselmeyer Date: Wed, 25 Oct 2023 13:07:59 +0200 Subject: [PATCH] runtime(DataBroker): Refine SignalDescriptor, add SignalTemplate --- runtime/include/cloe/data_broker.hpp | 246 +++++++++++++++++++------- runtime/src/cloe/data_broker_test.cpp | 63 +++++-- 2 files changed, 228 insertions(+), 81 deletions(-) diff --git a/runtime/include/cloe/data_broker.hpp b/runtime/include/cloe/data_broker.hpp index a3ae55ba4..87d92fe01 100644 --- a/runtime/include/cloe/data_broker.hpp +++ b/runtime/include/cloe/data_broker.hpp @@ -1761,87 +1761,158 @@ class DataBroker { namespace databroker { -/** - * Tags a signal - */ -template -struct SignalDescriptorBase { - using type = T; -}; -template -struct SignalDescriptorImpl : public SignalDescriptorBase { - using type = typename SignalDescriptorBase::type; - - template - static auto implement(DataBroker& db, TFirstName firstName, TNames... names) { - auto signal = TypedSignal(db.implement(firstName)); - ((db.alias(signal, names)), ...); - return signal; - } - template - static auto declare(DataBroker& db, TFirstName firstName, TNames... names) { - auto signal = TypedSignal(db.declare(firstName)); - ((db.alias(signal, names)), ...); - return signal; - } +struct DynamicName { + static constexpr bool STATIC = false; + + private: + std::string name_; + + public: + DynamicName(std::string name) : name_{name} {} + const std::string& name() const { return name_; } }; -template -struct SignalDescriptorImpl : public SignalDescriptorBase { - using type = typename SignalDescriptorBase::type; +template +struct StaticName { + static constexpr bool STATIC = true; + static constexpr const char* name() { return NAME; } +}; - static constexpr const char* Name() { return FIRSTNAME; } +/** + * SignalDescriptorBase implements a SignalDescriptor + * + * \tparam T Type of the signal + * \tparam TNAME Name of the signal + * \tparam bool true for names, false otherwise + */ +template +struct SignalDescriptorBase {}; +/** + * SignalDescriptorBase implements a SignalDescriptor, specialization for statically determined signal names + * + * \tparam T Type of the signal + * \tparam TNAME Name of the signal + */ +template +struct SignalDescriptorBase : public TNAME { + using TNAME::name; + using TNAME::TNAME; /** * Implements the signal * * \param db Instance of the DataBroker * \return Container, the container of the signal */ - static auto implement(DataBroker& db) { - auto container = db.implement(Name()); - auto signal = db.signal(Name()); - ((db.alias(signal, NAMES)), ...); - return container; - } + static auto implement(DataBroker& db) { return db.implement(name()); } /** * Declares the signal * * \param db Instance of the DataBroker * \return TypeSignal, the signal */ - static auto declare(DataBroker& db) { - auto signal = TypedSignal(db.declare(Name())); - ((db.alias(signal, NAMES)), ...); - return TypedSignal(std::move(signal)); - } - + static void declare(DataBroker& db) { db.declare(name()); } + /** + * Returns the instance of a signal. + * + * \param db Instance of the DataBroker + * \return TypedSignal, instance of the signal + */ + static auto signal(DataBroker& db) { return TypedSignal(db.signal(name())); } /** * Return the getter-function of a signal. * * \param db Instance of the DataBroker - * \return TypeSignal, the signal + * \return const Signal::typed_get_value_function_t&, getter-function of the signal + */ + static auto getter(DataBroker& db) { return db.getter(name()); } + /** + * Sets the getter-function of a signal. + * + * \param db Instance of the DataBroker + * \param get_value_fn getter-function of the signal + */ + static void set_getter(DataBroker& db, Signal::typed_get_value_function_t get_value_fn) { + db.set_getter(name(), std::move(get_value_fn)); + } + /** + * Return the setter-function of a signal. + * + * \param db Instance of the DataBroker + * \return const Signal::typed_set_value_function_t&, setter-function of the signal */ - static auto signal(DataBroker& db) { - auto signal = db.signal(Name()); - return TypedSignal(std::move(signal)); + static auto setter(DataBroker& db) { return db.setter(name()); } + /** + * Sets the setter-function of a signal. + * + * \param db Instance of the DataBroker + * \param set_value_fn setter-function of the signal + */ + static void set_setter(DataBroker& db, Signal::typed_set_value_function_t set_value_fn) { + db.set_setter(name(), std::move(set_value_fn)); } + /** + * Return the value of a signal. + * + * \param db Instance of the DataBroker + * \return Pointer to the value of the signal, nullptr if the signal does not exist + */ + static auto value(DataBroker& db) { return db.value(name()); } + /** + * Set the value of a signal. + * + * \param db Instance of the DataBroker + * \param value Value to be assigned to the signal + */ + static auto set_value(DataBroker& db, const T& value) { db.set_value(name(), value); } +}; + +/** + * SignalDescriptorBase implements a SignalDescriptor, specialization for dynamically determined signal names + * + * \tparam T Type of the signal + */ +template +struct SignalDescriptorBase : public TNAME { + using TNAME::name; + using TNAME::TNAME; + /** + * Implements the signal + * + * \param db Instance of the DataBroker + * \return Container, the container of the signal + */ + auto implement(DataBroker& db) { return db.implement(name()); } + /** + * Declares the signal + * + * \param db Instance of the DataBroker + * \return TypeSignal, the signal + */ + void declare(DataBroker& db) { db.declare(name()); } + /** + * Returns the instance of a signal. + * + * \param db Instance of the DataBroker + * \return TypedSignal, instance of the signal + */ + auto signal(DataBroker& db) { return TypedSignal(db.signal(name())); } /** * Return the getter-function of a signal. * * \param db Instance of the DataBroker - * \return const Signal::typed_get_value_function_t&, getter-function of the signal + * \return const Signal::typed_get_value_function_t&, getter-function of the signal */ - static auto getter(DataBroker& db) { return db.getter(Name()); } + auto getter(DataBroker& db) { return db.getter(name()); } /** * Sets the getter-function of a signal. * * \param db Instance of the DataBroker * \param get_value_fn getter-function of the signal */ - static void set_getter(DataBroker& db, Signal::typed_get_value_function_t get_value_fn) { - db.set_getter(Name(), std::move(get_value_fn)); + void set_getter(DataBroker& db, Signal::typed_get_value_function_t get_value_fn) { + db.set_getter(name(), std::move(get_value_fn)); } /** * Return the setter-function of a signal. @@ -1849,15 +1920,15 @@ struct SignalDescriptorImpl : public SignalDescriptorBas * \param db Instance of the DataBroker * \return const Signal::typed_set_value_function_t&, setter-function of the signal */ - static auto setter(DataBroker& db) { return db.setter(Name()); } + auto setter(DataBroker& db) { return db.setter(name()); } /** * Sets the setter-function of a signal. * * \param db Instance of the DataBroker * \param set_value_fn setter-function of the signal */ - static void set_setter(DataBroker& db, Signal::typed_set_value_function_t set_value_fn) { - db.set_setter(Name(), std::move(set_value_fn)); + void set_setter(DataBroker& db, Signal::typed_set_value_function_t set_value_fn) { + db.set_setter(name(), std::move(set_value_fn)); } /** @@ -1866,38 +1937,85 @@ struct SignalDescriptorImpl : public SignalDescriptorBas * \param db Instance of the DataBroker * \return Pointer to the value of the signal, nullptr if the signal does not exist */ - static auto value(DataBroker& db) { return db.value(Name()); } + auto value(DataBroker& db) { return db.value(name()); } /** * Set the value of a signal. * * \param db Instance of the DataBroker * \param value Value to be assigned to the signal */ - static auto set_value(DataBroker& db, const T& value) { db.set_value(value); } + auto set_value(DataBroker& db, const T& value) { db.set_value(name(), value); } +}; + +/** + * SignalDescriptorImpl implements a SignalDescriptor for names + * + * \tparam T Type of the signal + */ +template +struct SignalDescriptorImpl : public SignalDescriptorBase> { + using SignalDescriptorBase>::SignalDescriptorBase; +}; +/** + * SignalDescriptorImpl implements a SignalDescriptor for dynamic names + * + * \tparam T Type of the signal + */ +template +struct SignalDescriptorImpl : public SignalDescriptorBase { + using SignalDescriptorBase::SignalDescriptorBase; }; /** - * SignalDescriptor reflects properties of a signal at compile-time + * SignalDescriptor reflects properties of a signal at compile-/run-time * + * \tparam T Type of the signal + * \tparam NAME compile-time name, nullptr otherwise * \note: Design-Goals: * - Design-#1: Datatype of a signal shall be available at compile time * \note: Remarks: * - The declaration of a descriptor does not imply the availability of the coresponding signal at runtime. * Likewise a C/C++ header does not imply that the coresponding symbols can be resolved at runtime. */ -template -struct SignalDescriptor : public SignalDescriptorImpl { - using type = typename SignalDescriptorImpl::type; +template +struct SignalDescriptor : public SignalDescriptorImpl { + using SignalDescriptorImpl::SignalDescriptorImpl; }; -template -struct IsSignalDescriptor : std::false_type {}; -template -struct IsSignalDescriptor> : std::true_type {}; -template -constexpr bool is_signal_descriptor_v() { - return IsSignalDescriptor::value; -} +template +struct SignalTemplate : public StaticName { + private: + template