vrpc 2.6.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +83 -0
- package/LICENSE +1 -1
- package/README.md +34 -60
- package/binding.gyp.no-auto +4 -26
- package/browser/vrpc.js +1 -1
- package/index.js +2 -2
- package/package.json +16 -17
- package/vrpc/VrpcAdapter.js +293 -311
- package/vrpc/VrpcAgent.js +94 -87
- package/vrpc/{VrpcRemote.js → VrpcClient.js} +375 -413
- package/vrpc/VrpcNative.js +330 -0
- package/vrpc/{vrpc.hpp → adapter.hpp} +1003 -1115
- package/vrpc/addon.cpp +6 -6
- package/vrpc/json.hpp +1769 -870
- package/vrpc/vrpc-agent-js +4 -4
- package/README.rst +0 -18
- package/third_party/include/catch.hpp +0 -12749
- package/third_party/install.sh +0 -22
- package/vrpc/VrpcLocal.js +0 -269
- package/vrpc/VrpcLocal.py +0 -171
- package/vrpc/__init__.py +0 -1
- package/vrpc/module.cpp +0 -183
|
@@ -12,11 +12,12 @@ __\/\\\_______\/\\\__/\\\///////\\\___\/\\\/////////\\\____/\\\////////__
|
|
|
12
12
|
|
|
13
13
|
Non-intrusively binds any C++ code and provides access in form of asynchronous
|
|
14
14
|
remote procedural callbacks (RPC).
|
|
15
|
-
Author: Dr. Burkhard C. Heisen (https://github.com/
|
|
15
|
+
Author: Dr. Burkhard C. Heisen (https://github.com/heisenware/vrpc-hpp)
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
|
19
|
-
Copyright (c) 2018 -
|
|
19
|
+
Copyright (c) 2018 - 2022 Dr. Burkhard C. Heisen
|
|
20
|
+
<burkhard.heisen@heisenware.com>.
|
|
20
21
|
|
|
21
22
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
22
23
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -37,1243 +38,1129 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
37
38
|
SOFTWARE.
|
|
38
39
|
*/
|
|
39
40
|
|
|
40
|
-
#ifndef
|
|
41
|
-
#define
|
|
41
|
+
#ifndef VRPC_ADAPTER_HPP
|
|
42
|
+
#define VRPC_ADAPTER_HPP
|
|
42
43
|
|
|
43
|
-
#define VRPC_VERSION_MAJOR
|
|
44
|
-
#define VRPC_VERSION_MINOR
|
|
44
|
+
#define VRPC_VERSION_MAJOR 3
|
|
45
|
+
#define VRPC_VERSION_MINOR 0
|
|
45
46
|
#define VRPC_VERSION_PATCH 0
|
|
46
47
|
|
|
47
48
|
#include <cstdint>
|
|
48
49
|
#include <functional>
|
|
49
50
|
#include <iostream>
|
|
51
|
+
#include <map>
|
|
52
|
+
#include <memory>
|
|
50
53
|
#include <set>
|
|
51
54
|
#include <sstream>
|
|
52
55
|
#include <tuple>
|
|
56
|
+
#include <type_traits>
|
|
53
57
|
#include <typeindex>
|
|
54
58
|
#include <typeinfo>
|
|
55
|
-
#include <type_traits>
|
|
56
|
-
#include <map>
|
|
57
|
-
#include <memory>
|
|
58
59
|
#include <unordered_map>
|
|
59
60
|
#include <utility>
|
|
60
61
|
#include <vector>
|
|
61
62
|
#if defined(VRPC_WITH_DL) && !defined(_WIN32)
|
|
62
|
-
|
|
63
|
+
#include <dlfcn.h>
|
|
63
64
|
#endif
|
|
64
|
-
|
|
65
|
+
|
|
66
|
+
#include <vrpc/json.hpp>
|
|
65
67
|
|
|
66
68
|
#ifdef VRPC_DEBUG
|
|
67
69
|
#define _VRPC_DEBUG \
|
|
68
|
-
if (1)
|
|
70
|
+
if (1) \
|
|
71
|
+
std::cout << "vrpc::" << __func__ << "\t"
|
|
69
72
|
#else
|
|
70
73
|
#define _VRPC_DEBUG \
|
|
71
|
-
if (0)
|
|
74
|
+
if (0) \
|
|
75
|
+
std::cout << "vrpc::" << __func__ << "\t"
|
|
72
76
|
#endif
|
|
73
77
|
|
|
74
78
|
// Add std::function to json's serializable types
|
|
75
79
|
namespace vrpc {
|
|
76
80
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
j = std::string(); // Callbacks expect a string id as argument signature
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
static void from_json(const json& j, std::function < R(Args...)>& func) {}
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
namespace vrpc {
|
|
89
|
-
namespace detail {
|
|
90
|
-
|
|
91
|
-
// Reference and CV qualifier remover
|
|
92
|
-
template<typename T>
|
|
93
|
-
using no_ref_no_const = typename std::remove_const<
|
|
94
|
-
typename std::remove_reference<T>::type
|
|
95
|
-
>::type;
|
|
96
|
-
|
|
97
|
-
// Singleton helper
|
|
98
|
-
template <typename T>
|
|
99
|
-
inline T& init() {
|
|
100
|
-
static T t;
|
|
101
|
-
return t;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
inline void pack_r(vrpc::json &json, char i) {}
|
|
105
|
-
|
|
106
|
-
template <class Tfirst, class ... Trest>
|
|
107
|
-
inline void pack_r(
|
|
108
|
-
vrpc::json& json,
|
|
109
|
-
char i,
|
|
110
|
-
const Tfirst& first,
|
|
111
|
-
const Trest&... rest
|
|
112
|
-
) {
|
|
113
|
-
char name[] = {'_', '\0', '\0', '\0'};
|
|
114
|
-
name[1] = i;
|
|
115
|
-
json[name] = first;
|
|
116
|
-
detail::pack_r(json, i + 1, rest...);
|
|
117
|
-
}
|
|
81
|
+
template <typename R, typename... Args>
|
|
82
|
+
struct adl_serializer<std::function<R(Args...)>> {
|
|
83
|
+
static void to_json(json& j, const std::function<R(Args...)>& func) {
|
|
84
|
+
j = std::string(); // Callbacks expect a string id as argument signature
|
|
118
85
|
}
|
|
119
86
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
* @param args Any type and number of arguments forming the values
|
|
124
|
-
*/
|
|
125
|
-
template <class ... Ts>
|
|
126
|
-
inline void pack(vrpc::json& json, const Ts& ... args) {
|
|
127
|
-
detail::pack_r(json, '1', args...);
|
|
128
|
-
}
|
|
87
|
+
static void from_json(const json& j, std::function<R(Args...)>& func) {}
|
|
88
|
+
};
|
|
89
|
+
} // namespace vrpc
|
|
129
90
|
|
|
130
|
-
|
|
91
|
+
namespace vrpc {
|
|
92
|
+
namespace detail {
|
|
93
|
+
|
|
94
|
+
// Reference and CV qualifier remover
|
|
95
|
+
template <typename T>
|
|
96
|
+
using no_ref_no_const =
|
|
97
|
+
typename std::remove_const<typename std::remove_reference<T>::type>::type;
|
|
98
|
+
|
|
99
|
+
// Singleton helper
|
|
100
|
+
template <typename T>
|
|
101
|
+
inline T& init() {
|
|
102
|
+
static T t;
|
|
103
|
+
return t;
|
|
104
|
+
}
|
|
131
105
|
|
|
132
|
-
|
|
133
|
-
// http://stackoverflow.com/questions/10766112/c11-i-can-go-from-multiple-args-to-tuple-but-can-i-go-from-tuple-to-multiple
|
|
106
|
+
inline void pack_r(json&) {}
|
|
134
107
|
|
|
135
|
-
|
|
136
|
-
|
|
108
|
+
template <class Tfirst, class... Trest>
|
|
109
|
+
inline void pack_r(json& arr, const Tfirst& first, const Trest&... rest) {
|
|
110
|
+
arr.push_back(first);
|
|
111
|
+
detail::pack_r(arr, rest...);
|
|
112
|
+
}
|
|
113
|
+
} // namespace detail
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Packs the arguments into a json object.
|
|
117
|
+
*
|
|
118
|
+
* @param args The arguments
|
|
119
|
+
* @return json array filled with arguments
|
|
120
|
+
*
|
|
121
|
+
* And by the way: that's the "V" in VRPC (variadic template based arguments)
|
|
122
|
+
* This feature that was introduced in C++11 sparked the idea for this library
|
|
123
|
+
*/
|
|
124
|
+
template <class... Ts>
|
|
125
|
+
inline json pack(const Ts&... args) {
|
|
126
|
+
json arr;
|
|
127
|
+
detail::pack_r(arr, args...);
|
|
128
|
+
return arr;
|
|
129
|
+
}
|
|
137
130
|
|
|
138
|
-
|
|
139
|
-
return call_impl<
|
|
140
|
-
F,
|
|
141
|
-
Tuple,
|
|
142
|
-
Total == 1 + sizeof...(N),
|
|
143
|
-
Total,
|
|
144
|
-
N...,
|
|
145
|
-
sizeof...(N)
|
|
146
|
-
>::call(f, std::forward<Tuple>(t));
|
|
147
|
-
}
|
|
148
|
-
};
|
|
131
|
+
namespace detail {
|
|
149
132
|
|
|
150
|
-
|
|
151
|
-
|
|
133
|
+
// The code below was formulated as an answer to StackOverflow and can be read
|
|
134
|
+
// here:
|
|
135
|
+
// http://stackoverflow.com/questions/10766112/c11-i-can-go-from-multiple-args-to-tuple-but-can-i-go-from-tuple-to-multiple
|
|
152
136
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
137
|
+
template <typename F, typename Tuple, bool Done, int Total, int... N>
|
|
138
|
+
struct call_impl {
|
|
139
|
+
static auto call(F f, Tuple&& t) {
|
|
140
|
+
return call_impl<F, Tuple, Total == 1 + sizeof...(N), Total, N...,
|
|
141
|
+
sizeof...(N)>::call(f, std::forward<Tuple>(t));
|
|
157
142
|
}
|
|
143
|
+
};
|
|
158
144
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
*/
|
|
164
|
-
template <typename F, typename Tuple>
|
|
165
|
-
auto call(F f, Tuple && t) {
|
|
166
|
-
typedef typename std::decay<Tuple>::type ttype;
|
|
167
|
-
return detail::call_impl<
|
|
168
|
-
F,
|
|
169
|
-
Tuple,
|
|
170
|
-
0 == std::tuple_size<ttype>::value,
|
|
171
|
-
std::tuple_size<ttype>::value
|
|
172
|
-
>::call(f, std::forward<Tuple>(t));
|
|
145
|
+
template <typename F, typename Tuple, int Total, int... N>
|
|
146
|
+
struct call_impl<F, Tuple, true, Total, N...> {
|
|
147
|
+
static auto call(F f, Tuple&& t) {
|
|
148
|
+
return f(std::get<N>(std::forward<Tuple>(t))...);
|
|
173
149
|
}
|
|
150
|
+
};
|
|
151
|
+
} // namespace detail
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Call a function f with arguments unpacked from a std::tuple
|
|
155
|
+
* @param f The function to be called
|
|
156
|
+
* @param t A tuple containing representing the parameters
|
|
157
|
+
*/
|
|
158
|
+
template <typename F, typename Tuple>
|
|
159
|
+
auto call(F f, Tuple&& t) {
|
|
160
|
+
typedef typename std::decay<Tuple>::type ttype;
|
|
161
|
+
return detail::call_impl<
|
|
162
|
+
F, Tuple, 0 == std::tuple_size<ttype>::value,
|
|
163
|
+
std::tuple_size<ttype>::value>::call(f, std::forward<Tuple>(t));
|
|
164
|
+
}
|
|
174
165
|
|
|
175
|
-
|
|
166
|
+
namespace detail {
|
|
176
167
|
|
|
177
|
-
|
|
178
|
-
|
|
168
|
+
template <std::size_t... Is>
|
|
169
|
+
struct indices {};
|
|
179
170
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
: build_indices<N - 1, N - 1, Is...> {};
|
|
171
|
+
template <std::size_t N, std::size_t... Is>
|
|
172
|
+
struct build_indices : build_indices<N - 1, N - 1, Is...> {};
|
|
183
173
|
|
|
184
|
-
|
|
185
|
-
|
|
174
|
+
template <std::size_t... Is>
|
|
175
|
+
struct build_indices<0, Is...> : indices<Is...> {};
|
|
186
176
|
|
|
187
|
-
|
|
177
|
+
template <int I>
|
|
178
|
+
struct placeholder {};
|
|
188
179
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
return std::bind(f, ptr, placeholder<Is + 1 >{}...);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
180
|
+
template <std::size_t... Is, typename Klass, typename Func>
|
|
181
|
+
auto variadic_bind_member(detail::indices<Is...>,
|
|
182
|
+
const Func& f,
|
|
183
|
+
const std::shared_ptr<Klass>& ptr)
|
|
184
|
+
-> decltype(std::bind(f, ptr, placeholder<Is + 1>{}...)) {
|
|
185
|
+
return std::bind(f, ptr, placeholder<Is + 1>{}...);
|
|
198
186
|
}
|
|
187
|
+
} // namespace detail
|
|
188
|
+
} // namespace vrpc
|
|
199
189
|
|
|
200
190
|
namespace std {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
191
|
+
template <int I>
|
|
192
|
+
struct is_placeholder<vrpc::detail::placeholder<I>>
|
|
193
|
+
: std::integral_constant<int, I> {};
|
|
194
|
+
} // namespace std
|
|
205
195
|
|
|
206
196
|
namespace vrpc {
|
|
207
197
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
return detail::variadic_bind_member(
|
|
218
|
-
detail::build_indices<sizeof...(Args)>{},
|
|
219
|
-
f,
|
|
220
|
-
ptr
|
|
221
|
-
);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
namespace detail {
|
|
225
|
-
|
|
226
|
-
template<std::size_t... Is, typename Func>
|
|
227
|
-
auto variadic_bind(detail::indices<Is...>, const Func& f)
|
|
228
|
-
-> decltype(std::bind(f, placeholder<Is + 1 >{}...)) {
|
|
229
|
-
return std::bind(f, placeholder < Is + 1 >{}...);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
template<typename Func, typename ...Args>
|
|
234
|
-
auto variadic_bind(const Func& f)
|
|
235
|
-
-> decltype(
|
|
236
|
-
detail::variadic_bind(detail::build_indices<sizeof...(Args)>{}, f)
|
|
237
|
-
) {
|
|
238
|
-
return detail::variadic_bind(detail::build_indices<sizeof...(Args)>{}, f);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
typedef std::function<void (const vrpc::json&) > CallbackHandler;
|
|
242
|
-
|
|
243
|
-
struct Callback {
|
|
244
|
-
|
|
245
|
-
static void register_callback_handler(const CallbackHandler& handler) {
|
|
246
|
-
detail::init<CallbackHandler>() = handler;
|
|
247
|
-
}
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
namespace detail {
|
|
251
|
-
|
|
252
|
-
template <typename T>
|
|
253
|
-
struct CallbackT;
|
|
254
|
-
|
|
255
|
-
template <typename R, typename ...Args>
|
|
256
|
-
struct CallbackT<std::function<R(Args...)>> :
|
|
257
|
-
public std::enable_shared_from_this<CallbackT<std::function<R(Args...)>>>,
|
|
258
|
-
public vrpc::Callback {
|
|
259
|
-
vrpc::json m_json;
|
|
260
|
-
std::string m_callback_id;
|
|
198
|
+
template <typename Klass, typename Func, typename... Args>
|
|
199
|
+
auto variadic_bind_member(const Func& f, const std::shared_ptr<Klass>& ptr)
|
|
200
|
+
-> decltype(detail::variadic_bind_member(
|
|
201
|
+
detail::build_indices<sizeof...(Args)>{},
|
|
202
|
+
f,
|
|
203
|
+
ptr)) {
|
|
204
|
+
return detail::variadic_bind_member(detail::build_indices<sizeof...(Args)>{},
|
|
205
|
+
f, ptr);
|
|
206
|
+
}
|
|
261
207
|
|
|
262
|
-
|
|
263
|
-
m_json(json),
|
|
264
|
-
m_callback_id(json["data"][key].get<std::string>()) {
|
|
265
|
-
_VRPC_DEBUG << "Constructed with: " << m_json << " and "
|
|
266
|
-
<< m_callback_id << std::endl;
|
|
267
|
-
}
|
|
208
|
+
namespace detail {
|
|
268
209
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
<< " with payload: " << data << std::endl;
|
|
276
|
-
detail::init<CallbackHandler>()(m_json);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
auto bind_wrapper() {
|
|
280
|
-
auto func = &CallbackT < std::function<R(Args...)>>::wrapper;
|
|
281
|
-
auto ptr = std::enable_shared_from_this<
|
|
282
|
-
CallbackT<std::function<R(Args...)>>
|
|
283
|
-
>::shared_from_this();
|
|
284
|
-
return detail::variadic_bind_member(
|
|
285
|
-
detail::build_indices<sizeof...(Args)>{}, func, ptr
|
|
286
|
-
);
|
|
287
|
-
}
|
|
288
|
-
};
|
|
289
|
-
|
|
290
|
-
template <typename ...Args>
|
|
291
|
-
struct is_std_function : std::false_type {
|
|
292
|
-
};
|
|
210
|
+
template <std::size_t... Is, typename Func>
|
|
211
|
+
auto variadic_bind(detail::indices<Is...>, const Func& f)
|
|
212
|
+
-> decltype(std::bind(f, placeholder<Is + 1>{}...)) {
|
|
213
|
+
return std::bind(f, placeholder<Is + 1>{}...);
|
|
214
|
+
}
|
|
215
|
+
} // namespace detail
|
|
293
216
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
: std::true_type {};
|
|
301
|
-
|
|
302
|
-
template <char C, typename ...Args>
|
|
303
|
-
struct unpack_impl;
|
|
304
|
-
|
|
305
|
-
/* This specialization will remove reference and CV qualifier and bring
|
|
306
|
-
* back the recursion to the standard path using vrpc::json::get().
|
|
307
|
-
* Really, it should use vrpc::json::get_ref() in combination with
|
|
308
|
-
* std::tie(), however currently json does not support custom types in refs.
|
|
309
|
-
*/
|
|
310
|
-
template<char C, typename A, typename ...Args>
|
|
311
|
-
struct unpack_impl<C, A, Args...> {
|
|
312
|
-
template<
|
|
313
|
-
typename T = A,
|
|
314
|
-
typename std::enable_if<std::is_reference<T>::value, int>::type = 0
|
|
315
|
-
>
|
|
316
|
-
static auto unpack(vrpc::json& j)
|
|
317
|
-
-> decltype(
|
|
318
|
-
std::tuple_cat(
|
|
319
|
-
std::make_tuple(std::declval<no_ref_no_const<T>>()),
|
|
320
|
-
unpack_impl<C + 1, Args...>::unpack(j)
|
|
321
|
-
)
|
|
322
|
-
) {
|
|
323
|
-
// length 4 for better assembly alignment
|
|
324
|
-
constexpr const char key[] = {'_', C, '\0', '\0'};
|
|
325
|
-
typedef typename std::remove_const<
|
|
326
|
-
typename std::remove_reference<T>::type
|
|
327
|
-
>::type T_no_ref_no_const;
|
|
328
|
-
return std::tuple_cat(
|
|
329
|
-
std::make_tuple(j["data"][key].get<T_no_ref_no_const>()),
|
|
330
|
-
unpack_impl < C + 1, Args...>::unpack(j)
|
|
331
|
-
);
|
|
332
|
-
}
|
|
217
|
+
template <typename Func, typename... Args>
|
|
218
|
+
auto variadic_bind(const Func& f)
|
|
219
|
+
-> decltype(detail::variadic_bind(detail::build_indices<sizeof...(Args)>{},
|
|
220
|
+
f)) {
|
|
221
|
+
return detail::variadic_bind(detail::build_indices<sizeof...(Args)>{}, f);
|
|
222
|
+
}
|
|
333
223
|
|
|
334
|
-
|
|
335
|
-
typename T = A,
|
|
336
|
-
typename std::enable_if<!std::is_reference<T>::value, int>::type = 0
|
|
337
|
-
>
|
|
338
|
-
static auto unpack(vrpc::json& j)
|
|
339
|
-
-> decltype(std::tuple_cat(
|
|
340
|
-
std::make_tuple(std::declval<T>()),
|
|
341
|
-
unpack_impl<C + 1, Args...>::unpack(j))
|
|
342
|
-
) {
|
|
343
|
-
constexpr const char key[] = {'_', C, '\0', '\0'};
|
|
344
|
-
return std::tuple_cat(
|
|
345
|
-
std::make_tuple(j["data"][key].get<T>()),
|
|
346
|
-
unpack_impl < C + 1, Args...>::unpack(j)
|
|
347
|
-
);
|
|
348
|
-
}
|
|
349
|
-
};
|
|
224
|
+
typedef std::function<void(const json&)> CallbackHandler;
|
|
350
225
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
std::is_reference<T>::value &&
|
|
357
|
-
!is_std_function<T>::value, int>::type = 0
|
|
358
|
-
>
|
|
359
|
-
static std::tuple<no_ref_no_const<T>> unpack(vrpc::json& j) {
|
|
360
|
-
constexpr const char key[] = {'_', C, '\0', '\0'};
|
|
361
|
-
return std::make_tuple(j["data"][key].get<no_ref_no_const<T>>());
|
|
362
|
-
}
|
|
226
|
+
struct Callback {
|
|
227
|
+
static void register_callback_handler(const CallbackHandler& handler) {
|
|
228
|
+
detail::init<CallbackHandler>() = handler;
|
|
229
|
+
}
|
|
230
|
+
};
|
|
363
231
|
|
|
364
|
-
|
|
365
|
-
typename T = A,
|
|
366
|
-
typename std::enable_if<
|
|
367
|
-
!std::is_reference<T>::value &&
|
|
368
|
-
!is_std_function<T>::value, int>::type = 0
|
|
369
|
-
>
|
|
370
|
-
static std::tuple<T> unpack(vrpc::json& j) {
|
|
371
|
-
constexpr const char key[] = {'_', C, '\0', '\0'};
|
|
372
|
-
return std::make_tuple(j["data"][key].get<T>());
|
|
373
|
-
}
|
|
232
|
+
namespace detail {
|
|
374
233
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
typename std::enable_if<is_std_function<T>::value, int>::type = 0
|
|
378
|
-
>
|
|
379
|
-
static auto unpack(vrpc::json& j) {
|
|
380
|
-
constexpr const char key[] = {'_', C, '\0', '\0'};
|
|
381
|
-
auto ptr = std::make_shared<CallbackT<no_ref_no_const<T>>>(j, key);
|
|
382
|
-
return std::make_tuple(ptr->bind_wrapper());
|
|
383
|
-
}
|
|
384
|
-
};
|
|
234
|
+
template <typename T>
|
|
235
|
+
struct CallbackT;
|
|
385
236
|
|
|
386
|
-
|
|
387
|
-
|
|
237
|
+
template <typename R, typename... Args>
|
|
238
|
+
struct CallbackT<std::function<R(Args...)>>
|
|
239
|
+
: public std::enable_shared_from_this<CallbackT<std::function<R(Args...)>>>,
|
|
240
|
+
public vrpc::Callback {
|
|
241
|
+
json _json;
|
|
242
|
+
std::string _callback_id;
|
|
388
243
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
244
|
+
CallbackT(const json& json, int index)
|
|
245
|
+
: _json(json), _callback_id(json["a"][index].get<std::string>()) {
|
|
246
|
+
_VRPC_DEBUG << "Constructed with: " << _json << " and " << _callback_id
|
|
247
|
+
<< std::endl;
|
|
393
248
|
}
|
|
394
249
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
auto unpack(vrpc::json& j)
|
|
402
|
-
-> decltype(detail::unpack_impl < '1', Args...>::unpack(j)) {
|
|
403
|
-
return detail::unpack_impl < '1', Args...>::unpack(j);
|
|
250
|
+
void wrapper(Args... args) {
|
|
251
|
+
_json["a"] = pack(args...);
|
|
252
|
+
_json["i"] = _callback_id;
|
|
253
|
+
_VRPC_DEBUG << "Triggering callback: " << _callback_id
|
|
254
|
+
<< " with payload: " << _json["a"] << std::endl;
|
|
255
|
+
detail::init<CallbackHandler>()(_json);
|
|
404
256
|
}
|
|
405
257
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
template<std::size_t I = 0, typename ...Args>
|
|
415
|
-
inline typename std::enable_if<I < sizeof...(Args), void>::type
|
|
416
|
-
get_signature(std::string& signature, const std::tuple<Args...>& t) {
|
|
417
|
-
vrpc::json j{
|
|
418
|
-
{"t", std::get<I>(t)}};
|
|
419
|
-
signature += j["t"].type_name();
|
|
420
|
-
return get_signature < I + 1, Args...>(signature, t);
|
|
421
|
-
}
|
|
258
|
+
auto bind_wrapper() {
|
|
259
|
+
auto func = &CallbackT<std::function<R(Args...)>>::wrapper;
|
|
260
|
+
auto ptr = std::enable_shared_from_this<
|
|
261
|
+
CallbackT<std::function<R(Args...)>>>::shared_from_this();
|
|
262
|
+
return detail::variadic_bind_member(
|
|
263
|
+
detail::build_indices<sizeof...(Args)>{}, func, ptr);
|
|
422
264
|
}
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
template <typename... Args>
|
|
268
|
+
struct is_std_function : std::false_type {};
|
|
269
|
+
|
|
270
|
+
template <typename... Args>
|
|
271
|
+
struct is_std_function<std::function<void(Args...)>> : std::true_type {};
|
|
272
|
+
|
|
273
|
+
template <typename... Args>
|
|
274
|
+
struct is_std_function<const std::function<void(Args...)>&> : std::true_type {};
|
|
275
|
+
|
|
276
|
+
template <int I, typename... Args>
|
|
277
|
+
struct unpack_impl;
|
|
278
|
+
|
|
279
|
+
/* This specialization will remove reference and CV qualifier and bring
|
|
280
|
+
* back the recursion to the standard path using json::get().
|
|
281
|
+
* Really, it should use json::get_ref() in combination with
|
|
282
|
+
* std::tie(), however currently json does not support custom types in refs.
|
|
283
|
+
*/
|
|
284
|
+
template <int I, typename A, typename... Args>
|
|
285
|
+
struct unpack_impl<I, A, Args...> {
|
|
286
|
+
template <typename T = A,
|
|
287
|
+
typename std::enable_if<std::is_reference<T>::value &&
|
|
288
|
+
!is_std_function<T>::value,
|
|
289
|
+
int>::type = 0>
|
|
290
|
+
static auto unpack(json& j) -> decltype(std::tuple_cat(
|
|
291
|
+
std::make_tuple(std::declval<no_ref_no_const<T>>()),
|
|
292
|
+
unpack_impl<I + 1, Args...>::unpack(j))) {
|
|
293
|
+
typedef typename std::remove_const<
|
|
294
|
+
typename std::remove_reference<T>::type>::type T_no_ref_no_const;
|
|
295
|
+
return std::tuple_cat(std::make_tuple(j["a"][I].get<T_no_ref_no_const>()),
|
|
296
|
+
unpack_impl<I + 1, Args...>::unpack(j));
|
|
432
297
|
}
|
|
433
298
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
299
|
+
template <typename T = A,
|
|
300
|
+
typename std::enable_if<!std::is_reference<T>::value &&
|
|
301
|
+
!is_std_function<T>::value,
|
|
302
|
+
int>::type = 0>
|
|
303
|
+
static auto unpack(json& j)
|
|
304
|
+
-> decltype(std::tuple_cat(std::make_tuple(std::declval<T>()),
|
|
305
|
+
unpack_impl<I + 1, Args...>::unpack(j))) {
|
|
306
|
+
return std::tuple_cat(std::make_tuple(j["a"][I].get<T>()),
|
|
307
|
+
unpack_impl<I + 1, Args...>::unpack(j));
|
|
440
308
|
}
|
|
441
309
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
310
|
+
template <typename T = A,
|
|
311
|
+
typename std::enable_if<is_std_function<T>::value, int>::type = 0>
|
|
312
|
+
static auto unpack(json& j) {
|
|
313
|
+
// TODO hand over the index as template parameter
|
|
314
|
+
auto ptr = std::make_shared<CallbackT<no_ref_no_const<T>>>(j, I);
|
|
315
|
+
return std::tuple_cat(std::make_tuple(ptr->bind_wrapper()),
|
|
316
|
+
unpack_impl<I + 1, Args...>::unpack(j));
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
template <int I, typename A>
|
|
321
|
+
struct unpack_impl<I, A> {
|
|
322
|
+
template <typename T = A,
|
|
323
|
+
typename std::enable_if<std::is_reference<T>::value &&
|
|
324
|
+
!is_std_function<T>::value,
|
|
325
|
+
int>::type = 0>
|
|
326
|
+
static std::tuple<no_ref_no_const<T>> unpack(json& j) {
|
|
327
|
+
return std::make_tuple(j["a"][I].get<no_ref_no_const<T>>());
|
|
449
328
|
}
|
|
450
329
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
template<typename T>
|
|
459
|
-
Value(const T& value)
|
|
460
|
-
: content(new holder<
|
|
461
|
-
typename std::remove_cv<typename std::decay<T>::type>::type
|
|
462
|
-
>(value)) {}
|
|
463
|
-
|
|
464
|
-
Value(const char* const& value)
|
|
465
|
-
: Value(std::string(value)) {}
|
|
466
|
-
|
|
467
|
-
/// Copy constructor
|
|
468
|
-
Value(const Value& other)
|
|
469
|
-
: content(other.content ? other.content->clone() : 0) {}
|
|
470
|
-
|
|
471
|
-
/// Move constructor
|
|
472
|
-
Value(Value&& other)
|
|
473
|
-
: content(other.content) {
|
|
474
|
-
other.content = 0;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
template<typename T>
|
|
478
|
-
Value(
|
|
479
|
-
T&& value,
|
|
480
|
-
typename std::enable_if<!std::is_same<Value&, T>::value >::type* = 0,
|
|
481
|
-
typename std::enable_if<!std::is_const<T>::value >::type* = 0,
|
|
482
|
-
typename std::enable_if<!detail::is_shared_ptr<T>::value >::type* = 0
|
|
483
|
-
) : content(
|
|
484
|
-
new holder<typename std::remove_cv<typename std::decay<T>::type>::type>(
|
|
485
|
-
std::forward<T>(value)
|
|
486
|
-
)
|
|
487
|
-
) {}
|
|
488
|
-
|
|
489
|
-
~Value() noexcept {
|
|
490
|
-
delete content;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
public: // functions
|
|
494
|
-
|
|
495
|
-
Value& swap(Value& rhs) noexcept {
|
|
496
|
-
std::swap(content, rhs.content);
|
|
497
|
-
return *this;
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
Value& operator=(const Value& rhs) {
|
|
501
|
-
Value(rhs).swap(*this);
|
|
502
|
-
return *this;
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
Value& operator=(Value&& rhs) noexcept {
|
|
506
|
-
rhs.swap(*this);
|
|
507
|
-
Value().swap(rhs);
|
|
508
|
-
return *this;
|
|
509
|
-
}
|
|
330
|
+
template <typename T = A,
|
|
331
|
+
typename std::enable_if<!std::is_reference<T>::value &&
|
|
332
|
+
!is_std_function<T>::value,
|
|
333
|
+
int>::type = 0>
|
|
334
|
+
static std::tuple<T> unpack(json& j) {
|
|
335
|
+
return std::make_tuple(j["a"][I].get<T>());
|
|
336
|
+
}
|
|
510
337
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
338
|
+
template <typename T = A,
|
|
339
|
+
typename std::enable_if<is_std_function<T>::value, int>::type = 0>
|
|
340
|
+
static auto unpack(json& j) {
|
|
341
|
+
auto ptr = std::make_shared<CallbackT<no_ref_no_const<T>>>(j, I);
|
|
342
|
+
return std::make_tuple(ptr->bind_wrapper());
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
template <int I>
|
|
347
|
+
struct unpack_impl<I> {
|
|
348
|
+
static std::tuple<> unpack(json&) { return {}; }
|
|
349
|
+
};
|
|
350
|
+
} // namespace detail
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Unpack parameters into a tuple using perfect forwarding
|
|
354
|
+
* @param j json with keys _1, _2, etc. encoding function arguments
|
|
355
|
+
* @return std::tuple<Args...>
|
|
356
|
+
*/
|
|
357
|
+
template <typename... Args>
|
|
358
|
+
auto unpack(json& j) -> decltype(detail::unpack_impl<0, Args...>::unpack(j)) {
|
|
359
|
+
return detail::unpack_impl<0, Args...>::unpack(j);
|
|
360
|
+
}
|
|
516
361
|
|
|
517
|
-
|
|
518
|
-
Value(std::string(rhs)).swap(*this);
|
|
519
|
-
return *this;
|
|
520
|
-
}
|
|
362
|
+
namespace detail {
|
|
521
363
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
// template <typename T>
|
|
529
|
-
// operator T() const {
|
|
530
|
-
// return const_cast<Value*> (this)->template get<T>();
|
|
531
|
-
// }
|
|
532
|
-
|
|
533
|
-
template <typename T>
|
|
534
|
-
T& operator=(T& rhs) {
|
|
535
|
-
Value(rhs).swap(*this);
|
|
536
|
-
return *this;
|
|
537
|
-
}
|
|
364
|
+
template <std::size_t I = 0, typename... Args>
|
|
365
|
+
inline typename std::enable_if<I == sizeof...(Args), void>::type get_signature(
|
|
366
|
+
const std::string& signature,
|
|
367
|
+
const std::tuple<Args...>&) {
|
|
368
|
+
// end recursion
|
|
369
|
+
}
|
|
538
370
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
371
|
+
template <std::size_t I = 0, typename... Args>
|
|
372
|
+
inline typename std::enable_if <
|
|
373
|
+
I<sizeof...(Args), void>::type get_signature(std::string& signature,
|
|
374
|
+
const std::tuple<Args...>& t) {
|
|
375
|
+
json j = {{"t", std::get<I>(t)}};
|
|
376
|
+
if (!signature.empty()) signature += ":";
|
|
377
|
+
signature += j["t"].type_name();
|
|
378
|
+
return get_signature<I + 1, Args...>(signature, t);
|
|
379
|
+
}
|
|
380
|
+
} // namespace detail
|
|
381
|
+
|
|
382
|
+
template <typename... Args>
|
|
383
|
+
inline std::string get_signature() {
|
|
384
|
+
std::string signature;
|
|
385
|
+
detail::get_signature(
|
|
386
|
+
signature, std::tuple<typename std::remove_reference<Args>::type...>());
|
|
387
|
+
return signature.empty() ? signature : "-" + signature;
|
|
388
|
+
}
|
|
542
389
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
390
|
+
inline std::string get_signature(const json& json) {
|
|
391
|
+
std::string signature;
|
|
392
|
+
for (const auto& it : json) {
|
|
393
|
+
if (!signature.empty()) signature += ":";
|
|
394
|
+
signature += it.type_name();
|
|
395
|
+
}
|
|
396
|
+
return signature.empty() ? signature : "-" + signature;
|
|
397
|
+
}
|
|
546
398
|
|
|
547
|
-
|
|
548
|
-
static std::type_index void_type(typeid (void));
|
|
549
|
-
return content ? content->type() : void_type;
|
|
550
|
-
}
|
|
399
|
+
namespace detail {
|
|
551
400
|
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
// TODO Check type correctness here
|
|
555
|
-
// TODO implement by specialization and not by overload
|
|
556
|
-
return _get<T>(typename detail::is_shared_ptr<T>::type());
|
|
557
|
-
}
|
|
401
|
+
template <typename T>
|
|
402
|
+
struct is_shared_ptr : std::false_type {};
|
|
558
403
|
|
|
559
|
-
|
|
404
|
+
template <typename T>
|
|
405
|
+
struct is_shared_ptr<std::shared_ptr<T>> : std::true_type {};
|
|
406
|
+
} // namespace detail
|
|
560
407
|
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
> (content)->held;
|
|
566
|
-
}
|
|
408
|
+
// Value class
|
|
409
|
+
class Value {
|
|
410
|
+
public:
|
|
411
|
+
Value() noexcept : content(0) {}
|
|
567
412
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
}
|
|
413
|
+
template <typename T>
|
|
414
|
+
Value(const T& value)
|
|
415
|
+
: content(new holder<
|
|
416
|
+
typename std::remove_cv<typename std::decay<T>::type>::type>(
|
|
417
|
+
value)) {}
|
|
574
418
|
|
|
575
|
-
|
|
419
|
+
Value(const char* const& value) : Value(std::string(value)) {}
|
|
576
420
|
|
|
577
|
-
|
|
578
|
-
|
|
421
|
+
/// Copy constructor
|
|
422
|
+
Value(const Value& other)
|
|
423
|
+
: content(other.content ? other.content->clone() : 0) {}
|
|
579
424
|
|
|
580
|
-
|
|
425
|
+
/// Move constructor
|
|
426
|
+
Value(Value&& other) : content(other.content) { other.content = 0; }
|
|
581
427
|
|
|
582
|
-
|
|
428
|
+
template <typename T>
|
|
429
|
+
Value(T&& value,
|
|
430
|
+
typename std::enable_if<!std::is_same<Value&, T>::value>::type* = 0,
|
|
431
|
+
typename std::enable_if<!std::is_const<T>::value>::type* = 0,
|
|
432
|
+
typename std::enable_if<!detail::is_shared_ptr<T>::value>::type* = 0)
|
|
433
|
+
: content(new holder<
|
|
434
|
+
typename std::remove_cv<typename std::decay<T>::type>::type>(
|
|
435
|
+
std::forward<T>(value))) {}
|
|
583
436
|
|
|
584
|
-
|
|
437
|
+
~Value() noexcept { delete content; }
|
|
585
438
|
|
|
586
|
-
|
|
587
|
-
|
|
439
|
+
public: // functions
|
|
440
|
+
Value& swap(Value& rhs) noexcept {
|
|
441
|
+
std::swap(content, rhs.content);
|
|
442
|
+
return *this;
|
|
443
|
+
}
|
|
588
444
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
445
|
+
Value& operator=(const Value& rhs) {
|
|
446
|
+
Value(rhs).swap(*this);
|
|
447
|
+
return *this;
|
|
448
|
+
}
|
|
592
449
|
|
|
593
|
-
|
|
594
|
-
|
|
450
|
+
Value& operator=(Value&& rhs) noexcept {
|
|
451
|
+
rhs.swap(*this);
|
|
452
|
+
Value().swap(rhs);
|
|
453
|
+
return *this;
|
|
454
|
+
}
|
|
595
455
|
|
|
596
|
-
|
|
597
|
-
|
|
456
|
+
template <typename T>
|
|
457
|
+
Value& operator=(T&& rhs) {
|
|
458
|
+
Value(static_cast<T&&>(rhs)).swap(*this);
|
|
459
|
+
return *this;
|
|
460
|
+
}
|
|
598
461
|
|
|
462
|
+
Value& operator=(const char* const& rhs) {
|
|
463
|
+
Value(std::string(rhs)).swap(*this);
|
|
464
|
+
return *this;
|
|
465
|
+
}
|
|
599
466
|
|
|
600
|
-
|
|
467
|
+
// NOTE: Windows compiler is broken here
|
|
468
|
+
// template <typename T>
|
|
469
|
+
// operator const T&() const {
|
|
470
|
+
// return const_cast<Value*> (this)->template get<T>();
|
|
471
|
+
// }
|
|
472
|
+
|
|
473
|
+
// template <typename T>
|
|
474
|
+
// operator T() const {
|
|
475
|
+
// return const_cast<Value*> (this)->template get<T>();
|
|
476
|
+
// }
|
|
477
|
+
|
|
478
|
+
template <typename T>
|
|
479
|
+
T& operator=(T& rhs) {
|
|
480
|
+
Value(rhs).swap(*this);
|
|
481
|
+
return *this;
|
|
482
|
+
}
|
|
601
483
|
|
|
602
|
-
|
|
603
|
-
return std::type_index(typeid (T));
|
|
604
|
-
}
|
|
484
|
+
bool empty() const noexcept { return !content; }
|
|
605
485
|
|
|
606
|
-
|
|
607
|
-
// This copies a std::shared_ptr!
|
|
608
|
-
return new holder(*held);
|
|
609
|
-
}
|
|
486
|
+
void clear() noexcept { Value().swap(*this); }
|
|
610
487
|
|
|
611
|
-
|
|
488
|
+
std::type_index type() const noexcept {
|
|
489
|
+
static std::type_index void_type(typeid(void));
|
|
490
|
+
return content ? content->type() : void_type;
|
|
491
|
+
}
|
|
612
492
|
|
|
613
|
-
|
|
493
|
+
template <typename T>
|
|
494
|
+
inline const T& get() const {
|
|
495
|
+
// TODO Check type correctness here
|
|
496
|
+
// TODO implement by specialization and not by overload
|
|
497
|
+
return _get<T>(typename detail::is_shared_ptr<T>::type());
|
|
498
|
+
}
|
|
614
499
|
|
|
615
|
-
|
|
500
|
+
private: // functions
|
|
501
|
+
template <typename T>
|
|
502
|
+
inline const T& _get(const std::true_type&) const {
|
|
503
|
+
return static_cast<holder<
|
|
504
|
+
typename std::remove_cv<typename T::element_type>::type>*>(content)
|
|
505
|
+
->held;
|
|
506
|
+
}
|
|
616
507
|
|
|
617
|
-
|
|
508
|
+
template <typename T>
|
|
509
|
+
inline const T& _get(const std::false_type&) const {
|
|
510
|
+
return *(
|
|
511
|
+
static_cast<holder<typename std::remove_cv<T>::type>*>(content)->held);
|
|
512
|
+
}
|
|
618
513
|
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
514
|
+
private: // types
|
|
515
|
+
class placeholder {
|
|
516
|
+
public: // structors
|
|
517
|
+
virtual ~placeholder() {}
|
|
622
518
|
|
|
623
|
-
|
|
624
|
-
|
|
519
|
+
public: // queries
|
|
520
|
+
virtual std::type_index type() const noexcept = 0;
|
|
625
521
|
|
|
626
|
-
|
|
522
|
+
virtual placeholder* clone() const = 0;
|
|
523
|
+
};
|
|
627
524
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
525
|
+
template <typename T>
|
|
526
|
+
class holder : public placeholder {
|
|
527
|
+
public: // structors
|
|
528
|
+
holder(const T& value) : held(new T(value)) {}
|
|
631
529
|
|
|
632
|
-
|
|
633
|
-
// This copies a std::shared_ptr!
|
|
634
|
-
return new holder(held);
|
|
635
|
-
}
|
|
530
|
+
holder(T&& value) : held(new T(static_cast<T&&>(value))) {}
|
|
636
531
|
|
|
637
|
-
|
|
532
|
+
public: // queries
|
|
533
|
+
virtual std::type_index type() const noexcept {
|
|
534
|
+
return std::type_index(typeid(T));
|
|
535
|
+
}
|
|
638
536
|
|
|
639
|
-
|
|
537
|
+
virtual placeholder* clone() const {
|
|
538
|
+
// This copies a std::shared_ptr!
|
|
539
|
+
return new holder(*held);
|
|
540
|
+
}
|
|
640
541
|
|
|
641
|
-
|
|
642
|
-
};
|
|
542
|
+
holder& operator=(const holder&) = delete;
|
|
643
543
|
|
|
644
|
-
|
|
544
|
+
public: // representation
|
|
545
|
+
std::shared_ptr<T> held;
|
|
645
546
|
};
|
|
646
547
|
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
class Function {
|
|
652
|
-
public:
|
|
653
|
-
|
|
654
|
-
Function() { }
|
|
548
|
+
template <typename T>
|
|
549
|
+
class holder<std::shared_ptr<T>> : public placeholder {
|
|
550
|
+
public:
|
|
551
|
+
holder(const std::shared_ptr<T>& value) : held(value) {}
|
|
655
552
|
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
void bind_instance(const std::shared_ptr<T>& instance) {
|
|
660
|
-
this->do_bind_instance(Value(instance));
|
|
553
|
+
public: // queries
|
|
554
|
+
virtual std::type_index type() const noexcept {
|
|
555
|
+
return std::type_index(typeid(T));
|
|
661
556
|
}
|
|
662
557
|
|
|
663
|
-
|
|
664
|
-
|
|
558
|
+
virtual placeholder* clone() const {
|
|
559
|
+
// This copies a std::shared_ptr!
|
|
560
|
+
return new holder(held);
|
|
665
561
|
}
|
|
666
562
|
|
|
667
|
-
|
|
668
|
-
return this->do_clone();
|
|
669
|
-
}
|
|
563
|
+
holder& operator=(const holder&) = delete;
|
|
670
564
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
virtual void do_bind_instance(const Value& instance) = 0;
|
|
674
|
-
virtual void do_call_function(vrpc::json& json) = 0;
|
|
675
|
-
virtual std::shared_ptr<Function> do_clone() = 0;
|
|
565
|
+
public: // representation
|
|
566
|
+
std::shared_ptr<T> held;
|
|
676
567
|
};
|
|
677
568
|
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
Lambda m_lambda;
|
|
681
|
-
std::shared_ptr<Klass> m_ptr;
|
|
682
|
-
|
|
683
|
-
public:
|
|
569
|
+
placeholder* content;
|
|
570
|
+
};
|
|
684
571
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
572
|
+
inline bool operator==(const Value& lhs, const char& rhs) {
|
|
573
|
+
return lhs.get<char>() == rhs;
|
|
574
|
+
}
|
|
688
575
|
|
|
689
|
-
|
|
576
|
+
class Function {
|
|
577
|
+
public:
|
|
578
|
+
Function() {}
|
|
690
579
|
|
|
691
|
-
|
|
692
|
-
auto ptr = std::make_shared<MemberFunction>(m_lambda);
|
|
693
|
-
return std::static_pointer_cast<Function>(ptr);
|
|
694
|
-
}
|
|
580
|
+
virtual ~Function() {}
|
|
695
581
|
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
vrpc::unpack<Args...>(json)
|
|
701
|
-
);
|
|
702
|
-
} catch (const std::exception& e) {
|
|
703
|
-
json["data"]["e"] = std::string(e.what());
|
|
704
|
-
}
|
|
705
|
-
}
|
|
582
|
+
template <typename T>
|
|
583
|
+
void bind_instance(const std::shared_ptr<T>& instance) {
|
|
584
|
+
this->do_bind_instance(Value(instance));
|
|
585
|
+
}
|
|
706
586
|
|
|
707
|
-
|
|
708
|
-
m_ptr = instance.get<std::shared_ptr<Klass> >();
|
|
709
|
-
}
|
|
710
|
-
};
|
|
587
|
+
void call_function(json& json) { this->do_call_function(json); }
|
|
711
588
|
|
|
712
|
-
|
|
713
|
-
class MemberFunction<Klass, Lambda, void, Args...> : public Function {
|
|
714
|
-
Lambda m_lambda;
|
|
715
|
-
std::shared_ptr<Klass> m_ptr;
|
|
589
|
+
std::shared_ptr<Function> clone() { return this->do_clone(); }
|
|
716
590
|
|
|
717
|
-
|
|
591
|
+
protected:
|
|
592
|
+
virtual void do_bind_instance(const Value& instance) = 0;
|
|
593
|
+
virtual void do_call_function(json& json) = 0;
|
|
594
|
+
virtual std::shared_ptr<Function> do_clone() = 0;
|
|
595
|
+
};
|
|
718
596
|
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
597
|
+
template <typename Klass, typename Lambda, typename Ret, typename... Args>
|
|
598
|
+
class MemberFunction : public Function {
|
|
599
|
+
Lambda _lambda;
|
|
600
|
+
std::shared_ptr<Klass> _ptr;
|
|
722
601
|
|
|
723
|
-
|
|
602
|
+
public:
|
|
603
|
+
MemberFunction(const Lambda& lambda) : _lambda(lambda) {}
|
|
724
604
|
|
|
725
|
-
|
|
726
|
-
auto ptr = std::make_shared<MemberFunction>(m_lambda);
|
|
727
|
-
return std::static_pointer_cast<Function>(ptr);
|
|
728
|
-
}
|
|
605
|
+
virtual ~MemberFunction() = default;
|
|
729
606
|
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
} catch (const std::exception& e) {
|
|
735
|
-
json["data"]["e"] = std::string(e.what());
|
|
736
|
-
}
|
|
737
|
-
}
|
|
607
|
+
virtual std::shared_ptr<Function> do_clone() {
|
|
608
|
+
auto ptr = std::make_shared<MemberFunction>(_lambda);
|
|
609
|
+
return std::static_pointer_cast<Function>(ptr);
|
|
610
|
+
}
|
|
738
611
|
|
|
739
|
-
|
|
740
|
-
|
|
612
|
+
virtual void do_call_function(json& json) {
|
|
613
|
+
try {
|
|
614
|
+
json["r"] = vrpc::call(_lambda(_ptr), vrpc::unpack<Args...>(json));
|
|
615
|
+
} catch (const std::exception& e) {
|
|
616
|
+
json["e"] = std::string(e.what());
|
|
741
617
|
}
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
template <typename Lambda, typename Ret, typename ...Args>
|
|
745
|
-
class StaticFunction : public Function {
|
|
746
|
-
Lambda m_lambda;
|
|
618
|
+
}
|
|
747
619
|
|
|
748
|
-
|
|
620
|
+
virtual void do_bind_instance(const Value& instance) {
|
|
621
|
+
_ptr = instance.get<std::shared_ptr<Klass>>();
|
|
622
|
+
}
|
|
623
|
+
};
|
|
749
624
|
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
625
|
+
template <typename Klass, typename Lambda, typename... Args>
|
|
626
|
+
class MemberFunction<Klass, Lambda, void, Args...> : public Function {
|
|
627
|
+
Lambda _lambda;
|
|
628
|
+
std::shared_ptr<Klass> _ptr;
|
|
753
629
|
|
|
754
|
-
|
|
630
|
+
public:
|
|
631
|
+
MemberFunction(const Lambda& lambda) : _lambda(lambda) {}
|
|
755
632
|
|
|
756
|
-
|
|
757
|
-
auto ptr = std::make_shared<StaticFunction>(m_lambda);
|
|
758
|
-
return std::static_pointer_cast<Function>(ptr);
|
|
759
|
-
}
|
|
633
|
+
virtual ~MemberFunction() = default;
|
|
760
634
|
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
json["data"]["e"] = std::string(e.what());
|
|
766
|
-
}
|
|
767
|
-
}
|
|
635
|
+
virtual std::shared_ptr<Function> do_clone() {
|
|
636
|
+
auto ptr = std::make_shared<MemberFunction>(_lambda);
|
|
637
|
+
return std::static_pointer_cast<Function>(ptr);
|
|
638
|
+
}
|
|
768
639
|
|
|
769
|
-
|
|
770
|
-
|
|
640
|
+
virtual void do_call_function(json& json) {
|
|
641
|
+
try {
|
|
642
|
+
vrpc::call(_lambda(_ptr), vrpc::unpack<Args...>(json));
|
|
643
|
+
json["r"] = nullptr;
|
|
644
|
+
} catch (const std::exception& e) {
|
|
645
|
+
json["e"] = std::string(e.what());
|
|
771
646
|
}
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
template <typename Lambda, typename ...Args>
|
|
775
|
-
class StaticFunction<Lambda, void, Args...> : public Function {
|
|
776
|
-
Lambda m_lambda;
|
|
647
|
+
}
|
|
777
648
|
|
|
778
|
-
|
|
649
|
+
virtual void do_bind_instance(const Value& instance) {
|
|
650
|
+
_ptr = instance.get<std::shared_ptr<Klass>>();
|
|
651
|
+
}
|
|
652
|
+
};
|
|
779
653
|
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
654
|
+
template <typename Lambda, typename Ret, typename... Args>
|
|
655
|
+
class StaticFunction : public Function {
|
|
656
|
+
Lambda _lambda;
|
|
783
657
|
|
|
784
|
-
|
|
658
|
+
public:
|
|
659
|
+
StaticFunction(const Lambda& lambda) : _lambda(lambda) {}
|
|
785
660
|
|
|
786
|
-
|
|
787
|
-
auto ptr = std::make_shared<StaticFunction>(m_lambda);
|
|
788
|
-
return std::static_pointer_cast<Function>(ptr);
|
|
789
|
-
}
|
|
661
|
+
virtual ~StaticFunction() = default;
|
|
790
662
|
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
} catch (const std::exception& e) {
|
|
796
|
-
json["data"]["e"] = std::string(e.what());
|
|
797
|
-
}
|
|
798
|
-
}
|
|
663
|
+
virtual std::shared_ptr<Function> do_clone() {
|
|
664
|
+
auto ptr = std::make_shared<StaticFunction>(_lambda);
|
|
665
|
+
return std::static_pointer_cast<Function>(ptr);
|
|
666
|
+
}
|
|
799
667
|
|
|
800
|
-
|
|
801
|
-
|
|
668
|
+
virtual void do_call_function(json& json) {
|
|
669
|
+
try {
|
|
670
|
+
json["r"] = vrpc::call(_lambda(), vrpc::unpack<Args...>(json));
|
|
671
|
+
} catch (const std::exception& e) {
|
|
672
|
+
json["e"] = std::string(e.what());
|
|
802
673
|
}
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
template <typename Lambda, typename ...Args>
|
|
806
|
-
class ConstructorFunction : public Function {
|
|
807
|
-
Lambda m_lambda;
|
|
674
|
+
}
|
|
808
675
|
|
|
809
|
-
|
|
676
|
+
virtual void do_bind_instance(const Value&) {
|
|
677
|
+
// Nothing to bind, static function
|
|
678
|
+
}
|
|
679
|
+
};
|
|
810
680
|
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
681
|
+
template <typename Lambda, typename... Args>
|
|
682
|
+
class StaticFunction<Lambda, void, Args...> : public Function {
|
|
683
|
+
Lambda _lambda;
|
|
814
684
|
|
|
815
|
-
|
|
685
|
+
public:
|
|
686
|
+
StaticFunction(const Lambda& lambda) : _lambda(lambda) {}
|
|
816
687
|
|
|
817
|
-
|
|
818
|
-
auto ptr = std::make_shared<ConstructorFunction>(m_lambda);
|
|
819
|
-
return std::static_pointer_cast<Function>(ptr);
|
|
820
|
-
}
|
|
688
|
+
virtual ~StaticFunction() = default;
|
|
821
689
|
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
json["data"]["e"] = std::string(e.what());
|
|
827
|
-
}
|
|
828
|
-
}
|
|
690
|
+
virtual std::shared_ptr<Function> do_clone() {
|
|
691
|
+
auto ptr = std::make_shared<StaticFunction>(_lambda);
|
|
692
|
+
return std::static_pointer_cast<Function>(ptr);
|
|
693
|
+
}
|
|
829
694
|
|
|
830
|
-
|
|
831
|
-
|
|
695
|
+
virtual void do_call_function(json& json) {
|
|
696
|
+
try {
|
|
697
|
+
vrpc::call(_lambda(), vrpc::unpack<Args...>(json));
|
|
698
|
+
json["r"] = nullptr;
|
|
699
|
+
} catch (const std::exception& e) {
|
|
700
|
+
json["e"] = std::string(e.what());
|
|
832
701
|
}
|
|
833
|
-
}
|
|
702
|
+
}
|
|
834
703
|
|
|
835
|
-
|
|
704
|
+
virtual void do_bind_instance(const Value&) {
|
|
705
|
+
// Nothing to bind, static function
|
|
706
|
+
}
|
|
707
|
+
};
|
|
836
708
|
|
|
709
|
+
template <typename Lambda, typename... Args>
|
|
710
|
+
class ConstructorFunction : public Function {
|
|
711
|
+
Lambda _lambda;
|
|
837
712
|
|
|
713
|
+
public:
|
|
714
|
+
ConstructorFunction(const Lambda& lambda) : _lambda(lambda) {}
|
|
838
715
|
|
|
839
|
-
|
|
840
|
-
struct param {
|
|
841
|
-
json j;
|
|
842
|
-
template <typename DefaultType>
|
|
843
|
-
param(const std::string& name,
|
|
844
|
-
const DefaultType& default_value,
|
|
845
|
-
const std::string& description) {
|
|
846
|
-
// json tmp{{"t", type()}};
|
|
847
|
-
// j["type"] = tmp["t"].type_name();
|
|
848
|
-
j["name"] = name;
|
|
849
|
-
j["optional"] = true;
|
|
850
|
-
j["default"] = default_value;
|
|
851
|
-
j["description"] = description;
|
|
852
|
-
}
|
|
853
|
-
param(const std::string& name,
|
|
854
|
-
const required& default_value,
|
|
855
|
-
const std::string& description) {
|
|
856
|
-
// json tmp{{"t", type()}};
|
|
857
|
-
// j["type"] = tmp["t"].type_name();
|
|
858
|
-
j["name"] = name;
|
|
859
|
-
j["optional"] = false;
|
|
860
|
-
j["default"] = nullptr;
|
|
861
|
-
j["description"] = description;
|
|
862
|
-
}
|
|
863
|
-
};
|
|
716
|
+
virtual ~ConstructorFunction() = default;
|
|
864
717
|
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
ret(const std::string& description) {
|
|
869
|
-
j["type"] = json(ValueType()).type_name();
|
|
870
|
-
j["description"] = description;
|
|
871
|
-
}
|
|
872
|
-
};
|
|
873
|
-
template<>
|
|
874
|
-
struct ret<void>{
|
|
875
|
-
json j;
|
|
876
|
-
ret(const std::string& description) {
|
|
877
|
-
j["type"] = "void";
|
|
878
|
-
j["description"] = description;
|
|
879
|
-
}
|
|
880
|
-
};
|
|
718
|
+
virtual std::shared_ptr<Function> do_clone() {
|
|
719
|
+
auto ptr = std::make_shared<ConstructorFunction>(_lambda);
|
|
720
|
+
return std::static_pointer_cast<Function>(ptr);
|
|
881
721
|
}
|
|
882
722
|
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
typedef std::unordered_map<std::string, Value > StringAnyMap;
|
|
889
|
-
typedef std::unordered_map<std::string, std::shared_ptr<Function> > StringFunctionMap;
|
|
890
|
-
typedef std::unordered_map<std::string, StringFunctionMap> FunctionRegistry;
|
|
891
|
-
typedef std::unordered_map<std::string, std::string > NamedInstances;
|
|
892
|
-
typedef std::unordered_map<std::string, vrpc::json > MetaData;
|
|
893
|
-
|
|
894
|
-
// Maps: class_name => function_name => functionCallback
|
|
895
|
-
FunctionRegistry m_class_function_registry;
|
|
896
|
-
// Maps: instanceId => function_name => functionCallback
|
|
897
|
-
FunctionRegistry m_function_registry;
|
|
898
|
-
// Maps: instanceId => instanceObj
|
|
899
|
-
StringAnyMap m_instances;
|
|
900
|
-
// Maps: instanceId => class_name
|
|
901
|
-
NamedInstances m_named_instances;
|
|
902
|
-
// Optional schema information
|
|
903
|
-
MetaData m_meta_data;
|
|
904
|
-
|
|
905
|
-
public:
|
|
906
|
-
|
|
907
|
-
template <typename Klass, typename ...Args>
|
|
908
|
-
static void register_constructor(const std::string& class_name) {
|
|
909
|
-
LocalFactory::inject_create_function<Klass, Args...>(class_name);
|
|
910
|
-
LocalFactory::inject_create_named_function<Klass, Args...>(class_name);
|
|
911
|
-
LocalFactory::inject_get_named_function<Klass>(class_name);
|
|
912
|
-
LocalFactory::inject_delete_function<Klass>(class_name);
|
|
723
|
+
virtual void do_call_function(json& json) {
|
|
724
|
+
try {
|
|
725
|
+
json["r"] = vrpc::call(_lambda, vrpc::unpack<Args...>(json));
|
|
726
|
+
} catch (const std::exception& e) {
|
|
727
|
+
json["e"] = std::string(e.what());
|
|
913
728
|
}
|
|
729
|
+
}
|
|
914
730
|
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
731
|
+
virtual void do_bind_instance(const Value&) {
|
|
732
|
+
// Nothing to bind
|
|
733
|
+
}
|
|
734
|
+
};
|
|
735
|
+
|
|
736
|
+
struct required {};
|
|
737
|
+
|
|
738
|
+
namespace detail {
|
|
739
|
+
struct param {
|
|
740
|
+
json j;
|
|
741
|
+
template <typename DefaultType>
|
|
742
|
+
param(const std::string& name,
|
|
743
|
+
const DefaultType& default_value,
|
|
744
|
+
const std::string& description) {
|
|
745
|
+
// json tmp{{"t", type()}};
|
|
746
|
+
// j["type"] = tmp["t"].type_name();
|
|
747
|
+
j["name"] = name;
|
|
748
|
+
j["optional"] = true;
|
|
749
|
+
j["default"] = default_value;
|
|
750
|
+
j["description"] = description;
|
|
751
|
+
}
|
|
752
|
+
param(const std::string& name,
|
|
753
|
+
const required& default_value,
|
|
754
|
+
const std::string& description) {
|
|
755
|
+
// json tmp{{"t", type()}};
|
|
756
|
+
// j["type"] = tmp["t"].type_name();
|
|
757
|
+
j["name"] = name;
|
|
758
|
+
j["optional"] = false;
|
|
759
|
+
j["default"] = nullptr;
|
|
760
|
+
j["description"] = description;
|
|
761
|
+
}
|
|
762
|
+
};
|
|
763
|
+
|
|
764
|
+
template <typename ValueType>
|
|
765
|
+
struct ret {
|
|
766
|
+
json j;
|
|
767
|
+
ret(const std::string& description) {
|
|
768
|
+
j["type"] = json(ValueType()).type_name();
|
|
769
|
+
j["description"] = description;
|
|
770
|
+
}
|
|
771
|
+
};
|
|
772
|
+
template <>
|
|
773
|
+
struct ret<void> {
|
|
774
|
+
json j;
|
|
775
|
+
ret(const std::string& description) {
|
|
776
|
+
j["type"] = "void";
|
|
777
|
+
j["description"] = description;
|
|
778
|
+
}
|
|
779
|
+
};
|
|
780
|
+
} // namespace detail
|
|
781
|
+
|
|
782
|
+
class LocalFactory {
|
|
783
|
+
friend LocalFactory& detail::init<LocalFactory>();
|
|
784
|
+
friend class Proxy;
|
|
785
|
+
friend class MqttClient;
|
|
786
|
+
|
|
787
|
+
typedef std::unordered_map<std::string, Value> StringAnyMap;
|
|
788
|
+
typedef std::unordered_map<std::string, std::shared_ptr<Function>>
|
|
789
|
+
StringFunctionMap;
|
|
790
|
+
typedef std::unordered_map<std::string, StringFunctionMap> FunctionRegistry;
|
|
791
|
+
typedef std::unordered_map<std::string, std::string> SharedInstances;
|
|
792
|
+
typedef std::unordered_map<std::string, json> MetaData;
|
|
793
|
+
|
|
794
|
+
// Maps: class_name => function_name => functionCallback
|
|
795
|
+
FunctionRegistry _class_function_registry;
|
|
796
|
+
// Maps: instanceId => function_name => functionCallback
|
|
797
|
+
FunctionRegistry _function_registry;
|
|
798
|
+
// Maps: instanceId => instanceObj
|
|
799
|
+
StringAnyMap _instances;
|
|
800
|
+
// Maps: instanceId => class_name
|
|
801
|
+
SharedInstances _shared_instances;
|
|
802
|
+
// Optional schema information
|
|
803
|
+
MetaData _meta_data;
|
|
804
|
+
|
|
805
|
+
public:
|
|
806
|
+
template <typename Klass, typename... Args>
|
|
807
|
+
static void register_constructor(const std::string& class_name) {
|
|
808
|
+
LocalFactory::inject_create_isolated_function<Klass, Args...>(class_name);
|
|
809
|
+
LocalFactory::inject_create_shared_function<Klass, Args...>(class_name);
|
|
810
|
+
LocalFactory::inject_delete_function<Klass>(class_name);
|
|
811
|
+
}
|
|
934
812
|
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
813
|
+
template <typename Klass,
|
|
814
|
+
typename Func,
|
|
815
|
+
Func f,
|
|
816
|
+
typename Ret,
|
|
817
|
+
typename... Args>
|
|
818
|
+
static void register_member_function(const std::string& class_name,
|
|
819
|
+
const std::string& function_name) {
|
|
820
|
+
auto func = [](const std::shared_ptr<Klass>& ptr) {
|
|
821
|
+
return vrpc::variadic_bind_member<Klass, Func, Args...>(f, ptr);
|
|
822
|
+
};
|
|
823
|
+
auto funcT =
|
|
824
|
+
std::make_shared<MemberFunction<Klass, decltype(func), Ret, Args...>>(
|
|
825
|
+
func);
|
|
826
|
+
detail::init<LocalFactory>()
|
|
827
|
+
._class_function_registry[class_name][function_name] =
|
|
828
|
+
std::static_pointer_cast<Function>(funcT);
|
|
829
|
+
_VRPC_DEBUG << "Registered: " << class_name << "::" << function_name
|
|
830
|
+
<< std::endl;
|
|
831
|
+
}
|
|
946
832
|
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
833
|
+
template <typename Func, Func f, typename Ret, typename... Args>
|
|
834
|
+
static void register_static_function(const std::string& class_name,
|
|
835
|
+
const std::string& function_name) {
|
|
836
|
+
auto func = []() { return vrpc::variadic_bind<Func, Args...>(f); };
|
|
837
|
+
auto funcT =
|
|
838
|
+
std::make_shared<StaticFunction<decltype(func), Ret, Args...>>(func);
|
|
839
|
+
detail::init<LocalFactory>()._function_registry[class_name][function_name] =
|
|
840
|
+
std::static_pointer_cast<Function>(funcT);
|
|
841
|
+
_VRPC_DEBUG << "Registered: " << class_name << "::" << function_name
|
|
842
|
+
<< std::endl;
|
|
843
|
+
}
|
|
958
844
|
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
845
|
+
static void register_meta_data(const std::string& class_name,
|
|
846
|
+
const std::string& function_name,
|
|
847
|
+
const std::string& description,
|
|
848
|
+
const json& params,
|
|
849
|
+
const json& ret) {
|
|
850
|
+
LocalFactory& rf = detail::init<LocalFactory>();
|
|
851
|
+
json& j = rf._meta_data[class_name];
|
|
852
|
+
j[function_name]["description"] = description;
|
|
853
|
+
j[function_name]["params"] = params;
|
|
854
|
+
j[function_name]["ret"] = ret;
|
|
855
|
+
}
|
|
966
856
|
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
if (
|
|
971
|
-
|
|
972
|
-
functions.push_back(kv.first);
|
|
973
|
-
}
|
|
974
|
-
}
|
|
975
|
-
return functions;
|
|
857
|
+
static std::vector<std::string> get_instances(const std::string& class_name) {
|
|
858
|
+
std::vector<std::string> instances;
|
|
859
|
+
for (const auto& kv : detail::init<LocalFactory>()._shared_instances) {
|
|
860
|
+
if (kv.second == class_name)
|
|
861
|
+
instances.push_back(kv.first);
|
|
976
862
|
}
|
|
863
|
+
return instances;
|
|
864
|
+
}
|
|
977
865
|
|
|
978
|
-
|
|
979
|
-
const std::string& class_name
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
}
|
|
866
|
+
static std::vector<std::string> get_member_functions(
|
|
867
|
+
const std::string& class_name) {
|
|
868
|
+
std::vector<std::string> functions;
|
|
869
|
+
const auto& it =
|
|
870
|
+
detail::init<LocalFactory>()._class_function_registry.find(class_name);
|
|
871
|
+
if (it != detail::init<LocalFactory>()._class_function_registry.end()) {
|
|
872
|
+
for (const auto& kv : it->second) {
|
|
873
|
+
functions.push_back(kv.first);
|
|
987
874
|
}
|
|
988
|
-
return functions;
|
|
989
875
|
}
|
|
876
|
+
return functions;
|
|
877
|
+
}
|
|
990
878
|
|
|
991
|
-
|
|
992
|
-
std::
|
|
993
|
-
|
|
994
|
-
|
|
879
|
+
static std::vector<std::string> get_static_functions(
|
|
880
|
+
const std::string& class_name) {
|
|
881
|
+
std::vector<std::string> functions;
|
|
882
|
+
const auto& it =
|
|
883
|
+
detail::init<LocalFactory>()._function_registry.find(class_name);
|
|
884
|
+
if (it != detail::init<LocalFactory>()._function_registry.end()) {
|
|
885
|
+
for (const auto& kv : it->second) {
|
|
886
|
+
functions.push_back(kv.first);
|
|
995
887
|
}
|
|
996
|
-
return classes;
|
|
997
888
|
}
|
|
889
|
+
return functions;
|
|
890
|
+
}
|
|
998
891
|
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
892
|
+
static std::vector<std::string> get_classes() {
|
|
893
|
+
std::vector<std::string> classes;
|
|
894
|
+
for (const auto& kv :
|
|
895
|
+
detail::init<LocalFactory>()._class_function_registry) {
|
|
896
|
+
classes.push_back(kv.first);
|
|
1002
897
|
}
|
|
898
|
+
return classes;
|
|
899
|
+
}
|
|
1003
900
|
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
return json.dump();
|
|
1009
|
-
}
|
|
901
|
+
static json get_meta_data(const std::string& class_name) {
|
|
902
|
+
LocalFactory& rf = detail::init<LocalFactory>();
|
|
903
|
+
return rf._meta_data[class_name];
|
|
904
|
+
}
|
|
1010
905
|
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
906
|
+
static std::string call(const std::string& jsonString) {
|
|
907
|
+
json json;
|
|
908
|
+
json = json::parse(jsonString);
|
|
909
|
+
LocalFactory::call(json);
|
|
910
|
+
return json.dump();
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
static void call(json& json) {
|
|
914
|
+
const std::string context = json["c"].get<std::string>();
|
|
915
|
+
std::string function = json["f"].get<std::string>();
|
|
916
|
+
function += vrpc::get_signature(json["a"]);
|
|
917
|
+
_VRPC_DEBUG << "Calling function: " << function
|
|
918
|
+
<< " with payload: " << json["a"] << std::endl;
|
|
919
|
+
auto it_t = detail::init<LocalFactory>()._function_registry.find(context);
|
|
920
|
+
if (it_t != detail::init<LocalFactory>()._function_registry.end()) {
|
|
921
|
+
auto it_f = it_t->second.find(function);
|
|
922
|
+
if (it_f != it_t->second.end()) {
|
|
923
|
+
it_f->second->call_function(json);
|
|
1026
924
|
return;
|
|
1027
925
|
}
|
|
1028
|
-
json["
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
static void load_bindings(const std::string& path) {
|
|
1032
|
-
#if defined(VRPC_WITH_DL) && !defined(_WIN32)
|
|
1033
|
-
void* libHandle = dlopen(path.c_str(), RTLD_LAZY);
|
|
1034
|
-
if (libHandle == 0) {
|
|
1035
|
-
throw std::runtime_error("Problem loading bindings: " +
|
|
1036
|
-
std::string(dlerror()));
|
|
1037
|
-
}
|
|
1038
|
-
#else
|
|
1039
|
-
_VRPC_DEBUG << "Ignored call, dynamic loading is disabled" << std::endl;
|
|
1040
|
-
#endif
|
|
926
|
+
json["e"] = "Could not find function: " + function;
|
|
927
|
+
return;
|
|
1041
928
|
}
|
|
929
|
+
json["e"] = "Could not find context: " + context;
|
|
930
|
+
}
|
|
1042
931
|
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
virtual ~LocalFactory() = default;
|
|
1050
|
-
|
|
1051
|
-
template <typename Klass>
|
|
1052
|
-
static std::string create_instance_id(
|
|
1053
|
-
const std::shared_ptr<Klass>& ptr
|
|
1054
|
-
) noexcept {
|
|
1055
|
-
std::ostringstream ss;
|
|
1056
|
-
ss << reinterpret_cast<std::uintptr_t> (ptr.get());
|
|
1057
|
-
return ss.str();
|
|
932
|
+
static void load_bindings(const std::string& path) {
|
|
933
|
+
#if defined(VRPC_WITH_DL) && !defined(_WIN32)
|
|
934
|
+
void* libHandle = dlopen(path.c_str(), RTLD_LAZY);
|
|
935
|
+
if (libHandle == 0) {
|
|
936
|
+
throw std::runtime_error("Problem loading bindings: " +
|
|
937
|
+
std::string(dlerror()));
|
|
1058
938
|
}
|
|
939
|
+
#else
|
|
940
|
+
_VRPC_DEBUG << "Ignored call, dynamic loading is disabled" << std::endl;
|
|
941
|
+
#endif
|
|
942
|
+
}
|
|
1059
943
|
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
auto func = [ = ](Args... args){
|
|
1063
|
-
LocalFactory& rf = detail::init<LocalFactory>();
|
|
1064
|
-
// Create instance
|
|
1065
|
-
auto ptr = std::shared_ptr<Klass>(new Klass(args...));
|
|
1066
|
-
// Generate instance_id
|
|
1067
|
-
const std::string instance_id = create_instance_id(ptr);
|
|
1068
|
-
// Bind member functions
|
|
1069
|
-
for (auto& i : rf.m_class_function_registry[class_name]) {
|
|
1070
|
-
auto functionCallback = i.second->clone();
|
|
1071
|
-
functionCallback->bind_instance(ptr);
|
|
1072
|
-
rf.m_function_registry[instance_id][i.first] = functionCallback;
|
|
1073
|
-
}
|
|
1074
|
-
// Keep instance alive by saving the shared_ptr
|
|
1075
|
-
rf.m_instances[instance_id] = Value(ptr);
|
|
1076
|
-
return instance_id;
|
|
1077
|
-
};
|
|
1078
|
-
auto funcT = std::make_shared<ConstructorFunction<decltype(func), Args...>>(func);
|
|
1079
|
-
const std::string func_name("__create__" + vrpc::get_signature<Args...>());
|
|
1080
|
-
detail::init<LocalFactory>().m_function_registry[class_name][func_name] =
|
|
1081
|
-
std::static_pointer_cast<Function>(funcT);
|
|
1082
|
-
_VRPC_DEBUG << "Registered: " << class_name << "::" << func_name << std::endl;
|
|
1083
|
-
}
|
|
1084
|
-
|
|
1085
|
-
template <typename Klass, typename ...Args>
|
|
1086
|
-
static void inject_create_named_function(const std::string& class_name) {
|
|
1087
|
-
auto func = [ = ](const std::string& instance_id, Args... args){
|
|
1088
|
-
LocalFactory& rf = detail::init<LocalFactory>();
|
|
1089
|
-
const auto& it = rf.m_instances.find(instance_id);
|
|
1090
|
-
if (it != rf.m_instances.end()) return instance_id;
|
|
1091
|
-
// Create instance
|
|
1092
|
-
auto ptr = std::shared_ptr<Klass>(new Klass(args...));
|
|
1093
|
-
// Bind member functions
|
|
1094
|
-
for (auto& i : rf.m_class_function_registry[class_name]) {
|
|
1095
|
-
auto functionCallback = i.second->clone();
|
|
1096
|
-
functionCallback->bind_instance(ptr);
|
|
1097
|
-
rf.m_function_registry[instance_id][i.first] = functionCallback;
|
|
1098
|
-
}
|
|
1099
|
-
// Keep instance alive by saving the shared_ptr
|
|
1100
|
-
rf.m_instances[instance_id] = Value(ptr);
|
|
1101
|
-
// Store named instance
|
|
1102
|
-
rf.m_named_instances.insert({instance_id, class_name});
|
|
1103
|
-
return instance_id;
|
|
1104
|
-
};
|
|
1105
|
-
auto funcT = std::make_shared<ConstructorFunction<decltype(func), const std::string&, Args...>>(func);
|
|
1106
|
-
const std::string func_name("__createNamed__" + vrpc::get_signature<std::string, Args...>());
|
|
1107
|
-
detail::init<LocalFactory>().m_function_registry[class_name][func_name] =
|
|
1108
|
-
std::static_pointer_cast<Function>(funcT);
|
|
1109
|
-
_VRPC_DEBUG << "Registered: " << class_name << "::" << func_name << std::endl;
|
|
1110
|
-
}
|
|
1111
|
-
|
|
1112
|
-
template <typename Klass>
|
|
1113
|
-
static void inject_get_named_function(const std::string& class_name) {
|
|
1114
|
-
auto func = [ = ](const std::string& instance_id){
|
|
1115
|
-
LocalFactory& rf = detail::init<LocalFactory>();
|
|
1116
|
-
const auto& it = rf.m_instances.find(instance_id);
|
|
1117
|
-
if (it != rf.m_instances.end()) return instance_id;
|
|
1118
|
-
throw std::runtime_error("Instance with id: " + instance_id + " does not exist");
|
|
1119
|
-
};
|
|
1120
|
-
auto funcT = std::make_shared<ConstructorFunction<decltype(func), const std::string& >>(func);
|
|
1121
|
-
const std::string func_name("__getNamed__" + vrpc::get_signature<std::string>());
|
|
1122
|
-
detail::init<LocalFactory>().m_function_registry[class_name][func_name] =
|
|
1123
|
-
std::static_pointer_cast<Function>(funcT);
|
|
1124
|
-
_VRPC_DEBUG << "Registered: " << class_name << "::" << func_name << std::endl;
|
|
1125
|
-
}
|
|
1126
|
-
|
|
1127
|
-
template <typename Klass>
|
|
1128
|
-
static void inject_delete_function(const std::string& class_name) {
|
|
1129
|
-
auto func = [ = ](const std::string& instance_id){
|
|
1130
|
-
LocalFactory& rf = detail::init<LocalFactory>();
|
|
1131
|
-
const auto& it = rf.m_instances.find(instance_id);
|
|
1132
|
-
if (it == rf.m_instances.end()) return false;
|
|
1133
|
-
rf.m_function_registry.erase(instance_id);
|
|
1134
|
-
rf.m_instances.erase(instance_id);
|
|
1135
|
-
rf.m_named_instances.erase(instance_id);
|
|
1136
|
-
return true;
|
|
1137
|
-
};
|
|
1138
|
-
auto funcT = std::make_shared<ConstructorFunction<decltype(func), const std::string& >>(func);
|
|
1139
|
-
const std::string func_name("__delete__" + vrpc::get_signature<std::string>());
|
|
1140
|
-
detail::init<LocalFactory>().m_function_registry[class_name][func_name] =
|
|
1141
|
-
std::static_pointer_cast<Function>(funcT);
|
|
1142
|
-
_VRPC_DEBUG << "Registered: " << class_name << "::" << func_name << std::endl;
|
|
1143
|
-
}
|
|
1144
|
-
};
|
|
1145
|
-
|
|
1146
|
-
namespace detail {
|
|
1147
|
-
|
|
1148
|
-
template <class Klass, typename ...Args>
|
|
1149
|
-
struct CtorRegistrar {
|
|
1150
|
-
|
|
1151
|
-
CtorRegistrar(const std::string& class_name) {
|
|
1152
|
-
LocalFactory::register_constructor<Klass, Args...> (class_name);
|
|
1153
|
-
}
|
|
1154
|
-
};
|
|
1155
|
-
|
|
1156
|
-
template <class Klass, typename ...Args>
|
|
1157
|
-
struct RegisterCtor {
|
|
1158
|
-
static const CtorRegistrar<Klass, Args...> registerAs;
|
|
1159
|
-
};
|
|
1160
|
-
|
|
1161
|
-
template <class Klass, typename... Args>
|
|
1162
|
-
struct CtorXRegistrar {
|
|
1163
|
-
CtorXRegistrar(const std::string& class_name,
|
|
1164
|
-
const std::string& ctor_description,
|
|
1165
|
-
const ret<std::string>& ret,
|
|
1166
|
-
const std::vector<param> params = {}) {
|
|
1167
|
-
LocalFactory::register_constructor<Klass, Args...>(class_name);
|
|
1168
|
-
const std::string ctor_name("__createNamed__" + vrpc::get_signature<std::string, Args...>());
|
|
1169
|
-
json jp;
|
|
1170
|
-
for (const auto& param : params) {
|
|
1171
|
-
jp.push_back(param.j);
|
|
1172
|
-
}
|
|
1173
|
-
LocalFactory::register_meta_data(class_name, ctor_name,
|
|
1174
|
-
ctor_description, jp, ret.j);
|
|
1175
|
-
}
|
|
1176
|
-
};
|
|
944
|
+
private:
|
|
945
|
+
LocalFactory() {}
|
|
1177
946
|
|
|
1178
|
-
|
|
1179
|
-
struct RegisterCtorX {
|
|
1180
|
-
static const CtorXRegistrar<Klass, Args...> registerAs;
|
|
1181
|
-
};
|
|
947
|
+
LocalFactory(const LocalFactory&) = default;
|
|
1182
948
|
|
|
949
|
+
virtual ~LocalFactory() = default;
|
|
1183
950
|
|
|
1184
|
-
|
|
1185
|
-
|
|
951
|
+
template <typename Klass>
|
|
952
|
+
static std::string create_instance_id(
|
|
953
|
+
const std::shared_ptr<Klass>& ptr) noexcept {
|
|
954
|
+
std::ostringstream ss;
|
|
955
|
+
ss << reinterpret_cast<std::uintptr_t>(ptr.get());
|
|
956
|
+
return ss.str();
|
|
957
|
+
}
|
|
1186
958
|
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
959
|
+
template <typename Klass, typename... Args>
|
|
960
|
+
static void inject_create_isolated_function(const std::string& class_name) {
|
|
961
|
+
auto func = [=](const std::string& instance_id, Args... args) {
|
|
962
|
+
LocalFactory& rf = detail::init<LocalFactory>();
|
|
963
|
+
const auto& it = rf._instances.find(instance_id);
|
|
964
|
+
if (it != rf._instances.end())
|
|
965
|
+
return instance_id;
|
|
966
|
+
// Create instance
|
|
967
|
+
auto ptr = std::shared_ptr<Klass>(new Klass(args...));
|
|
968
|
+
// Bind member functions
|
|
969
|
+
for (auto& i : rf._class_function_registry[class_name]) {
|
|
970
|
+
auto functionCallback = i.second->clone();
|
|
971
|
+
functionCallback->bind_instance(ptr);
|
|
972
|
+
rf._function_registry[instance_id][i.first] = functionCallback;
|
|
1197
973
|
}
|
|
974
|
+
// Keep instance alive by saving the shared_ptr
|
|
975
|
+
rf._instances[instance_id] = Value(ptr);
|
|
976
|
+
return instance_id;
|
|
1198
977
|
};
|
|
978
|
+
auto funcT = std::make_shared<
|
|
979
|
+
ConstructorFunction<decltype(func), const std::string&, Args...>>(func);
|
|
980
|
+
const std::string func_name("__createIsolated__" +
|
|
981
|
+
vrpc::get_signature<std::string, Args...>());
|
|
982
|
+
detail::init<LocalFactory>()._function_registry[class_name][func_name] =
|
|
983
|
+
std::static_pointer_cast<Function>(funcT);
|
|
984
|
+
_VRPC_DEBUG << "Registered: " << class_name << "::" << func_name
|
|
985
|
+
<< std::endl;
|
|
986
|
+
}
|
|
1199
987
|
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
class_name, full_function_name);
|
|
1215
|
-
json jp;
|
|
1216
|
-
for (const auto& param : params) {
|
|
1217
|
-
jp.push_back(param.j);
|
|
1218
|
-
}
|
|
1219
|
-
LocalFactory::register_meta_data(class_name, full_function_name,
|
|
1220
|
-
function_description, jp, ret.j);
|
|
988
|
+
template <typename Klass, typename... Args>
|
|
989
|
+
static void inject_create_shared_function(const std::string& class_name) {
|
|
990
|
+
auto func = [=](const std::string& instance_id, Args... args) {
|
|
991
|
+
LocalFactory& rf = detail::init<LocalFactory>();
|
|
992
|
+
const auto& it = rf._instances.find(instance_id);
|
|
993
|
+
if (it != rf._instances.end())
|
|
994
|
+
return instance_id;
|
|
995
|
+
// Create instance
|
|
996
|
+
auto ptr = std::shared_ptr<Klass>(new Klass(args...));
|
|
997
|
+
// Bind member functions
|
|
998
|
+
for (auto& i : rf._class_function_registry[class_name]) {
|
|
999
|
+
auto functionCallback = i.second->clone();
|
|
1000
|
+
functionCallback->bind_instance(ptr);
|
|
1001
|
+
rf._function_registry[instance_id][i.first] = functionCallback;
|
|
1221
1002
|
}
|
|
1003
|
+
// Keep instance alive by saving the shared_ptr
|
|
1004
|
+
rf._instances[instance_id] = Value(ptr);
|
|
1005
|
+
// Store shared instance
|
|
1006
|
+
rf._shared_instances.insert({instance_id, class_name});
|
|
1007
|
+
return instance_id;
|
|
1222
1008
|
};
|
|
1009
|
+
auto funcT = std::make_shared<
|
|
1010
|
+
ConstructorFunction<decltype(func), const std::string&, Args...>>(func);
|
|
1011
|
+
const std::string func_name("__createShared__" +
|
|
1012
|
+
vrpc::get_signature<std::string, Args...>());
|
|
1013
|
+
detail::init<LocalFactory>()._function_registry[class_name][func_name] =
|
|
1014
|
+
std::static_pointer_cast<Function>(funcT);
|
|
1015
|
+
_VRPC_DEBUG << "Registered: " << class_name << "::" << func_name
|
|
1016
|
+
<< std::endl;
|
|
1017
|
+
}
|
|
1223
1018
|
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
struct StaticFunctionRegistrar {
|
|
1236
|
-
StaticFunctionRegistrar(const std::string& class_name,
|
|
1237
|
-
const std::string& function_name) {
|
|
1238
|
-
const std::string full_function_name(function_name +
|
|
1239
|
-
vrpc::get_signature<Args...>());
|
|
1240
|
-
LocalFactory::register_static_function<Func, f, Ret, Args...>(
|
|
1241
|
-
class_name, full_function_name);
|
|
1242
|
-
}
|
|
1019
|
+
template <typename Klass>
|
|
1020
|
+
static void inject_delete_function(const std::string& class_name) {
|
|
1021
|
+
auto func = [=](const std::string& instance_id) {
|
|
1022
|
+
LocalFactory& rf = detail::init<LocalFactory>();
|
|
1023
|
+
const auto& it = rf._instances.find(instance_id);
|
|
1024
|
+
if (it == rf._instances.end())
|
|
1025
|
+
return false;
|
|
1026
|
+
rf._function_registry.erase(instance_id);
|
|
1027
|
+
rf._instances.erase(instance_id);
|
|
1028
|
+
rf._shared_instances.erase(instance_id);
|
|
1029
|
+
return true;
|
|
1243
1030
|
};
|
|
1031
|
+
auto funcT = std::make_shared<
|
|
1032
|
+
ConstructorFunction<decltype(func), const std::string&>>(func);
|
|
1033
|
+
const std::string func_name("__delete__" +
|
|
1034
|
+
vrpc::get_signature<std::string>());
|
|
1035
|
+
detail::init<LocalFactory>()._function_registry[class_name][func_name] =
|
|
1036
|
+
std::static_pointer_cast<Function>(funcT);
|
|
1037
|
+
_VRPC_DEBUG << "Registered: " << class_name << "::" << func_name
|
|
1038
|
+
<< std::endl;
|
|
1039
|
+
}
|
|
1040
|
+
};
|
|
1244
1041
|
|
|
1245
|
-
|
|
1246
|
-
struct RegisterStaticFunction {
|
|
1247
|
-
static const StaticFunctionRegistrar<Func, f, Ret, Args...> registerAs;
|
|
1248
|
-
};
|
|
1042
|
+
namespace detail {
|
|
1249
1043
|
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1044
|
+
template <class Klass, typename... Args>
|
|
1045
|
+
struct CtorRegistrar {
|
|
1046
|
+
CtorRegistrar(const std::string& class_name) {
|
|
1047
|
+
LocalFactory::register_constructor<Klass, Args...>(class_name);
|
|
1048
|
+
}
|
|
1049
|
+
};
|
|
1050
|
+
|
|
1051
|
+
template <class Klass, typename... Args>
|
|
1052
|
+
struct RegisterCtor {
|
|
1053
|
+
static const CtorRegistrar<Klass, Args...> registerAs;
|
|
1054
|
+
};
|
|
1055
|
+
|
|
1056
|
+
template <class Klass, typename... Args>
|
|
1057
|
+
struct CtorXRegistrar {
|
|
1058
|
+
CtorXRegistrar(const std::string& class_name,
|
|
1059
|
+
const std::string& ctor_description,
|
|
1060
|
+
const ret<std::string>& ret,
|
|
1061
|
+
const std::vector<param> params = {}) {
|
|
1062
|
+
LocalFactory::register_constructor<Klass, Args...>(class_name);
|
|
1063
|
+
const std::string ctor_name("__createShared__" +
|
|
1064
|
+
vrpc::get_signature<std::string, Args...>());
|
|
1065
|
+
json jp;
|
|
1066
|
+
for (const auto& param : params) {
|
|
1067
|
+
jp.push_back(param.j);
|
|
1068
|
+
}
|
|
1069
|
+
LocalFactory::register_meta_data(class_name, ctor_name, ctor_description,
|
|
1070
|
+
jp, ret.j);
|
|
1071
|
+
}
|
|
1072
|
+
};
|
|
1073
|
+
|
|
1074
|
+
template <class Klass, typename... Args>
|
|
1075
|
+
struct RegisterCtorX {
|
|
1076
|
+
static const CtorXRegistrar<Klass, Args...> registerAs;
|
|
1077
|
+
};
|
|
1078
|
+
|
|
1079
|
+
template <class Klass, typename Func, Func f, typename Ret, typename... Args>
|
|
1080
|
+
struct MemberFunctionRegistrar {
|
|
1081
|
+
MemberFunctionRegistrar(const std::string& class_name,
|
|
1082
|
+
const std::string& function_name) {
|
|
1083
|
+
const std::string full_function_name(function_name +
|
|
1084
|
+
vrpc::get_signature<Args...>());
|
|
1085
|
+
LocalFactory::register_member_function<Klass, Func, f, Ret, Args...>(
|
|
1086
|
+
class_name, full_function_name);
|
|
1087
|
+
}
|
|
1088
|
+
};
|
|
1089
|
+
|
|
1090
|
+
template <class Klass, typename Func, Func f, typename Ret, typename... Args>
|
|
1091
|
+
struct MemberFunctionXRegistrar {
|
|
1092
|
+
MemberFunctionXRegistrar(const std::string& class_name,
|
|
1093
|
+
const std::string& function_name,
|
|
1094
|
+
const std::string& function_description,
|
|
1095
|
+
const ret<Ret>& ret,
|
|
1096
|
+
const std::vector<param> params = {}) {
|
|
1097
|
+
const std::string full_function_name(function_name +
|
|
1098
|
+
vrpc::get_signature<Args...>());
|
|
1099
|
+
LocalFactory::register_member_function<Klass, Func, f, Ret, Args...>(
|
|
1100
|
+
class_name, full_function_name);
|
|
1101
|
+
json jp;
|
|
1102
|
+
for (const auto& param : params) {
|
|
1103
|
+
jp.push_back(param.j);
|
|
1104
|
+
}
|
|
1105
|
+
LocalFactory::register_meta_data(class_name, full_function_name,
|
|
1106
|
+
function_description, jp, ret.j);
|
|
1107
|
+
}
|
|
1108
|
+
};
|
|
1109
|
+
|
|
1110
|
+
template <class Klass, typename Func, Func f, typename Ret, typename... Args>
|
|
1111
|
+
struct RegisterMemberFunction {
|
|
1112
|
+
static const MemberFunctionRegistrar<Klass, Func, f, Ret, Args...> registerAs;
|
|
1113
|
+
};
|
|
1114
|
+
|
|
1115
|
+
template <class Klass, typename Func, Func f, typename Ret, typename... Args>
|
|
1116
|
+
struct RegisterMemberFunctionX {
|
|
1117
|
+
static const MemberFunctionXRegistrar<Klass, Func, f, Ret, Args...>
|
|
1118
|
+
registerAs;
|
|
1119
|
+
};
|
|
1120
|
+
|
|
1121
|
+
template <typename Func, Func f, typename Ret, typename... Args>
|
|
1122
|
+
struct StaticFunctionRegistrar {
|
|
1123
|
+
StaticFunctionRegistrar(const std::string& class_name,
|
|
1124
|
+
const std::string& function_name) {
|
|
1125
|
+
const std::string full_function_name(function_name +
|
|
1126
|
+
vrpc::get_signature<Args...>());
|
|
1127
|
+
LocalFactory::register_static_function<Func, f, Ret, Args...>(
|
|
1128
|
+
class_name, full_function_name);
|
|
1129
|
+
}
|
|
1130
|
+
};
|
|
1131
|
+
|
|
1132
|
+
template <typename Func, Func f, typename Ret, typename... Args>
|
|
1133
|
+
struct RegisterStaticFunction {
|
|
1134
|
+
static const StaticFunctionRegistrar<Func, f, Ret, Args...> registerAs;
|
|
1135
|
+
};
|
|
1136
|
+
|
|
1137
|
+
template <typename Func, Func f, typename Ret, typename... Args>
|
|
1138
|
+
struct StaticFunctionXRegistrar {
|
|
1139
|
+
StaticFunctionXRegistrar(const std::string& class_name,
|
|
1140
|
+
const std::string& function_name,
|
|
1141
|
+
const std::string& function_description,
|
|
1142
|
+
const ret<Ret>& ret,
|
|
1143
|
+
const std::vector<param> params = {}) {
|
|
1144
|
+
const std::string full_function_name(function_name +
|
|
1145
|
+
vrpc::get_signature<Args...>());
|
|
1146
|
+
LocalFactory::register_static_function<Func, f, Ret, Args...>(
|
|
1147
|
+
class_name, full_function_name);
|
|
1148
|
+
json jp;
|
|
1149
|
+
for (const auto& param : params) {
|
|
1150
|
+
jp.push_back(param.j);
|
|
1151
|
+
}
|
|
1152
|
+
LocalFactory::register_meta_data(class_name, full_function_name,
|
|
1153
|
+
function_description, jp, ret.j);
|
|
1154
|
+
}
|
|
1155
|
+
};
|
|
1269
1156
|
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1157
|
+
template <typename Func, Func f, typename Ret, typename... Args>
|
|
1158
|
+
struct RegisterStaticFunctionX {
|
|
1159
|
+
static const StaticFunctionXRegistrar<Func, f, Ret, Args...> registerAs;
|
|
1160
|
+
};
|
|
1161
|
+
} // namespace detail
|
|
1275
1162
|
|
|
1276
|
-
|
|
1163
|
+
// ####################### Macro utility #######################
|
|
1277
1164
|
|
|
1278
1165
|
#define CAT(A, B) A##B
|
|
1279
1166
|
#define SELECT(NAME, NUM) CAT(_##NAME##_, NUM)
|
|
@@ -1298,7 +1185,7 @@ namespace vrpc {
|
|
|
1298
1185
|
#define VRPC_STATIC_FUNCTION_X(...) \
|
|
1299
1186
|
VA_SELECT(VRPC_STATIC_FUNCTION_X, __VA_ARGS__)
|
|
1300
1187
|
|
|
1301
|
-
|
|
1188
|
+
// deprecate
|
|
1302
1189
|
#define VRPC_MEMBER_FUNCTION_CONST(...) \
|
|
1303
1190
|
VA_SELECT(VRPC_CONST_MEMBER_FUNCTION, __VA_ARGS__)
|
|
1304
1191
|
#define VRPC_VOID_MEMBER_FUNCTION(...) \
|
|
@@ -1308,17 +1195,18 @@ namespace vrpc {
|
|
|
1308
1195
|
#define VRPC_VOID_STATIC_FUNCTION(...) \
|
|
1309
1196
|
VA_SELECT(VRPC_VOID_STATIC_FUNCTION, __VA_ARGS__)
|
|
1310
1197
|
|
|
1311
|
-
|
|
1198
|
+
// ####################### Callbacks #######################
|
|
1312
1199
|
|
|
1313
|
-
#define VRPC_CALLBACK(
|
|
1200
|
+
#define VRPC_CALLBACK(...) const std::function<void(__VA_ARGS__)>&
|
|
1314
1201
|
|
|
1315
|
-
|
|
1202
|
+
// ####################### Constructors #######################
|
|
1316
1203
|
|
|
1317
1204
|
#define _VRPC_CTOR_RET_DESC "returns the id of the created instance"
|
|
1318
1205
|
|
|
1319
|
-
#define _VRPC_CTOR_VA_ARGS(Klass, ...)
|
|
1320
|
-
|
|
1321
|
-
|
|
1206
|
+
#define _VRPC_CTOR_VA_ARGS(Klass, ...) \
|
|
1207
|
+
template <> \
|
|
1208
|
+
const vrpc::detail::CtorRegistrar<Klass, __VA_ARGS__> \
|
|
1209
|
+
vrpc::detail::RegisterCtor<Klass, __VA_ARGS__>::registerAs(#Klass);
|
|
1322
1210
|
|
|
1323
1211
|
#define _VRPC_CTOR_1(Klass) \
|
|
1324
1212
|
template <> \
|
|
@@ -1408,13 +1296,13 @@ namespace vrpc {
|
|
|
1408
1296
|
{A5Name, A5Default, A5Desc}, \
|
|
1409
1297
|
{A6Name, A6Default, A6Desc}});
|
|
1410
1298
|
|
|
1411
|
-
|
|
1299
|
+
// deprecate
|
|
1412
1300
|
#define VRPC_VOID_CTOR(Klass) \
|
|
1413
1301
|
template <> \
|
|
1414
1302
|
const vrpc::detail::CtorRegistrar<Klass> \
|
|
1415
1303
|
vrpc::detail::RegisterCtor<Klass>::registerAs(#Klass);
|
|
1416
1304
|
|
|
1417
|
-
|
|
1305
|
+
// ####################### Zero arguments #######################
|
|
1418
1306
|
|
|
1419
1307
|
#define _VRPC_MEMBER_FUNCTION_3(Klass, Ret, Function) \
|
|
1420
1308
|
template <> \
|
|
@@ -1484,7 +1372,7 @@ namespace vrpc {
|
|
|
1484
1372
|
#define _VRPC_VOID_STATIC_FUNCTION_2(Klass, Function) \
|
|
1485
1373
|
_VRPC_STATIC_FUNCTION_3(Klass, void, Function)
|
|
1486
1374
|
|
|
1487
|
-
|
|
1375
|
+
// ####################### One argument #######################
|
|
1488
1376
|
|
|
1489
1377
|
#define _VRPC_MEMBER_FUNCTION_4(Klass, Ret, Function, A1) \
|
|
1490
1378
|
template <> \
|
|
@@ -1566,7 +1454,7 @@ namespace vrpc {
|
|
|
1566
1454
|
#define _VRPC_VOID_STATIC_FUNCTION_3(Klass, Function, A1) \
|
|
1567
1455
|
_VRPC_STATIC_FUNCTION_4(Klass, void, Function, A1)
|
|
1568
1456
|
|
|
1569
|
-
|
|
1457
|
+
// ####################### Two arguments #######################
|
|
1570
1458
|
|
|
1571
1459
|
#define _VRPC_MEMBER_FUNCTION_5(Klass, Ret, Function, A1, A2) \
|
|
1572
1460
|
template <> \
|
|
@@ -1586,8 +1474,8 @@ namespace vrpc {
|
|
|
1586
1474
|
&Klass::Function, Ret, A1, A2> \
|
|
1587
1475
|
vrpc::detail::RegisterMemberFunction< \
|
|
1588
1476
|
Klass, \
|
|
1589
|
-
decltype(
|
|
1590
|
-
|
|
1477
|
+
decltype(static_cast<Ret (Klass::*)(A1, A2) const>( \
|
|
1478
|
+
&Klass::Function)), \
|
|
1591
1479
|
&Klass::Function, Ret, A1, A2>::registerAs(#Klass, #Function);
|
|
1592
1480
|
|
|
1593
1481
|
#define _VRPC_STATIC_FUNCTION_5(Klass, Ret, Function, A1, A2) \
|
|
@@ -1626,8 +1514,8 @@ namespace vrpc {
|
|
|
1626
1514
|
&Klass::Function, Ret, A1, A2> \
|
|
1627
1515
|
vrpc::detail::RegisterMemberFunctionX< \
|
|
1628
1516
|
Klass, \
|
|
1629
|
-
decltype(
|
|
1630
|
-
|
|
1517
|
+
decltype(static_cast<Ret (Klass::*)(A1, A2) const>( \
|
|
1518
|
+
&Klass::Function)), \
|
|
1631
1519
|
&Klass::Function, Ret, A1, A2>::registerAs(#Klass, #Function, \
|
|
1632
1520
|
FunctionDesc, {RetDesc}, \
|
|
1633
1521
|
{{A1Name, A1Default, \
|
|
@@ -1660,7 +1548,7 @@ namespace vrpc {
|
|
|
1660
1548
|
#define _VRPC_VOID_STATIC_FUNCTION_4(Klass, Function, A1, A2) \
|
|
1661
1549
|
_VRPC_STATIC_FUNCTION_5(Klass, void, Function, A1, A2)
|
|
1662
1550
|
|
|
1663
|
-
|
|
1551
|
+
// ####################### Three arguments #######################
|
|
1664
1552
|
|
|
1665
1553
|
#define _VRPC_MEMBER_FUNCTION_6(Klass, Ret, Function, A1, A2, A3) \
|
|
1666
1554
|
template <> \
|
|
@@ -1673,17 +1561,17 @@ namespace vrpc {
|
|
|
1673
1561
|
decltype(static_cast<Ret (Klass::*)(A1, A2, A3)>(&Klass::Function)), \
|
|
1674
1562
|
&Klass::Function, Ret, A1, A2, A3>::registerAs(#Klass, #Function);
|
|
1675
1563
|
|
|
1676
|
-
#define _VRPC_CONST_MEMBER_FUNCTION_6(Klass, Ret, Function, A1, A2, A3)
|
|
1677
|
-
template <>
|
|
1678
|
-
const vrpc::detail::MemberFunctionRegistrar<
|
|
1679
|
-
Klass,
|
|
1680
|
-
decltype(
|
|
1681
|
-
|
|
1682
|
-
&Klass::Function, Ret, A1, A2, A3>
|
|
1683
|
-
vrpc::detail::RegisterMemberFunction<
|
|
1684
|
-
Klass,
|
|
1685
|
-
decltype(static_cast<Ret (Klass::*)(A1, A2, A3) const>(
|
|
1686
|
-
&Klass::Function)),
|
|
1564
|
+
#define _VRPC_CONST_MEMBER_FUNCTION_6(Klass, Ret, Function, A1, A2, A3) \
|
|
1565
|
+
template <> \
|
|
1566
|
+
const vrpc::detail::MemberFunctionRegistrar< \
|
|
1567
|
+
Klass, \
|
|
1568
|
+
decltype(static_cast<Ret (Klass::*)(A1, A2, A3) const>( \
|
|
1569
|
+
&Klass::Function)), \
|
|
1570
|
+
&Klass::Function, Ret, A1, A2, A3> \
|
|
1571
|
+
vrpc::detail::RegisterMemberFunction< \
|
|
1572
|
+
Klass, \
|
|
1573
|
+
decltype(static_cast<Ret (Klass::*)(A1, A2, A3) const>( \
|
|
1574
|
+
&Klass::Function)), \
|
|
1687
1575
|
&Klass::Function, Ret, A1, A2, A3>::registerAs(#Klass, #Function);
|
|
1688
1576
|
|
|
1689
1577
|
#define _VRPC_STATIC_FUNCTION_6(Klass, Ret, Function, A1, A2, A3) \
|
|
@@ -1712,23 +1600,23 @@ namespace vrpc {
|
|
|
1712
1600
|
{A2Name, A2Default, A2Desc}, \
|
|
1713
1601
|
{A3Name, A3Default, A3Desc}});
|
|
1714
1602
|
|
|
1715
|
-
#define _VRPC_CONST_MEMBER_FUNCTION_X_17(
|
|
1716
|
-
Klass, Ret, RetDesc, Function, FunctionDesc, A1, A1Name, A1Default,
|
|
1717
|
-
A1Desc, A2, A2Name, A2Default, A2Desc, A3, A3Name, A3Default, A3Desc)
|
|
1718
|
-
template <>
|
|
1719
|
-
const vrpc::detail::MemberFunctionXRegistrar<
|
|
1720
|
-
Klass,
|
|
1721
|
-
decltype(
|
|
1722
|
-
|
|
1723
|
-
&Klass::Function, Ret, A1, A2, A3>
|
|
1724
|
-
vrpc::detail::RegisterMemberFunctionX<
|
|
1725
|
-
Klass,
|
|
1726
|
-
decltype(static_cast<Ret (Klass::*)(A1, A2, A3) const>(
|
|
1727
|
-
&Klass::Function)),
|
|
1728
|
-
&Klass::Function, Ret, A1, A2,
|
|
1729
|
-
A3>::registerAs(#Klass, #Function, FunctionDesc, {RetDesc},
|
|
1730
|
-
{{A1Name, A1Default, A1Desc},
|
|
1731
|
-
{A2Name, A2Default, A2Desc},
|
|
1603
|
+
#define _VRPC_CONST_MEMBER_FUNCTION_X_17( \
|
|
1604
|
+
Klass, Ret, RetDesc, Function, FunctionDesc, A1, A1Name, A1Default, \
|
|
1605
|
+
A1Desc, A2, A2Name, A2Default, A2Desc, A3, A3Name, A3Default, A3Desc) \
|
|
1606
|
+
template <> \
|
|
1607
|
+
const vrpc::detail::MemberFunctionXRegistrar< \
|
|
1608
|
+
Klass, \
|
|
1609
|
+
decltype(static_cast<Ret (Klass::*)(A1, A2, A3) const>( \
|
|
1610
|
+
&Klass::Function)), \
|
|
1611
|
+
&Klass::Function, Ret, A1, A2, A3> \
|
|
1612
|
+
vrpc::detail::RegisterMemberFunctionX< \
|
|
1613
|
+
Klass, \
|
|
1614
|
+
decltype(static_cast<Ret (Klass::*)(A1, A2, A3) const>( \
|
|
1615
|
+
&Klass::Function)), \
|
|
1616
|
+
&Klass::Function, Ret, A1, A2, \
|
|
1617
|
+
A3>::registerAs(#Klass, #Function, FunctionDesc, {RetDesc}, \
|
|
1618
|
+
{{A1Name, A1Default, A1Desc}, \
|
|
1619
|
+
{A2Name, A2Default, A2Desc}, \
|
|
1732
1620
|
{A3Name, A3Default, A3Desc}});
|
|
1733
1621
|
|
|
1734
1622
|
#define _VRPC_STATIC_FUNCTION_X_17( \
|
|
@@ -1755,7 +1643,7 @@ namespace vrpc {
|
|
|
1755
1643
|
#define _VRPC_VOID_STATIC_FUNCTION_5(Klass, Function, A1, A2, A3) \
|
|
1756
1644
|
_VRPC_STATIC_FUNCTION_6(Klass, void, Function, A1, A2, A3)
|
|
1757
1645
|
|
|
1758
|
-
|
|
1646
|
+
// ####################### Four arguments #######################
|
|
1759
1647
|
|
|
1760
1648
|
#define _VRPC_MEMBER_FUNCTION_7(Klass, Ret, Function, A1, A2, A3, A4) \
|
|
1761
1649
|
template <> \
|
|
@@ -1765,8 +1653,8 @@ namespace vrpc {
|
|
|
1765
1653
|
&Klass::Function, Ret, A1, A2, A3, A4> \
|
|
1766
1654
|
vrpc::detail::RegisterMemberFunction< \
|
|
1767
1655
|
Klass, \
|
|
1768
|
-
decltype(
|
|
1769
|
-
|
|
1656
|
+
decltype(static_cast<Ret (Klass::*)(A1, A2, A3, A4)>( \
|
|
1657
|
+
&Klass::Function)), \
|
|
1770
1658
|
&Klass::Function, Ret, A1, A2, A3, A4>::registerAs(#Klass, \
|
|
1771
1659
|
#Function);
|
|
1772
1660
|
|
|
@@ -1805,8 +1693,8 @@ namespace vrpc {
|
|
|
1805
1693
|
&Klass::Function, Ret, A1, A2, A3, A4> \
|
|
1806
1694
|
vrpc::detail::RegisterMemberFunctionX< \
|
|
1807
1695
|
Klass, \
|
|
1808
|
-
decltype(
|
|
1809
|
-
|
|
1696
|
+
decltype(static_cast<Ret (Klass::*)(A1, A2, A3, A4)>( \
|
|
1697
|
+
&Klass::Function)), \
|
|
1810
1698
|
&Klass::Function, Ret, A1, A2, A3, \
|
|
1811
1699
|
A4>::registerAs(#Klass, #Function, FunctionDesc, {RetDesc}, \
|
|
1812
1700
|
{{A1Name, A1Default, A1Desc}, \
|
|
@@ -1861,20 +1749,20 @@ namespace vrpc {
|
|
|
1861
1749
|
#define _VRPC_VOID_STATIC_FUNCTION_6(Klass, Function, A1, A2, A3, A4) \
|
|
1862
1750
|
_VRPC_STATIC_FUNCTION_7(Klass, void, Function, A1, A2, A3, A4)
|
|
1863
1751
|
|
|
1864
|
-
|
|
1752
|
+
// ####################### Five arguments #######################
|
|
1865
1753
|
|
|
1866
|
-
#define _VRPC_MEMBER_FUNCTION_8(Klass, Ret, Function, A1, A2, A3, A4, A5)
|
|
1867
|
-
template <>
|
|
1868
|
-
const vrpc::detail::MemberFunctionRegistrar<
|
|
1869
|
-
Klass,
|
|
1870
|
-
decltype(
|
|
1871
|
-
|
|
1872
|
-
&Klass::Function, Ret, A1, A2, A3, A4, A5>
|
|
1873
|
-
vrpc::detail::RegisterMemberFunction<
|
|
1874
|
-
Klass,
|
|
1875
|
-
decltype(static_cast<Ret (Klass::*)(A1, A2, A3, A4, A5)>(
|
|
1876
|
-
&Klass::Function)),
|
|
1877
|
-
&Klass::Function, Ret, A1, A2, A3, A4, A5>::registerAs(#Klass,
|
|
1754
|
+
#define _VRPC_MEMBER_FUNCTION_8(Klass, Ret, Function, A1, A2, A3, A4, A5) \
|
|
1755
|
+
template <> \
|
|
1756
|
+
const vrpc::detail::MemberFunctionRegistrar< \
|
|
1757
|
+
Klass, \
|
|
1758
|
+
decltype(static_cast<Ret (Klass::*)(A1, A2, A3, A4, A5)>( \
|
|
1759
|
+
&Klass::Function)), \
|
|
1760
|
+
&Klass::Function, Ret, A1, A2, A3, A4, A5> \
|
|
1761
|
+
vrpc::detail::RegisterMemberFunction< \
|
|
1762
|
+
Klass, \
|
|
1763
|
+
decltype(static_cast<Ret (Klass::*)(A1, A2, A3, A4, A5)>( \
|
|
1764
|
+
&Klass::Function)), \
|
|
1765
|
+
&Klass::Function, Ret, A1, A2, A3, A4, A5>::registerAs(#Klass, \
|
|
1878
1766
|
#Function);
|
|
1879
1767
|
|
|
1880
1768
|
#define _VRPC_CONST_MEMBER_FUNCTION_8(Klass, Ret, Function, A1, A2, A3, A4, \
|
|
@@ -1909,8 +1797,8 @@ namespace vrpc {
|
|
|
1909
1797
|
template <> \
|
|
1910
1798
|
const vrpc::detail::MemberFunctionXRegistrar< \
|
|
1911
1799
|
Klass, \
|
|
1912
|
-
decltype(
|
|
1913
|
-
|
|
1800
|
+
decltype(static_cast<Ret (Klass::*)(A1, A2, A3, A4, A5)>( \
|
|
1801
|
+
&Klass::Function)), \
|
|
1914
1802
|
&Klass::Function, Ret, A1, A2, A3, A4, A5> \
|
|
1915
1803
|
vrpc::detail::RegisterMemberFunctionX< \
|
|
1916
1804
|
Klass, \
|
|
@@ -1974,7 +1862,7 @@ namespace vrpc {
|
|
|
1974
1862
|
#define _VRPC_VOID_STATIC_FUNCTION_7(Klass, Function, A1, A2, A3, A4, A5) \
|
|
1975
1863
|
_VRPC_STATIC_FUNCTION_8(Klass, void, Function, A1, A2, A3, A4, A5)
|
|
1976
1864
|
|
|
1977
|
-
|
|
1865
|
+
// ####################### Six arguments #######################
|
|
1978
1866
|
|
|
1979
1867
|
#define _VRPC_MEMBER_FUNCTION_9(Klass, Ret, Function, A1, A2, A3, A4, A5, A6) \
|
|
1980
1868
|
template <> \
|
|
@@ -2011,8 +1899,8 @@ namespace vrpc {
|
|
|
2011
1899
|
decltype(static_cast<Ret (*)(A1, A2, A3, A4, A5, A6)>(Klass::Function)), \
|
|
2012
1900
|
&Klass::Function, Ret, A1, A2, A3, A4, A5, A6> \
|
|
2013
1901
|
vrpc::detail::RegisterStaticFunction< \
|
|
2014
|
-
decltype(
|
|
2015
|
-
|
|
1902
|
+
decltype(static_cast<Ret (*)(A1, A2, A3, A4, A5, A6)>( \
|
|
1903
|
+
Klass::Function)), \
|
|
2016
1904
|
&Klass::Function, Ret, A1, A2, A3, A4, A5, \
|
|
2017
1905
|
A6>::registerAs(#Klass, #Function);
|
|
2018
1906
|
|
|
@@ -2074,8 +1962,8 @@ namespace vrpc {
|
|
|
2074
1962
|
decltype(static_cast<Ret (*)(A1, A2, A3, A4, A5, A6)>(Klass::Function)), \
|
|
2075
1963
|
&Klass::Function, Ret, A1, A2, A3, A4, A5, A6> \
|
|
2076
1964
|
vrpc::detail::RegisterStaticFunctionX< \
|
|
2077
|
-
decltype(
|
|
2078
|
-
|
|
1965
|
+
decltype(static_cast<Ret (*)(A1, A2, A3, A4, A5, A6)>( \
|
|
1966
|
+
Klass::Function)), \
|
|
2079
1967
|
&Klass::Function, Ret, A1, A2, A3, A4, A5, \
|
|
2080
1968
|
A6>::registerAs(#Klass, #Function, FunctionDesc, {RetDesc}, \
|
|
2081
1969
|
{{A1Name, A1Default, A1Desc}, \
|
|
@@ -2095,6 +1983,6 @@ namespace vrpc {
|
|
|
2095
1983
|
#define _VRPC_VOID_STATIC_FUNCTION_8(Klass, Function, A1, A2, A3, A4, A5, A6) \
|
|
2096
1984
|
_VRPC_STATIC_FUNCTION_9(Klass, void, Function, A1, A2, A3, A4, A5, A6)
|
|
2097
1985
|
|
|
2098
|
-
}
|
|
1986
|
+
} // namespace vrpc
|
|
2099
1987
|
|
|
2100
1988
|
#endif
|