This commit is contained in:
Timur A. Fatkhullin 2024-10-31 12:01:02 +03:00
parent ff42a30717
commit 222691d2e9
4 changed files with 51 additions and 29 deletions

View File

@ -1,9 +1,9 @@
#pragma once
#include <algorithm>
#include <map>
#include <ranges>
#include <system_error>
#include <unordered_map>
#include "adc_device_concepts.h"
@ -100,7 +100,7 @@ public:
auto it = _deviceCommands.find(cmd_ident);
if (it != _deviceCommands.end()) {
*it();
it->second();
} else {
throw std::system_error(AdcGenericDeviceErrorCode::ERROR_COMMAND_IDENT);
}
@ -122,13 +122,20 @@ public:
AdcGenericDevice& addCommand(CommandT&& cmd)
{
auto id = cmd.ident();
_deviceCommands.emplace(id, std::move(cmd));
_deviceCommands.insert(std::move(cmd));
return *this;
}
template <typename... CtorArgTs>
AdcGenericDevice& addCommand(CtorArgTs&&... ctor_args)
{
_deviceCommands.emplace(std::forward<CtorArgTs>(ctor_args)...);
return *this;
}
AdcGenericDevice& delCommand(const cmd_ident_t& cmd_ident)
{
_deviceCommands.erase(cmd_ident);
@ -139,8 +146,7 @@ public:
AdcGenericDevice& addAttribute(AttributeT&& attr)
{
auto id = attr.ident();
_deviceAttributes.emplace(id, std::move(attr));
_deviceAttributes.insert(std::move(attr));
return *this;
}
@ -148,7 +154,9 @@ public:
template <typename... CtorArgTs>
AdcGenericDevice& addAttribute(CtorArgTs&&... ctor_args)
{
return addAttribute(AttributeT{std::forward<CtorArgTs>(ctor_args)...});
_deviceAttributes.emplace(std::forward<CtorArgTs>(ctor_args)...);
return *this;
}
@ -179,8 +187,8 @@ public:
protected:
IdentT _ident;
std::map<attr_ident_t, AttributeT> _deviceAttributes;
std::map<cmd_ident_t, CommandT> _deviceCommands;
std::unordered_map<attr_ident_t, AttributeT> _deviceAttributes;
std::unordered_map<cmd_ident_t, CommandT> _deviceCommands;
};
} // namespace adc

View File

@ -47,6 +47,13 @@ public:
}
AdcDeviceCommand(const AdcDeviceCommand&) = default;
AdcDeviceCommand(AdcDeviceCommand&&) = default;
AdcDeviceCommand& operator=(const AdcDeviceCommand&) = default;
AdcDeviceCommand& operator=(AdcDeviceCommand&&) = default;
virtual ~AdcDeviceCommand() = default;

View File

