This commit is contained in:
Timur A. Fatkhullin 2024-11-02 00:58:25 +03:00
parent 8e13ad0c3c
commit 2f46b08c8e
4 changed files with 81 additions and 88 deletions

View File

@ -206,20 +206,12 @@ protected:
std::function<void(const SerializedT&)> _deserializerFunc; std::function<void(const SerializedT&)> _deserializerFunc;
std::function<void()> _clearFunc; static inline std::vector<std::function<void(AdcDeviceAttribute*)>> _clearFunc{};
std::function<void(AdcDeviceAttribute*)> _copyFunc; static inline std::vector<std::function<void(const AdcDeviceAttribute*, AdcDeviceAttribute*)>> _copyFunc{};
std::function<void(AdcDeviceAttribute*)> _moveFunc; static inline std::vector<std::function<void(AdcDeviceAttribute*, AdcDeviceAttribute*)>> _moveFunc{};
template <typename VT>
struct ValueHolder {
std::function<VT()> _getterFunc;
std::function<void(const VT&)> _setterFunc;
// std::unordered_map<const AdcDeviceAttribute*>
};
public: public:
typedef IdentT ident_t; typedef IdentT ident_t;
@ -277,40 +269,27 @@ public:
ValueT val = deserializer(sval); ValueT val = deserializer(sval);
_setterFunc<ValueT>[this](val); AdcDeviceAttribute::_setterFunc<ValueT>[this](val);
}; };
} }
_clearFunc = [this]() { _clearFunc.emplace_back([](AdcDeviceAttribute* inst) {
_getterFunc<ValueT>.erase(this); _getterFunc<ValueT>.erase(inst);
_setterFunc<ValueT>.erase(this); _setterFunc<ValueT>.erase(inst);
}; });
// copy TO other // copy instance function
_copyFunc = [this](AdcDeviceAttribute* other) { _copyFunc.emplace_back([](const AdcDeviceAttribute* from, AdcDeviceAttribute* to) {
_getterFunc<ValueT>.emplace(other, _getterFunc<ValueT>[this]); _getterFunc<ValueT>.emplace(to, _getterFunc<ValueT>[from]);
_setterFunc<ValueT>.emplace(other, _setterFunc<ValueT>[this]); _setterFunc<ValueT>.emplace(to, _setterFunc<ValueT>[from]);
});
// define copy-function for newly constructed object // move instance function
other->_copyFunc = [other](AdcDeviceAttribute* o_next) { _moveFunc.emplace_back([](AdcDeviceAttribute* from, AdcDeviceAttribute* to) {
_getterFunc<ValueT>.emplace(o_next, _getterFunc<ValueT>[other]); _getterFunc<ValueT>.emplace(to, std::move(_getterFunc<ValueT>[from]));
_setterFunc<ValueT>.emplace(o_next, _setterFunc<ValueT>[other]); _setterFunc<ValueT>.emplace(to, std::move(_setterFunc<ValueT>[from]));
}; });
};
// move TO other
_moveFunc = [this](AdcDeviceAttribute* other) {
_getterFunc<ValueT>.emplace(other, std::move(_getterFunc<ValueT>[this]));
_setterFunc<ValueT>.emplace(other, std::move(_setterFunc<ValueT>[this]));
// define move-function for newly constructed object
other->_moveFunc = [other](AdcDeviceAttribute* o_next) {
_getterFunc<ValueT>.emplace(o_next, std::move(_getterFunc<ValueT>[other]));
_setterFunc<ValueT>.emplace(o_next, std::move(_setterFunc<ValueT>[other]));
};
};
} }
@ -400,8 +379,13 @@ public:
AdcDeviceAttribute(const AdcDeviceAttribute& other) AdcDeviceAttribute(const AdcDeviceAttribute& other)
{ {
if (&other != this) { if (&other != this) {
other._copyFunc(this); for (auto& fn : _copyFunc) {
fn(&other, this);
}
_ident = other._ident;
_accessType = other._accessType;
_serializerFunc = other._serializerFunc; _serializerFunc = other._serializerFunc;
_deserializerFunc = other._deserializerFunc; _deserializerFunc = other._deserializerFunc;
} }
@ -410,8 +394,12 @@ public:
AdcDeviceAttribute(AdcDeviceAttribute&& other) AdcDeviceAttribute(AdcDeviceAttribute&& other)
{ {
if (&other != this) { if (&other != this) {
other._moveFunc(this); for (auto& fn : _moveFunc) {
fn(&other, this);
}
_ident = std::move(other._ident);
_accessType = std::move(other._accessType);
_serializerFunc = std::move(other._serializerFunc); _serializerFunc = std::move(other._serializerFunc);
_deserializerFunc = std::move(other._deserializerFunc); _deserializerFunc = std::move(other._deserializerFunc);
} }
@ -420,7 +408,9 @@ public:
virtual ~AdcDeviceAttribute() virtual ~AdcDeviceAttribute()
{ {
// _clearFunc(); // for (auto& fn : _clearFunc) {
// fn(this);
// };
} }
@ -479,47 +469,24 @@ public:
throw std::system_error(AdcDeviceAttributeErrorCode::ERROR_INTERNAL_TYPE_MISMATCH); throw std::system_error(AdcDeviceAttributeErrorCode::ERROR_INTERNAL_TYPE_MISMATCH);
} }
_clearFunc = [prev_clear = _clearFunc, this]() { _clearFunc.emplace_back([](AdcDeviceAttribute* inst) {
prev_clear(); _getterFunc<user_t>.erase(inst);
_setterFunc<user_t>.erase(inst);
_getterFunc<user_t>.erase(this); });
_setterFunc<user_t>.erase(this);
};
// copy TO other // copy instance functions
_copyFunc = [prev_copy = _copyFunc, this](AdcDeviceAttribute* other) { _copyFunc.emplace_back([](const AdcDeviceAttribute* from, AdcDeviceAttribute* to) {
prev_copy(other); _getterFunc<user_t>.emplace(to, _getterFunc<user_t>[from]);
_setterFunc<user_t>.emplace(to, _setterFunc<user_t>[from]);
});
_getterFunc<user_t>.emplace(other, _getterFunc<user_t>[this]);
_setterFunc<user_t>.emplace(other, _setterFunc<user_t>[this]);
// redefine copy-function for newly constructed instance // move instance functions
// other._copyFunc was defined in the 'prev_copy(other)' call above _moveFunc.emplace_back([](AdcDeviceAttribute* from, AdcDeviceAttribute* to) {
other->_moveFunc = [other, copy_f = other->_copyFunc](AdcDeviceAttribute* o_next) { _getterFunc<user_t>.emplace(to, std::move(_getterFunc<user_t>[from]));
copy_f(o_next); _setterFunc<user_t>.emplace(to, std::move(_setterFunc<user_t>[from]));
});
_getterFunc<user_t>.emplace(o_next, _getterFunc<user_t>[other]);
_setterFunc<user_t>.emplace(o_next, _setterFunc<user_t>[other]);
};
};
// move TO other
_moveFunc = [prev_move = _moveFunc, this](AdcDeviceAttribute* other) {
prev_move(other);
_getterFunc<user_t>.emplace(other, std::move(_getterFunc<user_t>[this]));
_setterFunc<user_t>.emplace(other, std::move(_setterFunc<user_t>[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<user_t>.emplace(o_next, std::move(_getterFunc<user_t>[other]));
_setterFunc<user_t>.emplace(o_next, std::move(_setterFunc<user_t>[other]));
};
};
return *this; return *this;
} }
@ -541,6 +508,7 @@ public:
} }
template <typename UT> template <typename UT>
requires(!std::same_as<AdcDeviceAttribute, std::decay_t<UT>>)
AdcDeviceAttribute& operator=(UT&& val) AdcDeviceAttribute& operator=(UT&& val)
{ {
if (_accessType == ReadOnly) { if (_accessType == ReadOnly) {
@ -562,8 +530,12 @@ public:
AdcDeviceAttribute& operator=(const AdcDeviceAttribute& other) AdcDeviceAttribute& operator=(const AdcDeviceAttribute& other)
{ {
if (&other != this) { if (&other != this) {
other._copyFunc(this); for (auto& fn : other._copyFunc) {
fn(&other, this);
}
_ident = other._ident;
_accessType = other._accessType;
_serializerFunc = other._serializerFunc; _serializerFunc = other._serializerFunc;
_deserializerFunc = other._deserializerFunc; _deserializerFunc = other._deserializerFunc;
} }
@ -575,8 +547,13 @@ public:
AdcDeviceAttribute& operator=(AdcDeviceAttribute&& other) AdcDeviceAttribute& operator=(AdcDeviceAttribute&& other)
{ {
if (&other != this) { if (&other != this) {
other._moveFunc(this); for (auto& fn : other._moveFunc) {
fn(&other, this);
}
_ident = std::move(other._ident);
_accessType = std::move(other._accessType);
_serializerFunc = std::move(other._serializerFunc); _serializerFunc = std::move(other._serializerFunc);
_deserializerFunc = std::move(other._deserializerFunc); _deserializerFunc = std::move(other._deserializerFunc);
} }

View File

@ -453,7 +453,8 @@ public:
template <std::ranges::range ParT> template <std::ranges::range ParT>
requires(!traits::adc_input_char_range<std::ranges::range_value_t<ParT>>) // requires(!traits::adc_input_char_range<std::ranges::range_value_t<ParT>>)
requires(!traits::adc_input_char_range<ParT>)
void ack(const ParT& param) void ack(const ParT& param)
{ {
base_t::setKeyValue(ACK_KEY, param); base_t::setKeyValue(ACK_KEY, param);

View File

@ -159,9 +159,10 @@ protected:
_get_attr = [dev_ptr, wrapper = traits::adc_pf_wrapper(std::forward<AttrIdDeserialT>(attr_id_deser_func))]( _get_attr = [dev_ptr, wrapper = traits::adc_pf_wrapper(std::forward<AttrIdDeserialT>(attr_id_deser_func))](
const auto& attr_name) mutable { const auto& attr_name) mutable {
auto attr_id = std::get<0>(wrapper)(attr_name); auto attr_id = std::get<0>(wrapper)(attr_name);
// auto attr = (*dev_ptr)[attr_id]; auto& attr = (*dev_ptr)[attr_id];
// auto val = attr.serialize(); auto val = attr.serialize();
auto val = (*dev_ptr)[attr_id].serialize(); return val;
// auto val = (*dev_ptr)[attr_id].serialize();
using val_t = std::remove_cvref_t<decltype(val)>; using val_t = std::remove_cvref_t<decltype(val)>;
if constexpr (std::same_as<serialized_t, val_t> || std::convertible_to<val_t, serialized_t>) { if constexpr (std::same_as<serialized_t, val_t> || std::convertible_to<val_t, serialized_t>) {

View File

@ -9,8 +9,14 @@ using namespace adc;
template <typename T> template <typename T>
struct V { struct V {
static T getter() { return _v; } static T getter()
static void setter(const T& v) { _v = v; } {
return _v;
}
static void setter(const T& v)
{
_v = v;
}
static bool validator(const T& v) static bool validator(const T& v)
{ {
@ -30,7 +36,7 @@ TEST_CASE("[ADC DEVICE ATTRIBUTE]")
double av = -10; double av = -10;
using vv = V<unsigned>; using vv = V<unsigned>;
using attr_t = AdcDeviceAttribute<std::string_view>; using attr_t = AdcDeviceAttribute<std::string_view, std::string>;
std::string_view id{"ATTR_A"}; std::string_view id{"ATTR_A"};
@ -56,4 +62,12 @@ TEST_CASE("[ADC DEVICE ATTRIBUTE]")
std::cout << "ACC_TYPE: " << ar.accessType() << "\n"; std::cout << "ACC_TYPE: " << ar.accessType() << "\n";
std::cout << "ATTR_RO = " << (double)ar << "\n"; std::cout << "ATTR_RO = " << (double)ar << "\n";
auto ar1 = ar;
std::cout << "ATTR1_RO = " << (double)ar1 << "\n";
auto ar2(ar1);
std::cout << "ATTR2_RO = " << (double)ar2 << "\n";
std::cout << "ATTR2_RO_SER = " << ar2.serialize() << "\n";
} }