diff --git a/net/adc_device_netclient.h b/net/adc_device_netclient.h index 91f117e..96ebe25 100644 --- a/net/adc_device_netclient.h +++ b/net/adc_device_netclient.h @@ -1,5 +1,6 @@ #pragma once +#include #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(constants::ADC_DEVICE_NETPROTO_KEY_DEVICE, rtype, std::forward(dev_name)); } @@ -242,8 +243,6 @@ public: // ADC device helper methods (asynchronous) - // get device names - template CallbackT> auto asyncDeviceNames(CallbackT&& callback_func) { @@ -251,13 +250,38 @@ public: std::forward(callback_func)); } - template CallbackT> - auto asyncBindDevice(DevNameT&& dev_name, CallbackT&& callback_func) + template 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(callback_func), std::forward(dev_name)); } + template 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(callback_func), + std::forward(cmd_name)); + } + + template 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(callback_func), + std::forward(attr_name)); + } + + template 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(callback_func), + std::forward(attr_name), std::forward(value), + std::forward(values)...); + } + protected: netsession_ident_t _ident; netservice_t _netService; @@ -370,4 +394,104 @@ public: }; +template > +class AdcNetClientSendQueue +{ +public: + // + typedef std::tuple 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 + AdcNetClientSendQueue& addToQueue(std::string key, ElemTs&&... elems) + { + if constexpr (sizeof...(ElemTs)) { + _queue.push({key, ArgRangeT()}); + + addToQueueHelper(std::get<1>(_queue.back()), std::forward(elems)...); + } + + return *this; + } + + + template + AdcNetClientSendQueue& addCmdToQueue(CmdNameT&& cmd_name) + { + return addToQueue(constants::ADC_DEVICE_NETPROTO_KEY_CMD, std::forward(cmd_name)); + } + + template + AdcNetClientSendQueue& addGetAttrToQueue(AttrNameT&& attr_name) + { + return addToQueue(constants::ADC_DEVICE_NETPROTO_KEY_GET, std::forward(attr_name)); + } + + template + AdcNetClientSendQueue& addSetAttrToQueue(AttrNameT&& attr_name, ValueT&& value, ValueTs&&... values) + { + return addToQueue(constants::ADC_DEVICE_NETPROTO_KEY_SET, std::forward(attr_name), + std::forward(value), std::forward(values)...); + } + + AdcNetClientSendQueue& addGetNamesToQueue() + { + return addToQueue(constants::ADC_DEVICE_NETPROTO_KEY_NAMES); + } + + template + AdcNetClientSendQueue& addBindDevToQueue(DeviceNameT&& dev_name) + { + return addToQueue(constants::ADC_DEVICE_NETPROTO_KEY_DEVICE, std::forward(dev_name)); + } + +protected: + std::queue _queue; + + template + void addToQueueHelper(ArgRangeT& args, ElemT&& elem, ElemTs&&... elems) + { + using el_t = std::ranges::range_value_t; + + if constexpr (std::same_as>) { + std::ranges::copy(std::ranges::single_view(elem), std::back_inserter(args)); + } else { + std::span sp; + + if constexpr (std::is_array_v>) { + sp = std::string_view(elem); + } else { + sp = std::span(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(elems)...); + } + } +}; + } // namespace adc