@ -153,9 +153,11 @@ public:
T res;
if constexpr (std::ranges::contiguous_range<ByteSeqT>) {
auto pp = valueParts<std::vector<std::span<const char>>>(start, N);
// auto pp = valueParts<std::vector<std::span<const char>>>(start, N);
auto pp = valueParts<std::vector<std::span<char>>>(start, N);
if (pp.size()) {
res = T{pp.front().begin(), pp.back().end()};
// res = T{pp.front().begin(), pp.back().end()};
res = T(pp.front().begin(), pp.back().end());
}
} else {
utils::AdcJoinRange(valueParts<std::vector<std::vector<const char>>>(start, N), valueDelimiter, res);

View File

@ -109,25 +109,27 @@ namespace adc
class AdcDeviceNetServer : public AdcGenericNetServer
{
public:
// type for serialized data (attr/command ID, attr values etc...)
typedef std::vector<char> serialized_t;
protected:
class DeviceWrapper
{
public:
using char_range_t = std::span<const char>;
// using char_range_t = std::span<const char>;
using char_range_t = std::span<char>;
private:
serialized_t _id;
// std::function<serialized_t()> _get_id = []() -> serialized_t { throw std::system_error(); };
std::function<serialized_t(const char_range_t&)> _get_attr = [](auto) -> serialized_t {
std::function<serialized_t(const serialized_t&)> _get_attr = [](auto) -> serialized_t {
throw std::system_error(std::make_error_code(AdcDeviceNetServerSessionError::ERROR_NULL_DEVICE));
};
std::function<void(const char_range_t&, const char_range_t&)> _set_attr = [](auto, auto) {
std::function<void(const serialized_t&, const serialized_t&)> _set_attr = [](auto, auto) {
throw std::system_error(std::make_error_code(AdcDeviceNetServerSessionError::ERROR_NULL_DEVICE));
};
std::function<void(const char_range_t&)> _exec_cmd = [](auto) {
std::function<void(const serialized_t&)> _exec_cmd = [](auto) {
throw std::system_error(std::make_error_code(AdcDeviceNetServerSessionError::ERROR_NULL_DEVICE));
};
@ -155,7 +157,7 @@ protected:
// };
_get_attr = [dev_ptr, wrapper = traits::adc_pf_wrapper(std::forward<AttrIdDeserialT>(attr_id_deser_func))](
const char_range_t& attr_name) mutable {
const auto& attr_name) mutable {
auto attr_id = std::get<0>(wrapper)(attr_name);
auto val = (*dev_ptr)[attr_id].serialize();
using val_t = std::remove_cvref_t<decltype(val)>;
@ -169,13 +171,13 @@ protected:
};
_set_attr = [dev_ptr, wrapper = traits::adc_pf_wrapper(std::forward<AttrIdDeserialT>(attr_id_deser_func))](
const char_range_t& attr_name, const char_range_t& val) mutable {
const auto& attr_name, const auto& val) mutable {
auto attr_id = std::get<0>(wrapper)(attr_name);
(*dev_ptr)[attr_id].deserialize(val);
};
_exec_cmd = [dev_ptr, wrapper = traits::adc_pf_wrapper<CmdIdDeserialT>(cmd_id_deser_func)](
const char_range_t& cmd_name) mutable {
_exec_cmd = [dev_ptr, wrapper = traits::adc_pf_wrapper(std::forward<CmdIdDeserialT>(cmd_id_deser_func))](
const auto& cmd_name) mutable {
auto cmd_id = std::get<0>(wrapper)(cmd_name);
(*dev_ptr)(cmd_id);
};
@ -188,17 +190,17 @@ protected:
return _id;
}
serialized_t getAttr(const char_range_t& attr_name)
serialized_t getAttr(const serialized_t& attr_name)
{
return _get_attr(attr_name);
}
void setAttr(const char_range_t& attr_name, const char_range_t& val)
void setAttr(const serialized_t& attr_name, const serialized_t& val)
{
_set_attr(attr_name, val);
}
void exec(const char_range_t& cmd_name)
void exec(const serialized_t& cmd_name)
{
_exec_cmd(cmd_name);
}
@ -288,12 +290,13 @@ public:
attr_vec_t attrs;
auto get_elem = [&attrs](size_t idx) -> DeviceWrapper::char_range_t {
auto get_elem = [&attrs](size_t idx) {
if (idx < attrs.size()) {
auto& el = attrs[idx];
return DeviceWrapper::char_range_t{el.begin(), el.end()};
return attrs[idx];
// auto& el = attrs[idx];
// return serialized_t(el.begin(), el.end());
} else {
return DeviceWrapper::char_range_t{};
return serialized_t();
}
};
@ -331,16 +334,18 @@ public:
attrs = msg.template attrs<attr_vec_t>(0, 1);
if (attrs.size()) {
auto val = _bindDevice.getAttr(get_elem(0));
msg.ack(get_elem(0), serialized_t{val.begin(), val.end()});
// msg.ack(get_elem(0), serialized_t{val.begin(), val.end()});
msg.ack(get_elem(0), val);
} else { // no attr name!
msg.err(std::make_error_code(AdcDeviceNetServerSessionError::ERROR_NO_PROTO_ATTRNAME));
}
} else if (msg.isSET()) {
attrs = msg.template attrs<attr_vec_t>(0);
if (attrs.size() >= 2) {
auto val = msg.template joinAttrs<DeviceWrapper::char_range_t>(1);
auto val = msg.template joinAttrs<serialized_t>(1);
_bindDevice.setAttr(get_elem(0), val);
msg.ack(get_elem(0), serialized_t{val.begin(), val.end()});
// msg.ack(get_elem(0), serialized_t{val.begin(), val.end()});
msg.ack(get_elem(0), val);
} else { // no attr name or its value!
if (attrs.size() == 1) {
msg.err(std::make_error_code(AdcDeviceNetServerSessionError::ERROR_NO_PROTO_ATTRVALUE));