...
This commit is contained in:
parent
49d1b71565
commit
4fd0550de3
@ -151,8 +151,77 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// general-purpose server communication methods
|
||||||
|
|
||||||
|
// blocking
|
||||||
|
template <traits::adc_range_of_output_char_range R, typename... ArgTs>
|
||||||
|
R serverCall(ServerResponseType& rtype, std::string_view key, ArgTs&&... args)
|
||||||
|
{
|
||||||
|
typename netservice_t::send_msg_t bytes;
|
||||||
|
|
||||||
|
AdcDeviceProtoMessage msg(bytes);
|
||||||
|
msg.setKeyValue(key, std::forward<ArgTs>(args)...);
|
||||||
|
|
||||||
|
return getFromServer<R>(key, bytes, rtype);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... ArgTs>
|
||||||
|
default_server_resp_t serverCall(ServerResponseType& rtype, std::string_view key, ArgTs&&... args)
|
||||||
|
{
|
||||||
|
return serverCall<default_server_resp_t>(rtype, key, std::forward<ArgTs>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// asynchronous
|
||||||
|
template <std::convertible_to<async_callback_func_t> CallbackT, typename... ArgTs>
|
||||||
|
auto asyncServerCall(std::string_view key, CallbackT&& callback_func, ArgTs&&... args)
|
||||||
|
{
|
||||||
|
auto bytes = std::shared_ptr<typename netservice_t::send_msg_t>();
|
||||||
|
|
||||||
|
AdcDeviceProtoMessage msg(*bytes);
|
||||||
|
msg.setKeyValue(key, std::forward<ArgTs>(args)...);
|
||||||
|
|
||||||
|
asyncSendRecv(*bytes, [bytes, key, wrapper = traits::adc_pf_wrapper(std::forward<CallbackT>(callback_func)),
|
||||||
|
this](auto err, auto rmsg) mutable {
|
||||||
|
if (err) {
|
||||||
|
_clientPtr->logError("An error occured while receiving server respond: {}",
|
||||||
|
netservice_t::formattableError(err));
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
ServerResponseType type;
|
||||||
|
auto attrs = checkserverCall<default_server_resp_t>(key, rmsg, type);
|
||||||
|
|
||||||
|
std::forward<CallbackT>(std::get<0>(wrapper))(type, attrs);
|
||||||
|
|
||||||
|
} catch (const std::system_error& err) {
|
||||||
|
_clientPtr->logError("An error occured while getting server respond: {}", err.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ADC device helper methods (blocking)
|
// ADC device helper methods (blocking)
|
||||||
|
|
||||||
|
// send client HELLO-message
|
||||||
|
template <traits::adc_range_of_output_char_range R,
|
||||||
|
traits::adc_input_char_range SenderNameT,
|
||||||
|
typename... ParamTs>
|
||||||
|
R clientHello(ServerResponseType& rtype, SenderNameT&& name, ParamTs&&... params)
|
||||||
|
{
|
||||||
|
// expected respond: ACK HELLO ...
|
||||||
|
// return HELLO ... (or error description 'code category what')
|
||||||
|
return serverCall<R>(rtype, constants::ADC_DEVICE_NETPROTO_KEY_HELLO, std::forward<SenderNameT>(name),
|
||||||
|
std::forward<ParamTs>(params)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <traits::adc_input_char_range SenderNameT, typename... ParamTs>
|
||||||
|
default_server_resp_t clientHello(ServerResponseType& rtype, SenderNameT&& name, ParamTs&&... params)
|
||||||
|
{
|
||||||
|
return clientHello<default_server_resp_t>(rtype, std::forward<SenderNameT>(name),
|
||||||
|
std::forward<ParamTs>(params)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// get names of devices
|
// get names of devices
|
||||||
template <traits::adc_range_of_output_char_range R>
|
template <traits::adc_range_of_output_char_range R>
|
||||||
@ -160,7 +229,7 @@ public:
|
|||||||
{
|
{
|
||||||
// expected respond: ACK NAMES DEV1 DEV2 ...
|
// expected respond: ACK NAMES DEV1 DEV2 ...
|
||||||
// return DEV1 DEV2 ... (or error description 'code category what')
|
// return DEV1 DEV2 ... (or error description 'code category what')
|
||||||
return deviceFuncHelper<R>(constants::ADC_DEVICE_NETPROTO_KEY_NAMES, rtype);
|
return serverCall<R>(rtype, constants::ADC_DEVICE_NETPROTO_KEY_NAMES);
|
||||||
}
|
}
|
||||||
|
|
||||||
default_server_resp_t deviceNames(ServerResponseType& rtype)
|
default_server_resp_t deviceNames(ServerResponseType& rtype)
|
||||||
@ -170,51 +239,49 @@ public:
|
|||||||
|
|
||||||
// bind device to the client
|
// bind device to the client
|
||||||
template <traits::adc_range_of_output_char_range R, traits::adc_input_char_range DevNameT>
|
template <traits::adc_range_of_output_char_range R, traits::adc_input_char_range DevNameT>
|
||||||
R bindDevice(DevNameT&& dev_name, ServerResponseType& rtype)
|
R bindDevice(ServerResponseType& rtype, DevNameT&& dev_name)
|
||||||
{
|
{
|
||||||
// expected respond: ACK DEVICE DEV_NAME
|
// 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,
|
return serverCall<R>(rtype, constants::ADC_DEVICE_NETPROTO_KEY_DEVICE, std::forward<DevNameT>(dev_name));
|
||||||
std::forward<DevNameT>(dev_name));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <traits::adc_input_char_range DevNameT>
|
template <traits::adc_input_char_range DevNameT>
|
||||||
default_server_resp_t bindDevice(DevNameT&& dev_name, ServerResponseType& rtype)
|
default_server_resp_t bindDevice(ServerResponseType& rtype, DevNameT&& dev_name)
|
||||||
{
|
{
|
||||||
return bindDevice<default_server_resp_t>(std::forward<DevNameT>(dev_name), rtype);
|
return bindDevice<default_server_resp_t>(rtype, std::forward<DevNameT>(dev_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// execute a command
|
// execute a command
|
||||||
template <traits::adc_range_of_output_char_range R, traits::adc_input_char_range CmdNameT>
|
template <traits::adc_range_of_output_char_range R, traits::adc_input_char_range CmdNameT>
|
||||||
R exec(CmdNameT&& cmd_name, ServerResponseType& rtype)
|
R exec(ServerResponseType& rtype, CmdNameT&& cmd_name)
|
||||||
{
|
{
|
||||||
// expected respond: ACK CMD CMD_NAME
|
// expected respond: ACK CMD CMD_NAME
|
||||||
// return CMD_NAME ... (or error description 'code category what')
|
// return CMD_NAME ... (or error description 'code category what')
|
||||||
return deviceFuncHelper<R>(constants::ADC_DEVICE_NETPROTO_KEY_CMD, rtype, std::forward<CmdNameT>(cmd_name));
|
return serverCall<R>(rtype, constants::ADC_DEVICE_NETPROTO_KEY_CMD, std::forward<CmdNameT>(cmd_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <traits::adc_input_char_range CmdNameT>
|
template <traits::adc_input_char_range CmdNameT>
|
||||||
default_server_resp_t exec(CmdNameT&& cmd_name, ServerResponseType& rtype)
|
default_server_resp_t exec(ServerResponseType& rtype, CmdNameT&& cmd_name)
|
||||||
{
|
{
|
||||||
return exec<default_server_resp_t>(std::forward<CmdNameT>(cmd_name), rtype);
|
return exec<default_server_resp_t>(rtype, std::forward<CmdNameT>(cmd_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// get an attribute value
|
// get an attribute value
|
||||||
template <traits::adc_range_of_output_char_range R, traits::adc_input_char_range AttrNameT>
|
template <traits::adc_range_of_output_char_range R, traits::adc_input_char_range AttrNameT>
|
||||||
R getAttr(AttrNameT&& attr_name, ServerResponseType& rtype)
|
R getAttr(ServerResponseType& rtype, AttrNameT&& attr_name)
|
||||||
{
|
{
|
||||||
// expected respond: ACK GET ATTR_NAME ATTR_VALUE
|
// expected respond: ACK GET ATTR_NAME ATTR_VALUE
|
||||||
// return ATTR_NAME ATTR_VALUE (or error description 'code category what')
|
// return ATTR_NAME ATTR_VALUE (or error description 'code category what')
|
||||||
return deviceFuncHelper<R>(constants::ADC_DEVICE_NETPROTO_KEY_GET, rtype,
|
return serverCall<R>(rtype, constants::ADC_DEVICE_NETPROTO_KEY_GET, std::forward<AttrNameT>(attr_name));
|
||||||
std::forward<AttrNameT>(attr_name));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <traits::adc_input_char_range AttrNameT>
|
template <traits::adc_input_char_range AttrNameT>
|
||||||
default_server_resp_t getAttr(AttrNameT&& attr_name, ServerResponseType& rtype)
|
default_server_resp_t getAttr(ServerResponseType& rtype, AttrNameT&& attr_name)
|
||||||
{
|
{
|
||||||
return getAttr<default_server_resp_t>(std::forward<AttrNameT>(attr_name), rtype);
|
return getAttr<default_server_resp_t>(rtype, std::forward<AttrNameT>(attr_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -227,8 +294,8 @@ public:
|
|||||||
{
|
{
|
||||||
// expected respond: ACK SET ATTR_NAME ATTR_VALUE
|
// expected respond: ACK SET ATTR_NAME ATTR_VALUE
|
||||||
// return ATTR_NAME ATTR_VALUE (or error description 'code category what')
|
// return ATTR_NAME ATTR_VALUE (or error description 'code category what')
|
||||||
return deviceFuncHelper<R>(constants::ADC_DEVICE_NETPROTO_KEY_SET, rtype, std::forward<ValueT>(value),
|
return serverCall<R>(constants::ADC_DEVICE_NETPROTO_KEY_SET, rtype, std::forward<AttrNameT>(attr_name),
|
||||||
std::forward<ValueTs>(values)...);
|
std::forward<ValueT>(value), std::forward<ValueTs>(values)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <traits::adc_input_char_range AttrNameT, typename ValueT, typename... ValueTs>
|
template <traits::adc_input_char_range AttrNameT, typename ValueT, typename... ValueTs>
|
||||||
@ -243,32 +310,40 @@ public:
|
|||||||
|
|
||||||
// ADC device helper methods (asynchronous)
|
// ADC device helper methods (asynchronous)
|
||||||
|
|
||||||
|
template <std::convertible_to<async_callback_func_t> CallbackT,
|
||||||
|
traits::adc_input_char_range SenderNameT,
|
||||||
|
typename... ParamTs>
|
||||||
|
auto asyncClientHello(CallbackT&& callback_func, SenderNameT&& name, ParamTs&&... params)
|
||||||
|
{
|
||||||
|
return asyncServerCall(constants::ADC_DEVICE_NETPROTO_KEY_HELLO, std::forward<CallbackT>(callback_func),
|
||||||
|
std::forward<SenderNameT>(name), std::forward<ParamTs>(params)...);
|
||||||
|
}
|
||||||
|
|
||||||
template <std::convertible_to<async_callback_func_t> CallbackT>
|
template <std::convertible_to<async_callback_func_t> CallbackT>
|
||||||
auto asyncDeviceNames(CallbackT&& callback_func)
|
auto asyncDeviceNames(CallbackT&& callback_func)
|
||||||
{
|
{
|
||||||
return asyncDeviceFuncHelper(constants::ADC_DEVICE_NETPROTO_KEY_NAMES,
|
return asyncServerCall(constants::ADC_DEVICE_NETPROTO_KEY_NAMES, std::forward<CallbackT>(callback_func));
|
||||||
std::forward<CallbackT>(callback_func));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::convertible_to<async_callback_func_t> CallbackT, traits::adc_input_char_range DevNameT>
|
template <std::convertible_to<async_callback_func_t> CallbackT, traits::adc_input_char_range DevNameT>
|
||||||
auto asyncBindDevice(CallbackT&& callback_func, DevNameT&& dev_name)
|
auto asyncBindDevice(CallbackT&& callback_func, DevNameT&& dev_name)
|
||||||
{
|
{
|
||||||
return asyncDeviceFuncHelper(constants::ADC_DEVICE_NETPROTO_KEY_DEVICE,
|
return asyncServerCall(constants::ADC_DEVICE_NETPROTO_KEY_DEVICE, std::forward<CallbackT>(callback_func),
|
||||||
std::forward<CallbackT>(callback_func), std::forward<DevNameT>(dev_name));
|
std::forward<DevNameT>(dev_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::convertible_to<async_callback_func_t> CallbackT, traits::adc_input_char_range CmdNameT>
|
template <std::convertible_to<async_callback_func_t> CallbackT, traits::adc_input_char_range CmdNameT>
|
||||||
auto asyncExec(CallbackT&& callback_func, CmdNameT&& cmd_name)
|
auto asyncExec(CallbackT&& callback_func, CmdNameT&& cmd_name)
|
||||||
{
|
{
|
||||||
return asyncDeviceFuncHelper(constants::ADC_DEVICE_NETPROTO_KEY_CMD, std::forward<CallbackT>(callback_func),
|
return asyncServerCall(constants::ADC_DEVICE_NETPROTO_KEY_CMD, std::forward<CallbackT>(callback_func),
|
||||||
std::forward<CmdNameT>(cmd_name));
|
std::forward<CmdNameT>(cmd_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::convertible_to<async_callback_func_t> CallbackT, traits::adc_input_char_range AttrNameT>
|
template <std::convertible_to<async_callback_func_t> CallbackT, traits::adc_input_char_range AttrNameT>
|
||||||
auto asyncGetAttr(CallbackT&& callback_func, AttrNameT&& attr_name)
|
auto asyncGetAttr(CallbackT&& callback_func, AttrNameT&& attr_name)
|
||||||
{
|
{
|
||||||
return asyncDeviceFuncHelper(constants::ADC_DEVICE_NETPROTO_KEY_GET, std::forward<CallbackT>(callback_func),
|
return asyncServerCall(constants::ADC_DEVICE_NETPROTO_KEY_GET, std::forward<CallbackT>(callback_func),
|
||||||
std::forward<AttrNameT>(attr_name));
|
std::forward<AttrNameT>(attr_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::convertible_to<async_callback_func_t> CallbackT,
|
template <std::convertible_to<async_callback_func_t> CallbackT,
|
||||||
@ -277,9 +352,9 @@ public:
|
|||||||
typename... ValueTs>
|
typename... ValueTs>
|
||||||
auto asyncSetAttr(CallbackT&& callback_func, AttrNameT&& attr_name, ValueT&& value, ValueTs&&... values)
|
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),
|
return asyncServerCall(constants::ADC_DEVICE_NETPROTO_KEY_SET, std::forward<CallbackT>(callback_func),
|
||||||
std::forward<AttrNameT>(attr_name), std::forward<ValueT>(value),
|
std::forward<AttrNameT>(attr_name), std::forward<ValueT>(value),
|
||||||
std::forward<ValueTs>(values)...);
|
std::forward<ValueTs>(values)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -297,7 +372,7 @@ public:
|
|||||||
// helper methods
|
// helper methods
|
||||||
|
|
||||||
template <traits::adc_range_of_output_char_range R>
|
template <traits::adc_range_of_output_char_range R>
|
||||||
R checkServerRespond(std::string_view key, const auto& bytes, ServerResponseType& type) const
|
R checkserverCall(std::string_view key, const auto& bytes, ServerResponseType& type) const
|
||||||
{
|
{
|
||||||
AdcDeviceProtoMessage dev_msg(bytes);
|
AdcDeviceProtoMessage dev_msg(bytes);
|
||||||
|
|
||||||
@ -321,47 +396,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto rbytes = sendRecv(bytes);
|
auto rbytes = sendRecv(bytes);
|
||||||
|
|
||||||
return checkServerRespond<R>(key, rbytes, type);
|
return checkserverCall<R>(key, rbytes, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <traits::adc_range_of_output_char_range R, typename... ArgTs>
|
|
||||||
R deviceFuncHelper(std::string_view key, ServerResponseType& rtype, ArgTs&&... args)
|
|
||||||
{
|
|
||||||
typename netservice_t::send_msg_t bytes;
|
|
||||||
|
|
||||||
AdcDeviceProtoMessage msg(bytes);
|
|
||||||
msg.setKeyValue(key, std::forward<ArgTs>(args)...);
|
|
||||||
|
|
||||||
return getFromServer<R>(key, bytes, rtype);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <std::convertible_to<async_callback_func_t> CallbackT, typename... ArgTs>
|
|
||||||
auto asyncDeviceFuncHelper(std::string_view key, CallbackT&& callback_func, ArgTs&&... args)
|
|
||||||
{
|
|
||||||
auto bytes = std::shared_ptr<typename netservice_t::send_msg_t>();
|
|
||||||
|
|
||||||
AdcDeviceProtoMessage msg(*bytes);
|
|
||||||
msg.setKeyValue(key, std::forward<ArgTs>(args)...);
|
|
||||||
|
|
||||||
asyncSendRecv(*bytes, [bytes, key, wrapper = traits::adc_pf_wrapper(std::forward<CallbackT>(callback_func)),
|
|
||||||
this](auto err, auto rmsg) mutable {
|
|
||||||
if (err) {
|
|
||||||
_clientPtr->logError("An error occured while receiving server respond: {}",
|
|
||||||
netservice_t::formattableError(err));
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
ServerResponseType type;
|
|
||||||
auto attrs = checkServerRespond<default_server_resp_t>(key, rmsg, type);
|
|
||||||
|
|
||||||
std::forward<CallbackT>(std::get<0>(wrapper))(type, attrs);
|
|
||||||
|
|
||||||
} catch (const std::system_error& err) {
|
|
||||||
_clientPtr->logError("An error occured while getting server respond: {}", err.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <traits::adc_input_char_range SendMsgT>
|
template <traits::adc_input_char_range SendMsgT>
|
||||||
auto sendRecv(const SendMsgT& send_msg)
|
auto sendRecv(const SendMsgT& send_msg)
|
||||||
@ -394,6 +431,8 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* A HELPER CLASS TO IMPLEMENT AN SIMPLE QUEUE FOR DEVICE ATTRIBUTE GET/SET OPERATIONS AND COMMAND EXECUTION */
|
||||||
|
|
||||||
template <traits::adc_range_of_input_char_range ArgRangeT = std::vector<std::string>>
|
template <traits::adc_range_of_input_char_range ArgRangeT = std::vector<std::string>>
|
||||||
class AdcNetClientSendQueue
|
class AdcNetClientSendQueue
|
||||||
{
|
{
|
||||||
@ -415,13 +454,13 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <traits::adc_input_char_range... ElemTs>
|
template <traits::adc_input_char_range... ArgTs>
|
||||||
AdcNetClientSendQueue& addToQueue(std::string key, ElemTs&&... elems)
|
AdcNetClientSendQueue& addToQueue(std::string key, ArgTs&&... elems)
|
||||||
{
|
{
|
||||||
if constexpr (sizeof...(ElemTs)) {
|
if constexpr (sizeof...(ArgTs)) {
|
||||||
_queue.push({key, ArgRangeT()});
|
_queue.push({key, ArgRangeT()});
|
||||||
|
|
||||||
addToQueueHelper(std::get<1>(_queue.back()), std::forward<ElemTs>(elems)...);
|
addToQueueHelper(std::get<1>(_queue.back()), std::forward<ArgTs>(elems)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@ -463,17 +502,17 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
std::queue<queue_elem_t> _queue;
|
std::queue<queue_elem_t> _queue;
|
||||||
|
|
||||||
template <traits::adc_input_char_range ElemT, traits::adc_input_char_range... ElemTs>
|
template <traits::adc_input_char_range ArgT, traits::adc_input_char_range... ArgTs>
|
||||||
void addToQueueHelper(ArgRangeT& args, ElemT&& elem, ElemTs&&... elems)
|
void addToQueueHelper(ArgRangeT& args, ArgT&& elem, ArgTs&&... elems)
|
||||||
{
|
{
|
||||||
using el_t = std::ranges::range_value_t<ArgRangeT>;
|
using el_t = std::ranges::range_value_t<ArgRangeT>;
|
||||||
|
|
||||||
if constexpr (std::same_as<el_t, std::remove_cvref_t<ElemT>>) {
|
if constexpr (std::same_as<el_t, std::remove_cvref_t<ArgT>>) {
|
||||||
std::ranges::copy(std::ranges::single_view(elem), std::back_inserter(args));
|
std::ranges::copy(std::ranges::single_view(elem), std::back_inserter(args));
|
||||||
} else {
|
} else {
|
||||||
std::span<const char> sp;
|
std::span<const char> sp;
|
||||||
|
|
||||||
if constexpr (std::is_array_v<std::remove_cvref_t<ElemT>>) {
|
if constexpr (std::is_array_v<std::remove_cvref_t<ArgT>>) {
|
||||||
sp = std::string_view(elem);
|
sp = std::string_view(elem);
|
||||||
} else {
|
} else {
|
||||||
sp = std::span<const char>(elem);
|
sp = std::span<const char>(elem);
|
||||||
@ -488,8 +527,8 @@ protected:
|
|||||||
std::back_inserter(args));
|
std::back_inserter(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
if constexpr (sizeof...(ElemTs)) {
|
if constexpr (sizeof...(ArgTs)) {
|
||||||
addToQueue(args, std::forward<ElemTs>(elems)...);
|
addToQueue(args, std::forward<ArgTs>(elems)...);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user