From 8e13ad0c3cf9802931250d1aa57c68eb394add14 Mon Sep 17 00:00:00 2001 From: "Timur A. Fatkhullin" Date: Fri, 1 Nov 2024 17:26:52 +0300 Subject: [PATCH] ... --- device/adc_device.h | 26 ++-- device/adc_device_attribute.h | 222 +++++++++++++----------------- device/adc_device_concepts.h | 12 +- net/adc_device_netserver.h | 4 +- tests/adc_asio_netserver_test.cpp | 18 ++- 5 files changed, 128 insertions(+), 154 deletions(-) diff --git a/device/adc_device.h b/device/adc_device.h index 7aac2f2..c48da6d 100644 --- a/device/adc_device.h +++ b/device/adc_device.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -100,7 +101,8 @@ public: auto it = _deviceCommands.find(cmd_ident); if (it != _deviceCommands.end()) { - it->second(); + // it->second(); + it->second->operator()(); } else { throw std::system_error(AdcGenericDeviceErrorCode::ERROR_COMMAND_IDENT); } @@ -113,7 +115,8 @@ public: { auto it = _deviceAttributes.find(attr_ident); if (it != _deviceAttributes.end()) { - return it->second; + // return it->second; + return *(it->second); } throw std::system_error(AdcGenericDeviceErrorCode::ERROR_ATTR_IDENT); @@ -122,7 +125,8 @@ public: AdcGenericDevice& addCommand(CommandT&& cmd) { - _deviceCommands.insert({cmd.ident(), std::move(cmd)}); + // _deviceCommands.insert({cmd.ident(), std::move(cmd)}); + _deviceCommands.insert({cmd.ident(), std::make_unique(std::move(cmd))}); return *this; } @@ -131,10 +135,7 @@ public: template AdcGenericDevice& addCommand(CtorArgTs&&... ctor_args) { - // _deviceCommands.emplace(std::forward(ctor_args)...); return addCommand({std::forward(ctor_args)...}); - - // return *this; } AdcGenericDevice& delCommand(const cmd_ident_t& cmd_ident) @@ -147,7 +148,8 @@ public: AdcGenericDevice& addAttribute(AttributeT&& attr) { - _deviceAttributes.insert({attr.ident(), std::move(attr)}); + // _deviceAttributes.insert({attr.ident(), std::move(attr)}); + _deviceAttributes.insert({attr.ident(), std::make_unique(std::move(attr))}); return *this; } @@ -155,11 +157,7 @@ public: template AdcGenericDevice& addAttribute(CtorArgTs&&... ctor_args) { - // _deviceAttributes.emplace(std::forward(ctor_args)...); - return addAttribute({std::forward(ctor_args)...}); - - // return *this; } @@ -190,8 +188,10 @@ public: protected: IdentT _ident; - std::unordered_map _deviceAttributes; - std::unordered_map _deviceCommands; + // std::unordered_map _deviceAttributes; + // std::unordered_map _deviceCommands; + std::unordered_map> _deviceAttributes; + std::unordered_map> _deviceCommands; }; } // namespace adc diff --git a/device/adc_device_attribute.h b/device/adc_device_attribute.h index 393dc1a..c16422b 100644 --- a/device/adc_device_attribute.h +++ b/device/adc_device_attribute.h @@ -187,9 +187,11 @@ inline std::error_code make_error_code(AdcDeviceAttributeErrorCode ec) -template +template > class AdcDeviceAttribute { + static_assert(!std::is_null_pointer_v, "Deduced serialized type must not be std::nullptr_t!!!"); + protected: template using ret_value_t = std::decay_t>; @@ -200,12 +202,9 @@ protected: template inline static std::unordered_map> _setterFunc{}; - template - inline static std::unordered_map> _serializerFunc{}; + std::function _serializerFunc; - template - inline static std::unordered_map> - _deserializerFunc{}; + std::function _deserializerFunc; std::function _clearFunc; @@ -213,10 +212,18 @@ protected: std::function _moveFunc; + template + struct ValueHolder { + std::function _getterFunc; + std::function _setterFunc; + + // std::unordered_map + }; + public: typedef IdentT ident_t; - typedef std::string default_serialized_t; + typedef SerializedT serialized_t; enum AccessType { ReadOnly, WriteOnly, ReadWrite }; @@ -227,21 +234,18 @@ public: traits::adc_attr_setter_c ST, typename ValueT = traits::attr_value_t, traits::adc_serializer_c SRT = - decltype(utils::AdcDefaultValueConverter<>::serialize), + decltype(utils::AdcDefaultValueConverter<>::serialize), traits::adc_deserializer_c DSRT = - decltype(utils::AdcDefaultValueConverter<>::deserialize)> - AdcDeviceAttribute( - const IdentT& ident, - GT&& getter, - ST&& setter, - SRT&& serializer = utils::AdcDefaultValueConverter<>::serialize, - DSRT&& deserializer = utils::AdcDefaultValueConverter<>::deserialize) + decltype(utils::AdcDefaultValueConverter<>::deserialize)> + AdcDeviceAttribute(const IdentT& ident, + GT&& getter, + ST&& setter, + SRT&& serializer = utils::AdcDefaultValueConverter<>::serialize, + DSRT&& deserializer = utils::AdcDefaultValueConverter<>::deserialize) : _ident(ident), _accessType(AdcDeviceAttribute::ReadWrite) { static_assert(!std::is_null_pointer_v, "Getter and Setter can not be nullptr simultaneously!!!"); - using SerializedT = traits::adc_attr_serialized_t; - static_assert(!std::is_null_pointer_v, "Deduced serialized type must not be std::nullptr_t!!!"); _getterFunc.emplace(this, std::forward(getter)); _setterFunc.emplace(this, std::forward(setter)); @@ -255,8 +259,7 @@ public: } if constexpr (!std::is_null_pointer_v && !std::is_null_pointer_v) { - _serializerFunc[this] = [wrapper = traits::adc_pf_wrapper(std::forward(serializer)), - this]() { + _serializerFunc = [wrapper = traits::adc_pf_wrapper(std::forward(serializer)), this]() { auto& serializer = std::get<0>(wrapper); @@ -268,8 +271,8 @@ public: if constexpr (!std::is_null_pointer_v && !std::is_null_pointer_v) { - _deserializerFunc[this] = [wrapper = traits::adc_pf_wrapper(std::forward(deserializer)), - this](const SerializedT& sval) { + _deserializerFunc = [wrapper = traits::adc_pf_wrapper(std::forward(deserializer)), + this](const SerializedT& sval) { auto& deserializer = std::get<0>(wrapper); ValueT val = deserializer(sval); @@ -281,9 +284,6 @@ public: _clearFunc = [this]() { _getterFunc.erase(this); _setterFunc.erase(this); - - _serializerFunc.erase(this); - _deserializerFunc.erase(this); }; @@ -292,16 +292,10 @@ public: _getterFunc.emplace(other, _getterFunc[this]); _setterFunc.emplace(other, _setterFunc[this]); - _serializerFunc.emplace(other, _serializerFunc[this]); - _deserializerFunc.emplace(other, _deserializerFunc[this]); - // define copy-function for newly constructed object other->_copyFunc = [other](AdcDeviceAttribute* o_next) { _getterFunc.emplace(o_next, _getterFunc[other]); _setterFunc.emplace(o_next, _setterFunc[other]); - - _serializerFunc.emplace(o_next, _serializerFunc[other]); - _deserializerFunc.emplace(o_next, _deserializerFunc[other]); }; }; @@ -311,16 +305,10 @@ public: _getterFunc.emplace(other, std::move(_getterFunc[this])); _setterFunc.emplace(other, std::move(_setterFunc[this])); - _serializerFunc.emplace(other, std::move(_serializerFunc[this])); - _deserializerFunc.emplace(other, std::move(_deserializerFunc[this])); - // define move-function for newly constructed object other->_moveFunc = [other](AdcDeviceAttribute* o_next) { _getterFunc.emplace(o_next, std::move(_getterFunc[other])); _setterFunc.emplace(o_next, std::move(_setterFunc[other])); - - _serializerFunc.emplace(o_next, std::move(_serializerFunc[other])); - _deserializerFunc.emplace(o_next, std::move(_deserializerFunc[other])); }; }; } @@ -331,16 +319,15 @@ public: traits::adc_attr_setter_c ST, typename ValueT = traits::attr_value_t, traits::adc_serializer_c SRT = - decltype(utils::AdcDefaultValueConverter<>::serialize), + decltype(utils::AdcDefaultValueConverter<>::serialize), traits::adc_deserializer_c DSRT = - decltype(utils::AdcDefaultValueConverter<>::deserialize)> - AdcDeviceAttribute( - const IdentT& ident, - TupleT&&, - GT&& getter, - ST&& setter, - SRT&& serializer = utils::AdcDefaultValueConverter<>::serialize, - DSRT&& deserializer = utils::AdcDefaultValueConverter<>::deserialize) + decltype(utils::AdcDefaultValueConverter<>::deserialize)> + AdcDeviceAttribute(const IdentT& ident, + TupleT&&, + GT&& getter, + ST&& setter, + SRT&& serializer = utils::AdcDefaultValueConverter<>::serialize, + DSRT&& deserializer = utils::AdcDefaultValueConverter<>::deserialize) : AdcDeviceAttribute(ident, std::forward(getter), std::forward(setter), @@ -357,11 +344,10 @@ public: template , traits::adc_serializer_c SRT = - decltype(utils::AdcDefaultValueConverter<>::serialize), - typename SerializedT = ret_value_t> + decltype(utils::AdcDefaultValueConverter<>::serialize)> AdcDeviceAttribute(const IdentT& ident, GT&& getter, - SRT&& serializer = utils::AdcDefaultValueConverter<>::serialize) + SRT&& serializer = utils::AdcDefaultValueConverter<>::serialize) : AdcDeviceAttribute(ident, std::forward(getter), nullptr, std::forward(serializer), nullptr) { } @@ -371,12 +357,11 @@ public: std::invocable GT, typename ValueT = ret_value_t, traits::adc_serializer_c SRT = - decltype(utils::AdcDefaultValueConverter<>::serialize), - typename SerializedT = ret_value_t> + decltype(utils::AdcDefaultValueConverter<>::serialize)> AdcDeviceAttribute(const IdentT& ident, TupleT&&, GT&& getter, - SRT&& serializer = utils::AdcDefaultValueConverter<>::serialize) + SRT&& serializer = utils::AdcDefaultValueConverter<>::serialize) : AdcDeviceAttribute(ident, TupleT{}, std::forward(getter), nullptr, std::forward(serializer), nullptr) { } @@ -385,8 +370,7 @@ public: // write-only attribute constructor template >, - typename DSRT = decltype(utils::AdcDefaultValueConverter<>::deserialize), - typename SerializedT = std::decay_t>> + typename DSRT = decltype(utils::AdcDefaultValueConverter<>::deserialize)> AdcDeviceAttribute(const IdentT& ident, ST&& setter, DSRT&& deserializer = utils::AdcDefaultValueConverter<>::deserialize) @@ -398,8 +382,7 @@ public: template >, - typename DSRT = decltype(utils::AdcDefaultValueConverter<>::deserialize), - typename SerializedT = std::decay_t>> + typename DSRT = decltype(utils::AdcDefaultValueConverter<>::deserialize)> AdcDeviceAttribute(const IdentT& ident, TupleT&&, ST&& setter, @@ -416,28 +399,22 @@ public: AdcDeviceAttribute(const AdcDeviceAttribute& other) { - // _clearFunc(); - if (&other != this) { other._copyFunc(this); - } - // _clearFunc = other._clearFunc; - // _copyFunc = other._copyFunc; - // _moveFunc = other._moveFunc; + _serializerFunc = other._serializerFunc; + _deserializerFunc = other._deserializerFunc; + } } AdcDeviceAttribute(AdcDeviceAttribute&& other) { if (&other != this) { other._moveFunc(this); + + _serializerFunc = std::move(other._serializerFunc); + _deserializerFunc = std::move(other._deserializerFunc); } - - // other._clearFunc(); - - // _clearFunc = std::move(other._clearFunc); - // _copyFunc = std::move(other._copyFunc); - // _moveFunc = std::move(other._moveFunc); } @@ -516,6 +493,15 @@ public: _getterFunc.emplace(other, _getterFunc[this]); _setterFunc.emplace(other, _setterFunc[this]); + + // redefine copy-function for newly constructed instance + // other._copyFunc was defined in the 'prev_copy(other)' call above + other->_moveFunc = [other, copy_f = other->_copyFunc](AdcDeviceAttribute* o_next) { + copy_f(o_next); + + _getterFunc.emplace(o_next, _getterFunc[other]); + _setterFunc.emplace(o_next, _setterFunc[other]); + }; }; // move TO other @@ -524,6 +510,15 @@ public: _getterFunc.emplace(other, std::move(_getterFunc[this])); _setterFunc.emplace(other, std::move(_setterFunc[this])); + + // redefine move-function for newly constructed instance + // other._moveFunc was defined in the 'prev_move(other)' call above + other->_moveFunc = [other, move_f = other->_moveFunc](AdcDeviceAttribute* o_next) { + move_f(o_next); + + _getterFunc.emplace(o_next, std::move(_getterFunc[other])); + _setterFunc.emplace(o_next, std::move(_setterFunc[other])); + }; }; return *this; @@ -543,13 +538,6 @@ public: } catch (const std::out_of_range&) { throw std::system_error(AdcDeviceAttributeErrorCode::ERROR_NO_CONV_FUNC); } - - // auto& getter = _getterFunc[this]; - // if (getter) { - // return getter(); - // } - - // throw std::system_error(AdcDeviceAttributeErrorCode::ERROR_NO_CONV_FUNC); } template @@ -567,13 +555,6 @@ public: throw std::system_error(AdcDeviceAttributeErrorCode::ERROR_NO_CONV_FUNC); } - // auto& setter = _setterFunc[this]; - // if (setter) { - // setter(std::forward(val)); - // } else { - // throw std::system_error(AdcDeviceAttributeErrorCode::ERROR_NO_CONV_FUNC); - // } - return *this; } @@ -581,13 +562,10 @@ public: AdcDeviceAttribute& operator=(const AdcDeviceAttribute& other) { if (&other != this) { - // _clearFunc(); - other._copyFunc(this); - // _clearFunc = other._clearFunc; - // _copyFunc = other._copyFunc; - // _moveFunc = other._moveFunc; + _serializerFunc = other._serializerFunc; + _deserializerFunc = other._deserializerFunc; } return *this; @@ -597,73 +575,61 @@ public: AdcDeviceAttribute& operator=(AdcDeviceAttribute&& other) { if (&other != this) { - // _clearFunc(); - other._moveFunc(this); - // _clearFunc = std::move(other._clearFunc); - // _copyFunc = std::move(other._copyFunc); - // _moveFunc = std::move(other._moveFunc); + _serializerFunc = std::move(other._serializerFunc); + _deserializerFunc = std::move(other._deserializerFunc); } return *this; } - template - SerializedT serialize() + serialized_t serialize() { if (_accessType == AdcDeviceAttribute::WriteOnly) { throw std::system_error(AdcDeviceAttributeErrorCode::ERROR_WRITE_ONLY); } - using s_t = std::decay_t; - - try { - _serializerFunc.at(this)(); - } catch (const std::out_of_range&) { - throw std::system_error(AdcDeviceAttributeErrorCode::ERROR_INVALID_SERIALIZED_TYPE); - } catch (const std::bad_function_call&) { // serializer was not defined in ctor! - throw std::system_error(AdcDeviceAttributeErrorCode::ERROR_NO_SERIALIZER); - } - - // auto& serializer = _serializerFunc[this]; - - // if (serializer) { - // return serializer(); - // } - - // throw std::system_error(AdcDeviceAttributeErrorCode::ERROR_INVALID_SERIALIZED_TYPE); + return _serializerFunc(); } - default_serialized_t serialize() + template + requires(!std::convertible_to>) + ST serialize() { - return serialize(); + using s_t = std::decay_t; + + if constexpr (traits::adc_output_char_range && traits::adc_output_char_range) { + s_t res; + std::ranges::copy(serialize(), std::back_inserter(res)); + } else { + static_assert(false, "INVALID USER SERIALIZATION TYPE!"); + } } - template - AdcDeviceAttribute& deserialize(const SerializedT& sval) + AdcDeviceAttribute& deserialize(const serialized_t& sval) { if (_accessType == AdcDeviceAttribute::ReadOnly) { throw std::system_error(AdcDeviceAttributeErrorCode::ERROR_READ_ONLY); } - using s_t = std::decay_t; + _deserializerFunc(sval); - try { - _deserializerFunc.at(this)(sval); - } catch (const std::out_of_range&) { - throw std::system_error(AdcDeviceAttributeErrorCode::ERROR_INVALID_SERIALIZED_TYPE); - } catch (const std::bad_function_call&) { // deserializer was not defined in ctor! - throw std::system_error(AdcDeviceAttributeErrorCode::ERROR_NO_DESERIALIZER); + return *this; + } + + template + requires(!std::convertible_to, serialized_t>) + AdcDeviceAttribute& deserialize(const ST& sval) + { + using s_t = std::decay_t; + + if constexpr (traits::adc_input_char_range && traits::adc_input_char_range) { + _deserializerFunc(serialized_t(sval.begin(), sval.end())); + } else { + static_assert(false, "INVALID USER SERIALIZATION TYPE!"); } - // auto& deserializer = _deserializerFunc[this]; - // if (deserializer) { - // deserializer(sval); - // } else { - // throw std::system_error(AdcDeviceAttributeErrorCode::ERROR_INVALID_SERIALIZED_TYPE); - // } - return *this; } diff --git a/device/adc_device_concepts.h b/device/adc_device_concepts.h index 02743e6..34716f4 100644 --- a/device/adc_device_concepts.h +++ b/device/adc_device_concepts.h @@ -7,21 +7,21 @@ namespace adc::interfaces // ADC device attribute concept template -concept adc_device_attr_c = requires(T t, const T const_t) { +concept adc_device_attr_c = std::movable && requires(T t, const T const_t) { typename T::ident_t; - typename T::default_serialized_t; + typename T::serialized_t; { const_t.ident() } -> std::same_as; - // serializer and desiarializer must return/accept at least a value of type T::default_serialized_t - { t.serialize() } -> std::convertible_to; - t.deserialize(std::declval()); + // serializer and deserializer must return/accept at least a value of type T::serialized_t + { t.serialize() } -> std::convertible_to; + t.deserialize(std::declval()); }; // ADC device command concept template -concept adc_device_cmd_c = requires(T t, const T const_t) { +concept adc_device_cmd_c = std::movable && requires(T t, const T const_t) { typename T::ident_t; { const_t.ident() } -> std::same_as; diff --git a/net/adc_device_netserver.h b/net/adc_device_netserver.h index 761ee29..d9f8613 100644 --- a/net/adc_device_netserver.h +++ b/net/adc_device_netserver.h @@ -159,6 +159,8 @@ protected: _get_attr = [dev_ptr, wrapper = traits::adc_pf_wrapper(std::forward(attr_id_deser_func))]( const auto& attr_name) mutable { auto attr_id = std::get<0>(wrapper)(attr_name); + // auto attr = (*dev_ptr)[attr_id]; + // auto val = attr.serialize(); auto val = (*dev_ptr)[attr_id].serialize(); using val_t = std::remove_cvref_t; @@ -316,7 +318,7 @@ public: } } if (found) { - msg.ack(); + msg.ack(attrs); } else { msg.err(std::make_error_code(AdcDeviceNetServerSessionError::ERROR_UNKNOWN_DEVICE_ID)); } diff --git a/tests/adc_asio_netserver_test.cpp b/tests/adc_asio_netserver_test.cpp index e3761ea..6ac6070 100644 --- a/tests/adc_asio_netserver_test.cpp +++ b/tests/adc_asio_netserver_test.cpp @@ -8,12 +8,16 @@ #include "../net/adc_netproto.h" #include "../net/asio/adc_device_netserver_asio.h" +typedef adc::impl::AdcDeviceNetServerASIO server_t; + class Device1 : public adc::AdcGenericDevice, + adc::AdcDeviceAttribute, adc::AdcDeviceCommand> { - typedef adc::AdcGenericDevice, adc::AdcDeviceCommand> + typedef adc::AdcGenericDevice, + adc::AdcDeviceCommand> base_t; public: @@ -23,10 +27,13 @@ public: } }; -class Device2 - : public adc::AdcGenericDevice, adc::AdcDeviceCommand> +class Device2 : public adc::AdcGenericDevice, + adc::AdcDeviceCommand> { - typedef adc::AdcGenericDevice, adc::AdcDeviceCommand> + typedef adc::AdcGenericDevice, + adc::AdcDeviceCommand> base_t; public: @@ -106,7 +113,6 @@ int main(int argc, char* argv[]) asio::signal_set signals(io_ctx, SIGINT, SIGTERM); signals.async_wait([&](std::error_code, int) { io_ctx.stop(); }); - using server_t = adc::impl::AdcDeviceNetServerASIO; adc::impl::AdcDeviceNetServerASIO server("TEST SRV", io_ctx); server.setupSignals();