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

View File

@ -153,9 +153,11 @@ public:
T res; T res;
if constexpr (std::ranges::contiguous_range<ByteSeqT>) { 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()) { 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 { } else {
utils::AdcJoinRange(valueParts<std::vector<std::vector<const char>>>(start, N), valueDelimiter, res); 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 class AdcDeviceNetServer : public AdcGenericNetServer
{ {
public: public:
// type for serialized data (attr/command ID, attr values etc...)
typedef std::vector<char> serialized_t; typedef std::vector<char> serialized_t;
protected: protected:
class DeviceWrapper class DeviceWrapper
{ {
public: 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: private:
serialized_t _id; serialized_t _id;
// std::function<serialized_t()> _get_id = []() -> serialized_t { throw std::system_error(); }; // 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)); 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)); 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)); 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))]( _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 attr_id = std::get<0>(wrapper)(attr_name);
auto val = (*dev_ptr)[attr_id].serialize(); 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)>;
@ -169,13 +171,13 @@ protected:
}; };
_set_attr = [dev_ptr, wrapper = traits::adc_pf_wrapper(std::forward<AttrIdDeserialT>(attr_id_deser_func))]( _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); auto attr_id = std::get<0>(wrapper)(attr_name);
(*dev_ptr)[attr_id].deserialize(val); (*dev_ptr)[attr_id].deserialize(val);
}; };
_exec_cmd = [dev_ptr, wrapper = traits::adc_pf_wrapper<CmdIdDeserialT>(cmd_id_deser_func)]( _exec_cmd = [dev_ptr, wrapper = traits::adc_pf_wrapper(std::forward<CmdIdDeserialT>(cmd_id_deser_func))](
const char_range_t& cmd_name) mutable { const auto& cmd_name) mutable {
auto cmd_id = std::get<0>(wrapper)(cmd_name); auto cmd_id = std::get<0>(wrapper)(cmd_name);
(*dev_ptr)(cmd_id); (*dev_ptr)(cmd_id);
}; };
@ -188,17 +190,17 @@ protected:
return _id; return _id;
} }
serialized_t getAttr(const char_range_t& attr_name) serialized_t getAttr(const serialized_t& attr_name)
{ {
return _get_attr(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); _set_attr(attr_name, val);
} }
void exec(const char_range_t& cmd_name) void exec(const serialized_t& cmd_name)
{ {
_exec_cmd(cmd_name); _exec_cmd(cmd_name);
} }
@ -288,12 +290,13 @@ public:
attr_vec_t attrs; 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()) { if (idx < attrs.size()) {
auto& el = attrs[idx]; return attrs[idx];
return DeviceWrapper::char_range_t{el.begin(), el.end()}; // auto& el = attrs[idx];
// return serialized_t(el.begin(), el.end());
} else { } else {
return DeviceWrapper::char_range_t{}; return serialized_t();
} }
}; };
@ -331,16 +334,18 @@ public:
attrs = msg.template attrs<attr_vec_t>(0, 1); attrs = msg.template attrs<attr_vec_t>(0, 1);
if (attrs.size()) { if (attrs.size()) {
auto val = _bindDevice.getAttr(get_elem(0)); 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! } else { // no attr name!
msg.err(std::make_error_code(AdcDeviceNetServerSessionError::ERROR_NO_PROTO_ATTRNAME)); msg.err(std::make_error_code(AdcDeviceNetServerSessionError::ERROR_NO_PROTO_ATTRNAME));
} }
} else if (msg.isSET()) { } else if (msg.isSET()) {
attrs = msg.template attrs<attr_vec_t>(0); attrs = msg.template attrs<attr_vec_t>(0);
if (attrs.size() >= 2) { 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); _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! } else { // no attr name or its value!
if (attrs.size() == 1) { if (attrs.size() == 1) {
msg.err(std::make_error_code(AdcDeviceNetServerSessionError::ERROR_NO_PROTO_ATTRVALUE)); msg.err(std::make_error_code(AdcDeviceNetServerSessionError::ERROR_NO_PROTO_ATTRVALUE));