...
This commit is contained in:
parent
ff42a30717
commit
222691d2e9
@ -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
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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));
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user