Skip to content

Commit

Permalink
feat: refine code
Browse files Browse the repository at this point in the history
  • Loading branch information
shuai132 committed Nov 16, 2024
1 parent 6bc6093 commit 699c9de
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 76 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Arduino, STM32, ESP32/ESP8266, etc.)

## Introduction

Full-feature rpc frameworks (e.g. `gRPC` and `bRPC`) very complex and not suitable for embedded systems.
Full-feature rpc frameworks (e.g. `gRPC` and `bRPC`) are very complex and not suitable for embedded systems.

This project offers a lightweight and user-friend rpc library that is better suited for one-to-one rpc calls.
It supports all platforms and a wide range of microchips, including Arduino, STM32, ESP32/ESP8266, and more.
Expand Down Expand Up @@ -51,6 +51,7 @@ For TCP-based implementation: [asio_net](https://github.com/shuai132/asio_net)
NOTICE: complete data packets are required for data transmission, such as `websocket`.
If using `tcp socket`, `serial port`, etc., message pack and unpack need to be implemented.
Or you can use [stream_connection](include/rpc_core/connection.hpp).
* Optional: C++20 (for coroutine api, co_await async_call)

## Usage

Expand Down
76 changes: 1 addition & 75 deletions include/rpc_core/request.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,10 +256,7 @@ class request : detail::noncopyable, public std::enable_shared_from_this<request
return shared_from_this();
}

request_s mark_need_rsp() {
rsp([] {});
return shared_from_this();
}
inline request_s mark_need_rsp();

request_s rpc(rpc_w rpc) {
rpc_ = std::move(rpc);
Expand Down Expand Up @@ -348,77 +345,6 @@ class request : detail::noncopyable, public std::enable_shared_from_this<request
bool is_ping_ = false;
};

template <typename T>
struct request::result {
finally_t type;
T data;
};

template <>
struct request::result<void> {
finally_t type;
};

#ifdef RPC_CORE_FEATURE_FUTURE
template <typename R, typename std::enable_if<!std::is_same<R, void>::value, int>::type>
std::future<request::result<R>> request::future(const rpc_s& rpc) {
auto promise = std::make_shared<std::promise<result<R>>>();
rsp([promise](R r, finally_t type) {
promise->set_value({type, std::move(r)});
});
call(rpc);
return promise->get_future();
}

template <typename R, typename std::enable_if<std::is_same<R, void>::value, int>::type>
std::future<request::result<void>> request::future(const rpc_s& rpc) {
auto promise = std::make_shared<std::promise<request::result<void>>>();
mark_need_rsp();
finally([promise](request::finally_t type) {
promise->set_value({type});
});
call(rpc);
return promise->get_future();
}
#endif

#ifdef RPC_CORE_FEATURE_ASIO_COROUTINE
template <typename R, typename std::enable_if<!std::is_same<R, void>::value, int>::type>
asio::awaitable<request::result<R>> request::async_call() {
auto executor = co_await asio::this_coro::executor;
co_return co_await asio::async_compose<decltype(asio::use_awaitable), void(rpc_core::request::result<R>)>(
[this, &executor](auto& self) mutable {
using ST = std::remove_reference<decltype(self)>::type;
auto self_sp = std::make_shared<ST>(std::forward<ST>(self));
rsp([&executor, self = std::move(self_sp)](R data, finally_t type) mutable {
asio::dispatch(executor, [self = std::move(self), data = std::move(data), type]() {
self->complete({type, data});
});
});
call();
},
asio::use_awaitable);
}

template <typename R, typename std::enable_if<std::is_same<R, void>::value, int>::type>
asio::awaitable<request::result<R>> request::async_call() {
auto executor = co_await asio::this_coro::executor;
co_return co_await asio::async_compose<decltype(asio::use_awaitable), void(rpc_core::request::result<R>)>(
[this, &executor](auto&& self) mutable {
using ST = std::remove_reference<decltype(self)>::type;
auto self_sp = std::make_shared<ST>(std::forward<ST>(self));
mark_need_rsp();
finally([&executor, self = std::move(self_sp)](finally_t type) mutable {
asio::dispatch(executor, [self = std::move(self), type] {
self->complete({type});
});
});
call();
},
asio::use_awaitable);
}
#endif

using request_s = request::request_s;
using request_w = request::request_w;
using finally_t = request::finally_t;
Expand Down
76 changes: 76 additions & 0 deletions include/rpc_core/request.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,80 @@ request_s request::add_to(dispose& dispose) {
return self;
}

request_s request::mark_need_rsp() {
rsp([] {});
return shared_from_this();
}

template <typename T>
struct request::result {
finally_t type;
T data;
};

template <>
struct request::result<void> {
finally_t type;
};

#ifdef RPC_CORE_FEATURE_FUTURE
template <typename R, typename std::enable_if<!std::is_same<R, void>::value, int>::type>
std::future<request::result<R>> request::future(const rpc_s& rpc) {
auto promise = std::make_shared<std::promise<result<R>>>();
rsp([promise](R r, finally_t type) {
promise->set_value({type, std::move(r)});
});
call(rpc);
return promise->get_future();
}

template <typename R, typename std::enable_if<std::is_same<R, void>::value, int>::type>
std::future<request::result<void>> request::future(const rpc_s& rpc) {
auto promise = std::make_shared<std::promise<request::result<void>>>();
mark_need_rsp();
finally([promise](request::finally_t type) {
promise->set_value({type});
});
call(rpc);
return promise->get_future();
}
#endif

#ifdef RPC_CORE_FEATURE_ASIO_COROUTINE
template <typename R, typename std::enable_if<!std::is_same<R, void>::value, int>::type>
asio::awaitable<request::result<R>> request::async_call() {
auto executor = co_await asio::this_coro::executor;
co_return co_await asio::async_compose<decltype(asio::use_awaitable), void(rpc_core::request::result<R>)>(
[this, &executor](auto& self) mutable {
using ST = std::remove_reference<decltype(self)>::type;
auto self_sp = std::make_shared<ST>(std::forward<ST>(self));
rsp([&executor, self = std::move(self_sp)](R data, finally_t type) mutable {
asio::dispatch(executor, [self = std::move(self), data = std::move(data), type]() {
self->complete({type, data});
});
});
call();
},
asio::use_awaitable);
}

template <typename R, typename std::enable_if<std::is_same<R, void>::value, int>::type>
asio::awaitable<request::result<R>> request::async_call() {
auto executor = co_await asio::this_coro::executor;
co_return co_await asio::async_compose<decltype(asio::use_awaitable), void(rpc_core::request::result<R>)>(
[this, &executor](auto& self) mutable {
using ST = std::remove_reference<decltype(self)>::type;
auto self_sp = std::make_shared<ST>(std::forward<ST>(self));
mark_need_rsp();
finally([&executor, self = std::move(self_sp)](finally_t type) mutable {
asio::dispatch(executor, [self = std::move(self), type] {
self->complete({type});
});
});
call();
},
asio::use_awaitable);
}
#endif

} // namespace rpc_core

0 comments on commit 699c9de

Please sign in to comment.