diff --git a/src/loaders/request_response.hpp b/src/loaders/request_response.hpp new file mode 100644 index 0000000..61cfbe8 --- /dev/null +++ b/src/loaders/request_response.hpp @@ -0,0 +1,87 @@ +/** + * Copyright Quadrivium LLC + * All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "injector/node_injector.hpp" +#include "se/impl/common.hpp" +#include +#include +#include "modules/module.hpp" + +namespace jam::loaders { + + template + struct ResponseContext { + enum class Error : uint8_t { + REQUEST_RESPONSE_DELETED = 1, + }; + + using Response = outcome::result; + virtual ~ResponseContext() = default; + virtual void on_response(Response response) = 0; + }; + + template + struct RequestResponse final : public ResponseContext, se::utils::NoCopy { + using typename ResponseContext::Response; + + RequestResponse(FRespCb &&on_response_cb, Args&&... args) + : on_response_cb_(std::move(on_response_cb)), args_(std::forward(args)...) {} + + ~RequestResponse() override { + if (on_response_cb_) { + (*on_response_cb_)(args(), outcome::failure(std::error_code( + static_cast(ResponseContext::Error::REQUEST_RESPONSE_DELETED)))); + } + } + + void on_response(Response response) override { + if (on_response_cb_) { + (*on_response_cb_)(args(), std::move(response)); + on_response_cb_ = std::nullopt; + } + } + + std::tuple &args() { + return args_; + } + + const std::tuple &args() const { + return args_; + } + + private: + std::optional on_response_cb_; + std::tuple args_; + }; + + template + inline auto make_request(FRespCb &&on_response_cb, Args&&... args) { + return RequestResponse, std::decay_t...>( + std::forward(on_response_cb), + std::forward(args)... + ); + } + + /* Example: + auto r2 = jam::loaders::make_request( + [](const std::tuple& args, outcome::result resp) { + if(resp) { + std::cout << "Успех: " << resp.value() << std::endl; + } else { + std::cout << "Ошибка при обработке " + << std::get<0>(args) << " (код: " + << std::get<1>(args) << ")" << std::endl; + } + }, + "запрос данных", 42 + ); + + r2.on_response(outcome::result("результат")); + */ + +} // namespace jam::loaders