diff --git a/device/adc_device_attribute.h b/device/adc_device_attribute.h index d21007e..94bfe49 100644 --- a/device/adc_device_attribute.h +++ b/device/adc_device_attribute.h @@ -206,10 +206,13 @@ protected: std::function _deserializerFunc; - static inline std::vector> _clearFunc{}; + // static inline std::vector> _clearFunc{}; + std::vector> _clearFunc{}; - static inline std::vector> _copyFunc{}; - static inline std::vector> _moveFunc{}; + // static inline std::vector> _copyFunc{}; + // static inline std::vector> _moveFunc{}; + std::vector> _copyFunc{}; + std::vector> _moveFunc{}; public: @@ -251,11 +254,12 @@ public: } if constexpr (!std::is_null_pointer_v && !std::is_null_pointer_v) { - _serializerFunc = [wrapper = traits::adc_pf_wrapper(std::forward(serializer)), this]() { + auto& getter_func = _getterFunc[this]; + _serializerFunc = [getter_func, wrapper = traits::adc_pf_wrapper(std::forward(serializer)), this]() { auto& serializer = std::get<0>(wrapper); - - auto val = _getterFunc[this](); + // auto val = _getterFunc[this](); + auto val = getter_func(); return serializer(val); }; @@ -263,13 +267,15 @@ public: if constexpr (!std::is_null_pointer_v && !std::is_null_pointer_v) { - _deserializerFunc = [wrapper = traits::adc_pf_wrapper(std::forward(deserializer)), + auto& setter_func = _setterFunc[this]; + _deserializerFunc = [setter_func, wrapper = traits::adc_pf_wrapper(std::forward(deserializer)), this](const SerializedT& sval) { auto& deserializer = std::get<0>(wrapper); ValueT val = deserializer(sval); - AdcDeviceAttribute::_setterFunc[this](val); + // _setterFunc[this](val); + setter_func(val); }; } @@ -379,10 +385,14 @@ public: AdcDeviceAttribute(const AdcDeviceAttribute& other) { if (&other != this) { - for (auto& fn : _copyFunc) { + // for (auto& fn : _copyFunc) { + for (auto& fn : other._copyFunc) { fn(&other, this); } + _copyFunc = other._copyFunc; + _moveFunc = other._moveFunc; + _clearFunc = other._clearFunc; _ident = other._ident; _accessType = other._accessType; @@ -394,10 +404,15 @@ public: AdcDeviceAttribute(AdcDeviceAttribute&& other) { if (&other != this) { - for (auto& fn : _moveFunc) { + // for (auto& fn : _moveFunc) { + for (auto& fn : other._moveFunc) { fn(&other, this); } + _copyFunc = std::move(other._copyFunc); + _moveFunc = std::move(other._moveFunc); + _clearFunc = std::move(other._clearFunc); + _ident = std::move(other._ident); _accessType = std::move(other._accessType); _serializerFunc = std::move(other._serializerFunc); @@ -408,9 +423,9 @@ public: virtual ~AdcDeviceAttribute() { - // for (auto& fn : _clearFunc) { - // fn(this); - // }; + for (auto& fn : _clearFunc) { + fn(this); + }; } @@ -447,7 +462,8 @@ public: auto& getter = _getterFunc.at(this); // throw out_of_range if value_t is invalid _getterFunc[this] = - [&getter, wrapper = traits::adc_pf_wrapper(std::forward(func_from_internal)), this]() { + [getter, wrapper = traits::adc_pf_wrapper(std::forward(func_from_internal)), this]() { + // auto val = _getterFunc.at(this)(); // throw out_of_range if value_t is invalid auto val = getter(); return std::get<0>(wrapper)(val); // convert from internal type }; @@ -458,10 +474,13 @@ public: if (_accessType != AdcDeviceAttribute::ReadOnly) { auto& setter = _setterFunc.at(this); // throw out_of_range if value_t is invalid - _setterFunc[this] = [&setter, + _setterFunc[this] = [setter, wrapper = traits::adc_pf_wrapper(std::forward(func_to_internal)), this](const user_t& val) { value_t value = std::get<0>(wrapper)(val); // convert to internal type + + // throw out_of_range if value_t is invalid + // _setterFunc.at(this)(value); setter(value); }; } // ignore "to_internal" conversional function for read-only attribute @@ -534,6 +553,10 @@ public: fn(&other, this); } + _copyFunc = other._copyFunc; + _moveFunc = other._moveFunc; + _clearFunc = other._clearFunc; + _ident = other._ident; _accessType = other._accessType; _serializerFunc = other._serializerFunc; @@ -551,6 +574,9 @@ public: fn(&other, this); } + _copyFunc = std::move(other._copyFunc); + _moveFunc = std::move(other._moveFunc); + _clearFunc = std::move(other._clearFunc); _ident = std::move(other._ident); _accessType = std::move(other._accessType); diff --git a/net/adc_device_netserver.h b/net/adc_device_netserver.h index 59faba7..deae86c 100644 --- a/net/adc_device_netserver.h +++ b/net/adc_device_netserver.h @@ -156,21 +156,13 @@ protected: // return serialized_t{id.begin(), id.end()}; // }; - _get_attr = [dev_ptr, wrapper = traits::adc_pf_wrapper(std::forward(attr_id_deser_func))]( - const auto& attr_name) mutable { + _get_attr = [dev_ptr, wrapper = traits::adc_pf_wrapper(std::forward(attr_id_deser_func)), + this](const auto& attr_name) mutable { auto attr_id = std::get<0>(wrapper)(attr_name); - auto& attr = (*dev_ptr)[attr_id]; + // auto& attr = (*dev_ptr)[attr_id]; + auto& attr = dev_ptr->operator[](attr_id); auto val = attr.serialize(); return val; - // auto val = (*dev_ptr)[attr_id].serialize(); - using val_t = std::remove_cvref_t; - - if constexpr (std::same_as || std::convertible_to) { - return val; - } else { - // !!!!!!!! TODO: val_t must be a char range - return serialized_t{val.begin(), val.end()}; - } }; _set_attr = [dev_ptr, wrapper = traits::adc_pf_wrapper(std::forward(attr_id_deser_func))]( diff --git a/tests/adc_asio_netserver_test.cpp b/tests/adc_asio_netserver_test.cpp index 6ac6070..201243b 100644 --- a/tests/adc_asio_netserver_test.cpp +++ b/tests/adc_asio_netserver_test.cpp @@ -9,7 +9,7 @@ #include "../net/asio/adc_device_netserver_asio.h" typedef adc::impl::AdcDeviceNetServerASIO server_t; - +typedef adc::AdcDeviceAttribute attr_t; class Device1 : public adc::AdcGenericDevice, @@ -66,8 +66,10 @@ int main(int argc, char* argv[]) // device#1 dev1.addCommand("DEV1::COM1", []() { std::cout << "EXEC DEV1::COM1\n"; }); - dev1.addAttribute( - "DEV1::ATTR1", [&dev1_val1]() { return dev1_val1; }, [&dev1_val1](const int& v) { dev1_val1 = v; }); + // dev1.addAttribute( + // "DEV1::ATTR1", [&dev1_val1]() { return dev1_val1; }, [&dev1_val1](const int& v) { dev1_val1 = v; }); + dev1.addAttribute(Device1::attribute_t::makeArithAttr( + "DEV1::ATTR1", [&dev1_val1]() { return dev1_val1; }, [&dev1_val1](const int& v) { dev1_val1 = v; })); dev1.addAttribute("DEV1::ATTR2", gt, st); @@ -75,7 +77,24 @@ int main(int argc, char* argv[]) // read-only attr dev2.addAttribute(0x1ul, [&dev1_val1]() { return dev1_val1; }); // write-only - dev2.addAttribute(0xfful, [&dev1_val1](const int& v) { dev1_val1 = v; }); + // dev2.addAttribute(0xfful, [&dev1_val1](const int& v) { dev1_val1 = v; }); + dev2.addAttribute(Device2::attribute_t::makeArithAttr(0xfful, [&dev1_val1](const int& v) { dev1_val1 = v; })); + + + double f = 7.7; + std::cout << "SET DEV1['DEV1::ATTR1'] to " << f; + dev1["DEV1::ATTR1"] = f; + std::cout << "\tRESULT ( " << dev1_val1 << " )\n"; + + dev1_val1 = 111; + std::cout << "GET DEV1['DEV1::ATTR1']"; + float fl = dev1["DEV1::ATTR1"]; + std::cout << "\tRESULT ( " << fl << " )\n"; + + f *= 3.3; + std::cout << "SET DEV2['0xff'] to " << f; + dev2[0xff] = f; + std::cout << "\tRESULT ( " << dev1_val1 << " )\n"; /* COMMANDLINE OPTS */ diff --git a/tests/adc_devattr_test.cpp b/tests/adc_devattr_test.cpp index 14d0e1b..f73858a 100644 --- a/tests/adc_devattr_test.cpp +++ b/tests/adc_devattr_test.cpp @@ -66,7 +66,7 @@ TEST_CASE("[ADC DEVICE ATTRIBUTE]") auto ar1 = ar; std::cout << "ATTR1_RO = " << (double)ar1 << "\n"; - auto ar2(ar1); + auto ar2(std::move(ar1)); std::cout << "ATTR2_RO = " << (double)ar2 << "\n"; std::cout << "ATTR2_RO_SER = " << ar2.serialize() << "\n";