This commit is contained in:
Timur A. Fatkhullin 2024-11-20 17:25:33 +03:00
parent 319276845a
commit ad12ee1ad8

View File

@ -1,5 +1,6 @@
#pragma once
#include <queue>
#include "../common/adc_utils.h"
#include "adc_device_netmsg.h"
#include "adc_netclient.h"
@ -172,7 +173,7 @@ public:
R bindDevice(DevNameT&& dev_name, ServerResponseType& rtype)
{
// expected respond: ACK DEVICE DEV_NAME
// return DEV_NAME ... (or error description 'code category what')
// return DEV_NAME (or error description 'code category what')
return deviceFuncHelper<R>(constants::ADC_DEVICE_NETPROTO_KEY_DEVICE, rtype,
std::forward<DevNameT>(dev_name));
}
@ -242,8 +243,6 @@ public:
// ADC device helper methods (asynchronous)
// get device names
template <std::convertible_to<async_callback_func_t> CallbackT>
auto asyncDeviceNames(CallbackT&& callback_func)
{
@ -251,13 +250,38 @@ public:
std::forward<CallbackT>(callback_func));
}
template <traits::adc_input_char_range DevNameT, std::convertible_to<async_callback_func_t> CallbackT>
auto asyncBindDevice(DevNameT&& dev_name, CallbackT&& callback_func)
template <std::convertible_to<async_callback_func_t> CallbackT, traits::adc_input_char_range DevNameT>
auto asyncBindDevice(CallbackT&& callback_func, DevNameT&& dev_name)
{
return asyncDeviceFuncHelper(constants::ADC_DEVICE_NETPROTO_KEY_DEVICE,
std::forward<CallbackT>(callback_func), std::forward<DevNameT>(dev_name));
}
template <std::convertible_to<async_callback_func_t> CallbackT, traits::adc_input_char_range CmdNameT>
auto asyncExec(CallbackT&& callback_func, CmdNameT&& cmd_name)
{
return asyncDeviceFuncHelper(constants::ADC_DEVICE_NETPROTO_KEY_CMD, std::forward<CallbackT>(callback_func),
std::forward<CmdNameT>(cmd_name));
}
template <std::convertible_to<async_callback_func_t> CallbackT, traits::adc_input_char_range AttrNameT>
auto asyncGetAttr(CallbackT&& callback_func, AttrNameT&& attr_name)
{
return asyncDeviceFuncHelper(constants::ADC_DEVICE_NETPROTO_KEY_GET, std::forward<CallbackT>(callback_func),
std::forward<AttrNameT>(attr_name));
}
template <std::convertible_to<async_callback_func_t> CallbackT,
traits::adc_input_char_range AttrNameT,
typename ValueT,
typename... ValueTs>
auto asyncSetAttr(CallbackT&& callback_func, AttrNameT&& attr_name, ValueT&& value, ValueTs&&... values)
{
return asyncDeviceFuncHelper(constants::ADC_DEVICE_NETPROTO_KEY_SET, std::forward<CallbackT>(callback_func),
std::forward<AttrNameT>(attr_name), std::forward<ValueT>(value),
std::forward<ValueTs>(values)...);
}
protected:
netsession_ident_t _ident;
netservice_t _netService;
@ -370,4 +394,104 @@ public:
};
template <traits::adc_range_of_input_char_range ArgRangeT = std::vector<std::string>>
class AdcNetClientSendQueue
{
public:
// <netproto-key, args ...>
typedef std::tuple<std::string_view, ArgRangeT> queue_elem_t;
AdcNetClientSendQueue() = default;
size_t queueSize() const
{
return _queue.size();
}
AdcNetClientSendQueue& addToQueue(std::string_view key, const ArgRangeT& args)
{
_queue.push({key, args});
return *this;
}
template <traits::adc_input_char_range... ElemTs>
AdcNetClientSendQueue& addToQueue(std::string key, ElemTs&&... elems)
{
if constexpr (sizeof...(ElemTs)) {
_queue.push({key, ArgRangeT()});
addToQueueHelper(std::get<1>(_queue.back()), std::forward<ElemTs>(elems)...);
}
return *this;
}
template <traits::adc_input_char_range CmdNameT>
AdcNetClientSendQueue& addCmdToQueue(CmdNameT&& cmd_name)
{
return addToQueue(constants::ADC_DEVICE_NETPROTO_KEY_CMD, std::forward<CmdNameT>(cmd_name));
}
template <traits::adc_input_char_range AttrNameT>
AdcNetClientSendQueue& addGetAttrToQueue(AttrNameT&& attr_name)
{
return addToQueue(constants::ADC_DEVICE_NETPROTO_KEY_GET, std::forward<AttrNameT>(attr_name));
}
template <traits::adc_input_char_range AttrNameT,
traits::adc_input_char_range ValueT,
traits::adc_input_char_range... ValueTs>
AdcNetClientSendQueue& addSetAttrToQueue(AttrNameT&& attr_name, ValueT&& value, ValueTs&&... values)
{
return addToQueue(constants::ADC_DEVICE_NETPROTO_KEY_SET, std::forward<AttrNameT>(attr_name),
std::forward<ValueT>(value), std::forward<ValueTs>(values)...);
}
AdcNetClientSendQueue& addGetNamesToQueue()
{
return addToQueue(constants::ADC_DEVICE_NETPROTO_KEY_NAMES);
}
template <traits::adc_input_char_range DeviceNameT>
AdcNetClientSendQueue& addBindDevToQueue(DeviceNameT&& dev_name)
{
return addToQueue(constants::ADC_DEVICE_NETPROTO_KEY_DEVICE, std::forward<DeviceNameT>(dev_name));
}
protected:
std::queue<queue_elem_t> _queue;
template <traits::adc_input_char_range ElemT, traits::adc_input_char_range... ElemTs>
void addToQueueHelper(ArgRangeT& args, ElemT&& elem, ElemTs&&... elems)
{
using el_t = std::ranges::range_value_t<ArgRangeT>;
if constexpr (std::same_as<el_t, std::remove_cvref_t<ElemT>>) {
std::ranges::copy(std::ranges::single_view(elem), std::back_inserter(args));
} else {
std::span<const char> sp;
if constexpr (std::is_array_v<std::remove_cvref_t<ElemT>>) {
sp = std::string_view(elem);
} else {
sp = std::span<const char>(elem);
}
std::ranges::copy(std::views::transform(std::ranges::single_view(sp),
[](const auto& val) {
el_t el;
std::ranges::copy(val, std::back_inserter(el));
return el;
}),
std::back_inserter(args));
}
if constexpr (sizeof...(ElemTs)) {
addToQueue(args, std::forward<ElemTs>(elems)...);
}
}
};
} // namespace adc