24template <
typename Response>
28 template <
typename Context>
34 template <
typename CompletionHandler,
typename TransformResponse>
37 TransformResponse&& transformResponse,
38 CompletionHandler&& completionHandler
40 static_assert(std::is_invocable_v<TransformResponse, Response&>);
41 using TransformResult = std::invoke_result_t<TransformResponse, Response&>;
42 static_assert(std::is_invocable_v<CompletionHandler, TransformResult&>);
43 using Context = std::tuple<ExceptionCatcher&, TransformResponse, CompletionHandler>;
45 auto callback = [](
UA_Client*,
void* userdata, uint32_t ,
void* responsePtr) {
46 assert(userdata !=
nullptr);
47 std::unique_ptr<Context> context{
static_cast<Context*
>(userdata)};
48 auto& catcher = std::get<ExceptionCatcher&>(*context);
50 if (responsePtr ==
nullptr) {
53 Response& response = *
static_cast<Response*
>(responsePtr);
54 auto result = std::invoke(std::get<TransformResponse>(*context), response);
55 std::invoke(std::get<CompletionHandler>(*context), result);
61 std::make_unique<Context>(
63 std::forward<TransformResponse>(transformResponse),
64 std::forward<CompletionHandler>(completionHandler)
77 template <
typename Initiation,
typename TransformResponse,
typename CompletionToken>
80 Initiation&& initiation,
81 TransformResponse&& transformResponse,
82 CompletionToken&& token
84 static_assert(std::is_invocable_v<Initiation, UA_ClientAsyncServiceCallback, void*>);
85 using TransformResult = std::invoke_result_t<TransformResponse, Response&>;
88 [&](
auto&& completionHandler,
auto&& transform) {
92 std::forward<
decltype(transform)>(transform),
93 std::forward<
decltype(completionHandler)>(completionHandler)
97 std::forward<Initiation>(initiation),
98 callbackAndContext.callback,
99 callbackAndContext.context.release()
102 std::forward<CompletionToken>(token),
103 std::forward<TransformResponse>(transformResponse)
108template <
typename Request,
typename Response,
typename TransformResponse,
typename CompletionToken>
111 const Request& request,
112 TransformResponse&& transformResponse,
113 CompletionToken&& token
129 response.responseHeader.serviceResult =
status;
130 callback(client.
handle(), userdata, {}, &response);
133 std::forward<TransformResponse>(transformResponse),
134 std::forward<CompletionToken>(token)
142template <
typename Request,
typename Response,
typename TransformResponse>
145 const Request& request,
146 TransformResponse&& transformResponse,
148)
noexcept(std::is_nothrow_invocable_v<TransformResponse, Response&>) {
158 return std::invoke(std::forward<TransformResponse>(transformResponse), response);
Exception for bad status codes from open62541 UA_STATUSCODE_*.
UA_Client * handle() noexcept
Catch & store exceptions from user-defined callbacks in an exception-unaware context (open62541).
General-purpose scope guard intended to call its exit function when a scope is exited.
void(* UA_ClientAsyncServiceCallback)(UA_Client *client, void *userdata, UA_UInt32 requestId, void *response)
void __UA_Client_Service(UA_Client *client, const void *request, const UA_DataType *requestType, void *response, const UA_DataType *responseType)
UA_StatusCode __UA_Client_AsyncService(UA_Client *client, const void *request, const UA_DataType *requestType, UA_ClientAsyncServiceCallback callback, const UA_DataType *responseType, void *userdata, UA_UInt32 *requestId)
auto asyncInitiate(Initiation &&initiation, CompletionToken &&token, Args &&... args)
ClientContext * getContext(UA_Client *client) noexcept
constexpr void clear(T &native, const UA_DataType &type) noexcept
constexpr bool isBad(UA_StatusCode code) noexcept
auto sendRequest(Client &client, const Request &request, TransformResponse &&transformResponse, CompletionToken &&token)
const UA_DataType & getDataType() noexcept
#define UA_STATUSCODE_BADUNEXPECTEDERROR
UA_ClientAsyncServiceCallback callback
std::unique_ptr< Context > context
Adapter to initiate open62541 async client operations with completion tokens.
static auto createCallbackAndContext(ExceptionCatcher &exceptionCatcher, TransformResponse &&transformResponse, CompletionHandler &&completionHandler)
static auto initiate(Client &client, Initiation &&initiation, TransformResponse &&transformResponse, CompletionToken &&token)
Initiate open62541 async client operation with user-defined completion token.
Completion token for sync client operations.