CARLA
 
载入中...
搜索中...
未找到
rpc/Server.h
浏览该文件的文档.
1// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3//
4// This work is licensed under the terms of the MIT license.
5// For a copy, see <https://opensource.org/licenses/MIT>.
6
7#pragma once
8
9#include "carla/MoveHandler.h" // 包含处理移动的头文件
10#include "carla/Time.h" // 包含时间相关的头文件
11#include "carla/rpc/Metadata.h" // 包含元数据相关的头文件
12#include "carla/rpc/Response.h" // 包含响应相关的头文件
13
14#include <boost/asio/io_context.hpp> // 包含Boost.Asio的io_context类
15#include <boost/asio/post.hpp> // 包含Boost.Asio的post函数
16
17#include <rpc/server.h> // 包含RPC服务器的头文件
18
19#include <future> // 包含future库,用于异步编程
20
21namespace carla {
22namespace rpc {
23
24 // ===========================================================================
25 // -- Server -----------------------------------------------------------------
26 // ===========================================================================
27
28 /// 一个RPC服务器,可以将功能绑定为同步或异步运行。
29 ///
30 /// 使用`AsyncRun`启动工作线程,使用`SyncRunFor`在调用者线程中运行一段工作。
31 ///
32 /// 使用`BindAsync`绑定的函数将在工作线程中异步运行。使用`BindSync`绑定的函数将在
33 /// `SyncRunFor`函数中运行。
34 class Server {
35 public:
36
37 // 构造函数,接受变长参数
38 template <typename... Args>
39 explicit Server(Args &&... args);
40
41 // 绑定一个同步函数
42 template <typename FunctorT>
43 void BindSync(const std::string &name, FunctorT &&functor);
44
45 // 绑定一个异步函数
46 template <typename FunctorT>
47 void BindAsync(const std::string &name, FunctorT &&functor);
48
49 // 异步运行指定数量的工作线程
50 void AsyncRun(size_t worker_threads) {
51 _server.async_run(worker_threads);
52 }
53
54 // 在当前线程中运行指定持续时间的同步工作
55 void SyncRunFor(time_duration duration) {
56 #ifdef LIBCARLA_INCLUDED_FROM_UE4
57 #include <compiler/enable-ue4-macros.h> // 包含UE4宏
58 TRACE_CPUPROFILER_EVENT_SCOPE_STR(__FUNCTION__); // CPU性能分析
59 #include <compiler/disable-ue4-macros.h> // 禁用UE4宏
60 #endif // LIBCARLA_INCLUDED_FROM_UE4
61 _sync_io_context.reset(); // 重置同步IO上下文
62 _sync_io_context.run_for(duration.to_chrono()); // 运行指定持续时间
63 }
64
65 /// @warning 不会停止游戏线程。
66 void Stop() {
67 _server.stop(); // 停止服务器
68 }
69
70 private:
71
72 boost::asio::io_context _sync_io_context; // 同步IO上下文
73
74 ::rpc::server _server; // RPC服务器实例
75 };
76
77 // ===========================================================================
78 // -- Server implementation --------------------------------------------------
79 // ===========================================================================
80
81namespace detail {
82
83 // 函数包装器的结构体模板
84 template <typename T>
85 struct FunctionWrapper : FunctionWrapper<decltype(&T::operator())> {};
86
87 // 特化:用于成员函数
88 template <typename C, typename R, typename... Args>
89 struct FunctionWrapper<R (C::*)(Args...)> : FunctionWrapper<R (*)(Args...)> {};
90
91 // 特化:用于常量成员函数
92 template <typename C, typename R, typename... Args>
93 struct FunctionWrapper<R (C::*)(Args...) const> : FunctionWrapper<R (*)(Args...)> {};
94
95 // 处理引用类型
96 template<class T>
97 struct FunctionWrapper<T &> : public FunctionWrapper<T> {};
98
99 // 处理右值引用类型
100 template<class T>
101 struct FunctionWrapper<T &&> : public FunctionWrapper<T> {};
102
103 // 定义函数指针包装器
104 template <typename R, typename... Args>
105 struct FunctionWrapper<R (*)(Args...)> {
106
107 /// 将@a functor包装为具有等效签名的函数类型。返回的包装函数。
108 /// 当调用时,将@a functor放入io_context;如果客户端同步调用此方法,则等待
109 /// 已发布任务完成,否则立即返回。
110 ///
111 /// 这样,无论从哪个线程调用包装函数,提供的@a functor始终在
112 /// io_context的上下文中调用。即,我们可以使用io_context在特定线程(例如
113 /// 游戏线程)上运行任务。
114 template <typename FuncT>
115 static auto WrapSyncCall(boost::asio::io_context &io, FuncT &&functor) {
116 return [&io, functor=std::forward<FuncT>(functor)](Metadata metadata, Args... args) -> R {
117 auto task = std::packaged_task<R()>([functor=std::move(functor), args...]() {
118 return functor(args...); // 调用传入的可调用对象
119 });
120 if (metadata.IsResponseIgnored()) { // 如果响应被忽略
121 // 发布任务并忽略结果。
122 boost::asio::post(io, MoveHandler(task)); // 将任务发布到IO上下文
123 return R(); // 返回默认构造的R
124 } else {
125 // 发布任务并等待结果。
126 auto result = task.get_future(); // 获取未来对象以获取结果
127 boost::asio::post(io, MoveHandler(task)); // 将任务发布到IO上下文
128 return result.get(); // 等待并返回结果
129 }
130 };
131 }
132
133
134 /// 将@a functor包装为具有等效签名的函数类型,
135/// 处理客户端发送的元数据。如果客户端异步调用此方法,结果将被忽略。
136template <typename FuncT>
137static auto WrapAsyncCall(FuncT &&functor) {
138 return [functor=std::forward<FuncT>(functor)](::carla::rpc::Metadata metadata, Args... args) -> R {
139 if (metadata.IsResponseIgnored()) { // 检查响应是否被忽略
140 functor(args...); // 调用传入的可调用对象
141 return R(); // 返回默认构造的R
142 } else {
143 return functor(args...); // 正常返回调用结果
144 }
145 };
146}
147};
148
149} // namespace detail
150
151// 构造函数,接受变长参数
152template <typename ... Args>
153inline Server::Server(Args && ... args)
154 : _server(std::forward<Args>(args) ...) { // 初始化服务器
155 _server.suppress_exceptions(true); // 抑制异常
156}
157
158// 绑定一个同步函数
159template <typename FunctorT>
160inline void Server::BindSync(const std::string &name, FunctorT &&functor) {
161 using Wrapper = detail::FunctionWrapper<FunctorT>; // 使用函数包装器
162 _server.bind(
163 name,
164 Wrapper::WrapSyncCall(_sync_io_context, std::forward<FunctorT>(functor))); // 绑定同步函数
165}
166
167// 绑定一个异步函数
168template <typename FunctorT>
169inline void Server::BindAsync(const std::string &name, FunctorT &&functor) {
170 using Wrapper = detail::FunctionWrapper<FunctorT>; // 使用函数包装器
171 _server.bind(
172 name,
173 Wrapper::WrapAsyncCall(std::forward<FunctorT>(functor))); // 绑定异步函数
174}
175
176} // namespace rpc
177} // namespace carla
carla::rpc::Response< T > R
Metadata of an RPC function call.
Definition Metadata.h:15
一个RPC服务器,可以将功能绑定为同步或异步运行。
Definition rpc/Server.h:34
::rpc::server _server
Definition rpc/Server.h:74
Server(Args &&... args)
Definition rpc/Server.h:153
void SyncRunFor(time_duration duration)
Definition rpc/Server.h:55
void AsyncRun(size_t worker_threads)
Definition rpc/Server.h:50
boost::asio::io_context _sync_io_context
Definition rpc/Server.h:72
void BindSync(const std::string &name, FunctorT &&functor)
Definition rpc/Server.h:160
void BindAsync(const std::string &name, FunctorT &&functor)
Definition rpc/Server.h:169
Positive time duration up to milliseconds resolution.
Definition Time.h:19
constexpr auto to_chrono() const
Definition Time.h:52
CARLA模拟器的主命名空间。
Definition Carla.cpp:139
auto MoveHandler(FunctorT &&func)
下面是一种hack,用于绕过Asio库的限制,使其能够接受仅可移动的处理程序。 如果Asio试图复制一个仅可移动的处理程序,那么编译时可能不会立即报错
Definition MoveHandler.h:34
static auto WrapSyncCall(boost::asio::io_context &io, FuncT &&functor)
将functor包装为具有等效签名的函数类型。返回的包装函数。 当调用时,将functor放入io_context;如果客户端同步调用此方法,则等待 已发布任务完成,否则立即返回。
Definition rpc/Server.h:115
static auto WrapAsyncCall(FuncT &&functor)
将functor包装为具有等效签名的函数类型,
Definition rpc/Server.h:137