vrpc 2.5.0 → 3.0.0-alpha.2
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 +66 -0
- package/README.md +33 -56
- package/binding.gyp.no-auto +4 -26
- package/browser/vrpc.js +1 -1
- package/index.js +2 -2
- package/package.json +13 -17
- package/vrpc/VrpcAdapter.js +275 -233
- package/vrpc/VrpcAgent.js +204 -185
- package/vrpc/{VrpcRemote.js → VrpcClient.js} +295 -288
- package/vrpc/VrpcNative.js +307 -0
- package/vrpc/{vrpc.hpp → adapter.hpp} +1001 -1115
- package/vrpc/addon.cpp +5 -5
- 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 -264
- package/vrpc/VrpcLocal.py +0 -171
- package/vrpc/__init__.py +0 -1
- package/vrpc/module.cpp +0 -183
|
@@ -16,7 +16,8 @@ Author: Dr. Burkhard C. Heisen (https://github.com/bheisen/vrpc)
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
|
19
|
-
Copyright (c) 2018 - 2021 Dr. Burkhard C. Heisen
|
|
19
|
+
Copyright (c) 2018 - 2021 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,1127 @@ 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
|
+
signature += j["t"].type_name();
|
|
377
|
+
return get_signature<I + 1, Args...>(signature, t);
|
|
378
|
+
}
|
|
379
|
+
} // namespace detail
|
|
380
|
+
|
|
381
|
+
template <typename... Args>
|
|
382
|
+
inline std::string get_signature() {
|
|
383
|
+
std::string signature;
|
|
384
|
+
detail::get_signature(
|
|
385
|
+
signature, std::tuple<typename std::remove_reference<Args>::type...>());
|
|
386
|
+
return signature.empty() ? signature : "-" + signature;
|
|
387
|
+
}
|
|
542
388
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
389
|
+
inline std::string get_signature(const json& json) {
|
|
390
|
+
std::string signature;
|
|
391
|
+
for (const auto& it : json) {
|
|
392
|
+
signature += it.type_name();
|
|
393
|
+
}
|
|
394
|
+
return signature.empty() ? signature : "-" + signature;
|
|
395
|
+
}
|
|
546
396
|
|
|
547
|
-
|
|
548
|
-
static std::type_index void_type(typeid (void));
|
|
549
|
-
return content ? content->type() : void_type;
|
|
550
|
-
}
|
|
397
|
+
namespace detail {
|
|
551
398
|
|
|
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
|
-
}
|
|
399
|
+
template <typename T>
|
|
400
|
+
struct is_shared_ptr : std::false_type {};
|
|
558
401
|
|
|
559
|
-
|
|
402
|
+
template <typename T>
|
|
403
|
+
struct is_shared_ptr<std::shared_ptr<T>> : std::true_type {};
|
|
404
|
+
} // namespace detail
|
|
560
405
|
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
> (content)->held;
|
|
566
|
-
}
|
|
406
|
+
// Value class
|
|
407
|
+
class Value {
|
|
408
|
+
public:
|
|
409
|
+
Value() noexcept : content(0) {}
|
|
567
410
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
}
|
|
411
|
+
template <typename T>
|
|
412
|
+
Value(const T& value)
|
|
413
|
+
: content(new holder<
|
|
414
|
+
typename std::remove_cv<typename std::decay<T>::type>::type>(
|
|
415
|
+
value)) {}
|
|
574
416
|
|
|
575
|
-
|
|
417
|
+
Value(const char* const& value) : Value(std::string(value)) {}
|
|
576
418
|
|
|
577
|
-
|
|
578
|
-
|
|
419
|
+
/// Copy constructor
|
|
420
|
+
Value(const Value& other)
|
|
421
|
+
: content(other.content ? other.content->clone() : 0) {}
|
|
579
422
|
|
|
580
|
-
|
|
423
|
+
/// Move constructor
|
|
424
|
+
Value(Value&& other) : content(other.content) { other.content = 0; }
|
|
581
425
|
|
|
582
|
-
|
|
426
|
+
template <typename T>
|
|
427
|
+
Value(T&& value,
|
|
428
|
+
typename std::enable_if<!std::is_same<Value&, T>::value>::type* = 0,
|
|
429
|
+
typename std::enable_if<!std::is_const<T>::value>::type* = 0,
|
|
430
|
+
typename std::enable_if<!detail::is_shared_ptr<T>::value>::type* = 0)
|
|
431
|
+
: content(new holder<
|
|
432
|
+
typename std::remove_cv<typename std::decay<T>::type>::type>(
|
|
433
|
+
std::forward<T>(value))) {}
|
|
583
434
|
|
|
584
|
-
|
|
435
|
+
~Value() noexcept { delete content; }
|
|
585
436
|
|
|
586
|
-
|
|
587
|
-
|
|
437
|
+
public: // functions
|
|
438
|
+
Value& swap(Value& rhs) noexcept {
|
|
439
|
+
std::swap(content, rhs.content);
|
|
440
|
+
return *this;
|
|
441
|
+
}
|
|
588
442
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
443
|
+
Value& operator=(const Value& rhs) {
|
|
444
|
+
Value(rhs).swap(*this);
|
|
445
|
+
return *this;
|
|
446
|
+
}
|
|
592
447
|
|
|
593
|
-
|
|
594
|
-
|
|
448
|
+
Value& operator=(Value&& rhs) noexcept {
|
|
449
|
+
rhs.swap(*this);
|
|
450
|
+
Value().swap(rhs);
|
|
451
|
+
return *this;
|
|
452
|
+
}
|
|
595
453
|
|
|
596
|
-
|
|
597
|
-
|
|
454
|
+
template <typename T>
|
|
455
|
+
Value& operator=(T&& rhs) {
|
|
456
|
+
Value(static_cast<T&&>(rhs)).swap(*this);
|
|
457
|
+
return *this;
|
|
458
|
+
}
|
|
598
459
|
|
|
460
|
+
Value& operator=(const char* const& rhs) {
|
|
461
|
+
Value(std::string(rhs)).swap(*this);
|
|
462
|
+
return *this;
|
|
463
|
+
}
|
|
599
464
|
|
|
600
|
-
|
|
465
|
+
// NOTE: Windows compiler is broken here
|
|
466
|
+
// template <typename T>
|
|
467
|
+
// operator const T&() const {
|
|
468
|
+
// return const_cast<Value*> (this)->template get<T>();
|
|
469
|
+
// }
|
|
470
|
+
|
|
471
|
+
// template <typename T>
|
|
472
|
+
// operator T() const {
|
|
473
|
+
// return const_cast<Value*> (this)->template get<T>();
|
|
474
|
+
// }
|
|
475
|
+
|
|
476
|
+
template <typename T>
|
|
477
|
+
T& operator=(T& rhs) {
|
|
478
|
+
Value(rhs).swap(*this);
|
|
479
|
+
return *this;
|
|
480
|
+
}
|
|
601
481
|
|
|
602
|
-
|
|
603
|
-
return std::type_index(typeid (T));
|
|
604
|
-
}
|
|
482
|
+
bool empty() const noexcept { return !content; }
|
|
605
483
|
|
|
606
|
-
|
|
607
|
-
// This copies a std::shared_ptr!
|
|
608
|
-
return new holder(*held);
|
|
609
|
-
}
|
|
484
|
+
void clear() noexcept { Value().swap(*this); }
|
|
610
485
|
|
|
611
|
-
|
|
486
|
+
std::type_index type() const noexcept {
|
|
487
|
+
static std::type_index void_type(typeid(void));
|
|
488
|
+
return content ? content->type() : void_type;
|
|
489
|
+
}
|
|
612
490
|
|
|
613
|
-
|
|
491
|
+
template <typename T>
|
|
492
|
+
inline const T& get() const {
|
|
493
|
+
// TODO Check type correctness here
|
|
494
|
+
// TODO implement by specialization and not by overload
|
|
495
|
+
return _get<T>(typename detail::is_shared_ptr<T>::type());
|
|
496
|
+
}
|
|
614
497
|
|
|
615
|
-
|
|
498
|
+
private: // functions
|
|
499
|
+
template <typename T>
|
|
500
|
+
inline const T& _get(const std::true_type&) const {
|
|
501
|
+
return static_cast<holder<
|
|
502
|
+
typename std::remove_cv<typename T::element_type>::type>*>(content)
|
|
503
|
+
->held;
|
|
504
|
+
}
|
|
616
505
|
|
|
617
|
-
|
|
506
|
+
template <typename T>
|
|
507
|
+
inline const T& _get(const std::false_type&) const {
|
|
508
|
+
return *(
|
|
509
|
+
static_cast<holder<typename std::remove_cv<T>::type>*>(content)->held);
|
|
510
|
+
}
|
|
618
511
|
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
512
|
+
private: // types
|
|
513
|
+
class placeholder {
|
|
514
|
+
public: // structors
|
|
515
|
+
virtual ~placeholder() {}
|
|
622
516
|
|
|
623
|
-
|
|
624
|
-
|
|
517
|
+
public: // queries
|
|
518
|
+
virtual std::type_index type() const noexcept = 0;
|
|
625
519
|
|
|
626
|
-
|
|
520
|
+
virtual placeholder* clone() const = 0;
|
|
521
|
+
};
|
|
627
522
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
523
|
+
template <typename T>
|
|
524
|
+
class holder : public placeholder {
|
|
525
|
+
public: // structors
|
|
526
|
+
holder(const T& value) : held(new T(value)) {}
|
|
631
527
|
|
|
632
|
-
|
|
633
|
-
// This copies a std::shared_ptr!
|
|
634
|
-
return new holder(held);
|
|
635
|
-
}
|
|
528
|
+
holder(T&& value) : held(new T(static_cast<T&&>(value))) {}
|
|
636
529
|
|
|
637
|
-
|
|
530
|
+
public: // queries
|
|
531
|
+
virtual std::type_index type() const noexcept {
|
|
532
|
+
return std::type_index(typeid(T));
|
|
533
|
+
}
|
|
638
534
|
|
|
639
|
-
|
|
535
|
+
virtual placeholder* clone() const {
|
|
536
|
+
// This copies a std::shared_ptr!
|
|
537
|
+
return new holder(*held);
|
|
538
|
+
}
|
|
640
539
|
|
|
641
|
-
|
|
642
|
-
};
|
|
540
|
+
holder& operator=(const holder&) = delete;
|
|
643
541
|
|
|
644
|
-
|
|
542
|
+
public: // representation
|
|
543
|
+
std::shared_ptr<T> held;
|
|
645
544
|
};
|
|
646
545
|
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
class Function {
|
|
652
|
-
public:
|
|
653
|
-
|
|
654
|
-
Function() { }
|
|
546
|
+
template <typename T>
|
|
547
|
+
class holder<std::shared_ptr<T>> : public placeholder {
|
|
548
|
+
public:
|
|
549
|
+
holder(const std::shared_ptr<T>& value) : held(value) {}
|
|
655
550
|
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
void bind_instance(const std::shared_ptr<T>& instance) {
|
|
660
|
-
this->do_bind_instance(Value(instance));
|
|
551
|
+
public: // queries
|
|
552
|
+
virtual std::type_index type() const noexcept {
|
|
553
|
+
return std::type_index(typeid(T));
|
|
661
554
|
}
|
|
662
555
|
|
|
663
|
-
|
|
664
|
-
|
|
556
|
+
virtual placeholder* clone() const {
|
|
557
|
+
// This copies a std::shared_ptr!
|
|
558
|
+
return new holder(held);
|
|
665
559
|
}
|
|
666
560
|
|
|
667
|
-
|
|
668
|
-
return this->do_clone();
|
|
669
|
-
}
|
|
561
|
+
holder& operator=(const holder&) = delete;
|
|
670
562
|
|
|
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;
|
|
563
|
+
public: // representation
|
|
564
|
+
std::shared_ptr<T> held;
|
|
676
565
|
};
|
|
677
566
|
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
Lambda m_lambda;
|
|
681
|
-
std::shared_ptr<Klass> m_ptr;
|
|
682
|
-
|
|
683
|
-
public:
|
|
567
|
+
placeholder* content;
|
|
568
|
+
};
|
|
684
569
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
570
|
+
inline bool operator==(const Value& lhs, const char& rhs) {
|
|
571
|
+
return lhs.get<char>() == rhs;
|
|
572
|
+
}
|
|
688
573
|
|
|
689
|
-
|
|
574
|
+
class Function {
|
|
575
|
+
public:
|
|
576
|
+
Function() {}
|
|
690
577
|
|
|
691
|
-
|
|
692
|
-
auto ptr = std::make_shared<MemberFunction>(m_lambda);
|
|
693
|
-
return std::static_pointer_cast<Function>(ptr);
|
|
694
|
-
}
|
|
578
|
+
virtual ~Function() {}
|
|
695
579
|
|
|
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
|
-
}
|
|
580
|
+
template <typename T>
|
|
581
|
+
void bind_instance(const std::shared_ptr<T>& instance) {
|
|
582
|
+
this->do_bind_instance(Value(instance));
|
|
583
|
+
}
|
|
706
584
|
|
|
707
|
-
|
|
708
|
-
m_ptr = instance.get<std::shared_ptr<Klass> >();
|
|
709
|
-
}
|
|
710
|
-
};
|
|
585
|
+
void call_function(json& json) { this->do_call_function(json); }
|
|
711
586
|
|
|
712
|
-
|
|
713
|
-
class MemberFunction<Klass, Lambda, void, Args...> : public Function {
|
|
714
|
-
Lambda m_lambda;
|
|
715
|
-
std::shared_ptr<Klass> m_ptr;
|
|
587
|
+
std::shared_ptr<Function> clone() { return this->do_clone(); }
|
|
716
588
|
|
|
717
|
-
|
|
589
|
+
protected:
|
|
590
|
+
virtual void do_bind_instance(const Value& instance) = 0;
|
|
591
|
+
virtual void do_call_function(json& json) = 0;
|
|
592
|
+
virtual std::shared_ptr<Function> do_clone() = 0;
|
|
593
|
+
};
|
|
718
594
|
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
595
|
+
template <typename Klass, typename Lambda, typename Ret, typename... Args>
|
|
596
|
+
class MemberFunction : public Function {
|
|
597
|
+
Lambda _lambda;
|
|
598
|
+
std::shared_ptr<Klass> _ptr;
|
|
722
599
|
|
|
723
|
-
|
|
600
|
+
public:
|
|
601
|
+
MemberFunction(const Lambda& lambda) : _lambda(lambda) {}
|
|
724
602
|
|
|
725
|
-
|
|
726
|
-
auto ptr = std::make_shared<MemberFunction>(m_lambda);
|
|
727
|
-
return std::static_pointer_cast<Function>(ptr);
|
|
728
|
-
}
|
|
603
|
+
virtual ~MemberFunction() = default;
|
|
729
604
|
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
} catch (const std::exception& e) {
|
|
735
|
-
json["data"]["e"] = std::string(e.what());
|
|
736
|
-
}
|
|
737
|
-
}
|
|
605
|
+
virtual std::shared_ptr<Function> do_clone() {
|
|
606
|
+
auto ptr = std::make_shared<MemberFunction>(_lambda);
|
|
607
|
+
return std::static_pointer_cast<Function>(ptr);
|
|
608
|
+
}
|
|
738
609
|
|
|
739
|
-
|
|
740
|
-
|
|
610
|
+
virtual void do_call_function(json& json) {
|
|
611
|
+
try {
|
|
612
|
+
json["r"] = vrpc::call(_lambda(_ptr), vrpc::unpack<Args...>(json));
|
|
613
|
+
} catch (const std::exception& e) {
|
|
614
|
+
json["e"] = std::string(e.what());
|
|
741
615
|
}
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
template <typename Lambda, typename Ret, typename ...Args>
|
|
745
|
-
class StaticFunction : public Function {
|
|
746
|
-
Lambda m_lambda;
|
|
616
|
+
}
|
|
747
617
|
|
|
748
|
-
|
|
618
|
+
virtual void do_bind_instance(const Value& instance) {
|
|
619
|
+
_ptr = instance.get<std::shared_ptr<Klass>>();
|
|
620
|
+
}
|
|
621
|
+
};
|
|
749
622
|
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
623
|
+
template <typename Klass, typename Lambda, typename... Args>
|
|
624
|
+
class MemberFunction<Klass, Lambda, void, Args...> : public Function {
|
|
625
|
+
Lambda _lambda;
|
|
626
|
+
std::shared_ptr<Klass> _ptr;
|
|
753
627
|
|
|
754
|
-
|
|
628
|
+
public:
|
|
629
|
+
MemberFunction(const Lambda& lambda) : _lambda(lambda) {}
|
|
755
630
|
|
|
756
|
-
|
|
757
|
-
auto ptr = std::make_shared<StaticFunction>(m_lambda);
|
|
758
|
-
return std::static_pointer_cast<Function>(ptr);
|
|
759
|
-
}
|
|
631
|
+
virtual ~MemberFunction() = default;
|
|
760
632
|
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
json["data"]["e"] = std::string(e.what());
|
|
766
|
-
}
|
|
767
|
-
}
|
|
633
|
+
virtual std::shared_ptr<Function> do_clone() {
|
|
634
|
+
auto ptr = std::make_shared<MemberFunction>(_lambda);
|
|
635
|
+
return std::static_pointer_cast<Function>(ptr);
|
|
636
|
+
}
|
|
768
637
|
|
|
769
|
-
|
|
770
|
-
|
|
638
|
+
virtual void do_call_function(json& json) {
|
|
639
|
+
try {
|
|
640
|
+
vrpc::call(_lambda(_ptr), vrpc::unpack<Args...>(json));
|
|
641
|
+
json["r"] = nullptr;
|
|
642
|
+
} catch (const std::exception& e) {
|
|
643
|
+
json["e"] = std::string(e.what());
|
|
771
644
|
}
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
template <typename Lambda, typename ...Args>
|
|
775
|
-
class StaticFunction<Lambda, void, Args...> : public Function {
|
|
776
|
-
Lambda m_lambda;
|
|
645
|
+
}
|
|
777
646
|
|
|
778
|
-
|
|
647
|
+
virtual void do_bind_instance(const Value& instance) {
|
|
648
|
+
_ptr = instance.get<std::shared_ptr<Klass>>();
|
|
649
|
+
}
|
|
650
|
+
};
|
|
779
651
|
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
652
|
+
template <typename Lambda, typename Ret, typename... Args>
|
|
653
|
+
class StaticFunction : public Function {
|
|
654
|
+
Lambda _lambda;
|
|
783
655
|
|
|
784
|
-
|
|
656
|
+
public:
|
|
657
|
+
StaticFunction(const Lambda& lambda) : _lambda(lambda) {}
|
|
785
658
|
|
|
786
|
-
|
|
787
|
-
auto ptr = std::make_shared<StaticFunction>(m_lambda);
|
|
788
|
-
return std::static_pointer_cast<Function>(ptr);
|
|
789
|
-
}
|
|
659
|
+
virtual ~StaticFunction() = default;
|
|
790
660
|
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
} catch (const std::exception& e) {
|
|
796
|
-
json["data"]["e"] = std::string(e.what());
|
|
797
|
-
}
|
|
798
|
-
}
|
|
661
|
+
virtual std::shared_ptr<Function> do_clone() {
|
|
662
|
+
auto ptr = std::make_shared<StaticFunction>(_lambda);
|
|
663
|
+
return std::static_pointer_cast<Function>(ptr);
|
|
664
|
+
}
|
|
799
665
|
|
|
800
|
-
|
|
801
|
-
|
|
666
|
+
virtual void do_call_function(json& json) {
|
|
667
|
+
try {
|
|
668
|
+
json["r"] = vrpc::call(_lambda(), vrpc::unpack<Args...>(json));
|
|
669
|
+
} catch (const std::exception& e) {
|
|
670
|
+
json["e"] = std::string(e.what());
|
|
802
671
|
}
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
template <typename Lambda, typename ...Args>
|
|
806
|
-
class ConstructorFunction : public Function {
|
|
807
|
-
Lambda m_lambda;
|
|
672
|
+
}
|
|
808
673
|
|
|
809
|
-
|
|
674
|
+
virtual void do_bind_instance(const Value&) {
|
|
675
|
+
// Nothing to bind, static function
|
|
676
|
+
}
|
|
677
|
+
};
|
|
810
678
|
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
679
|
+
template <typename Lambda, typename... Args>
|
|
680
|
+
class StaticFunction<Lambda, void, Args...> : public Function {
|
|
681
|
+
Lambda _lambda;
|
|
814
682
|
|
|
815
|
-
|
|
683
|
+
public:
|
|
684
|
+
StaticFunction(const Lambda& lambda) : _lambda(lambda) {}
|
|
816
685
|
|
|
817
|
-
|
|
818
|
-
auto ptr = std::make_shared<ConstructorFunction>(m_lambda);
|
|
819
|
-
return std::static_pointer_cast<Function>(ptr);
|
|
820
|
-
}
|
|
686
|
+
virtual ~StaticFunction() = default;
|
|
821
687
|
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
json["data"]["e"] = std::string(e.what());
|
|
827
|
-
}
|
|
828
|
-
}
|
|
688
|
+
virtual std::shared_ptr<Function> do_clone() {
|
|
689
|
+
auto ptr = std::make_shared<StaticFunction>(_lambda);
|
|
690
|
+
return std::static_pointer_cast<Function>(ptr);
|
|
691
|
+
}
|
|
829
692
|
|
|
830
|
-
|
|
831
|
-
|
|
693
|
+
virtual void do_call_function(json& json) {
|
|
694
|
+
try {
|
|
695
|
+
vrpc::call(_lambda(), vrpc::unpack<Args...>(json));
|
|
696
|
+
json["r"] = nullptr;
|
|
697
|
+
} catch (const std::exception& e) {
|
|
698
|
+
json["e"] = std::string(e.what());
|
|
832
699
|
}
|
|
833
|
-
}
|
|
700
|
+
}
|
|
834
701
|
|
|
835
|
-
|
|
702
|
+
virtual void do_bind_instance(const Value&) {
|
|
703
|
+
// Nothing to bind, static function
|
|
704
|
+
}
|
|
705
|
+
};
|
|
836
706
|
|
|
707
|
+
template <typename Lambda, typename... Args>
|
|
708
|
+
class ConstructorFunction : public Function {
|
|
709
|
+
Lambda _lambda;
|
|
837
710
|
|
|
711
|
+
public:
|
|
712
|
+
ConstructorFunction(const Lambda& lambda) : _lambda(lambda) {}
|
|
838
713
|
|
|
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
|
-
};
|
|
714
|
+
virtual ~ConstructorFunction() = default;
|
|
864
715
|
|
|
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
|
-
};
|
|
716
|
+
virtual std::shared_ptr<Function> do_clone() {
|
|
717
|
+
auto ptr = std::make_shared<ConstructorFunction>(_lambda);
|
|
718
|
+
return std::static_pointer_cast<Function>(ptr);
|
|
881
719
|
}
|
|
882
720
|
|
|
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);
|
|
721
|
+
virtual void do_call_function(json& json) {
|
|
722
|
+
try {
|
|
723
|
+
json["r"] = vrpc::call(_lambda, vrpc::unpack<Args...>(json));
|
|
724
|
+
} catch (const std::exception& e) {
|
|
725
|
+
json["e"] = std::string(e.what());
|
|
913
726
|
}
|
|
727
|
+
}
|
|
914
728
|
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
729
|
+
virtual void do_bind_instance(const Value&) {
|
|
730
|
+
// Nothing to bind
|
|
731
|
+
}
|
|
732
|
+
};
|
|
733
|
+
|
|
734
|
+
struct required {};
|
|
735
|
+
|
|
736
|
+
namespace detail {
|
|
737
|
+
struct param {
|
|
738
|
+
json j;
|
|
739
|
+
template <typename DefaultType>
|
|
740
|
+
param(const std::string& name,
|
|
741
|
+
const DefaultType& default_value,
|
|
742
|
+
const std::string& description) {
|
|
743
|
+
// json tmp{{"t", type()}};
|
|
744
|
+
// j["type"] = tmp["t"].type_name();
|
|
745
|
+
j["name"] = name;
|
|
746
|
+
j["optional"] = true;
|
|
747
|
+
j["default"] = default_value;
|
|
748
|
+
j["description"] = description;
|
|
749
|
+
}
|
|
750
|
+
param(const std::string& name,
|
|
751
|
+
const required& default_value,
|
|
752
|
+
const std::string& description) {
|
|
753
|
+
// json tmp{{"t", type()}};
|
|
754
|
+
// j["type"] = tmp["t"].type_name();
|
|
755
|
+
j["name"] = name;
|
|
756
|
+
j["optional"] = false;
|
|
757
|
+
j["default"] = nullptr;
|
|
758
|
+
j["description"] = description;
|
|
759
|
+
}
|
|
760
|
+
};
|
|
761
|
+
|
|
762
|
+
template <typename ValueType>
|
|
763
|
+
struct ret {
|
|
764
|
+
json j;
|
|
765
|
+
ret(const std::string& description) {
|
|
766
|
+
j["type"] = json(ValueType()).type_name();
|
|
767
|
+
j["description"] = description;
|
|
768
|
+
}
|
|
769
|
+
};
|
|
770
|
+
template <>
|
|
771
|
+
struct ret<void> {
|
|
772
|
+
json j;
|
|
773
|
+
ret(const std::string& description) {
|
|
774
|
+
j["type"] = "void";
|
|
775
|
+
j["description"] = description;
|
|
776
|
+
}
|
|
777
|
+
};
|
|
778
|
+
} // namespace detail
|
|
779
|
+
|
|
780
|
+
class LocalFactory {
|
|
781
|
+
friend LocalFactory& detail::init<LocalFactory>();
|
|
782
|
+
friend class Proxy;
|
|
783
|
+
friend class MqttClient;
|
|
784
|
+
|
|
785
|
+
typedef std::unordered_map<std::string, Value> StringAnyMap;
|
|
786
|
+
typedef std::unordered_map<std::string, std::shared_ptr<Function>>
|
|
787
|
+
StringFunctionMap;
|
|
788
|
+
typedef std::unordered_map<std::string, StringFunctionMap> FunctionRegistry;
|
|
789
|
+
typedef std::unordered_map<std::string, std::string> SharedInstances;
|
|
790
|
+
typedef std::unordered_map<std::string, json> MetaData;
|
|
791
|
+
|
|
792
|
+
// Maps: class_name => function_name => functionCallback
|
|
793
|
+
FunctionRegistry _class_function_registry;
|
|
794
|
+
// Maps: instanceId => function_name => functionCallback
|
|
795
|
+
FunctionRegistry _function_registry;
|
|
796
|
+
// Maps: instanceId => instanceObj
|
|
797
|
+
StringAnyMap _instances;
|
|
798
|
+
// Maps: instanceId => class_name
|
|
799
|
+
SharedInstances _shared_instances;
|
|
800
|
+
// Optional schema information
|
|
801
|
+
MetaData _meta_data;
|
|
802
|
+
|
|
803
|
+
public:
|
|
804
|
+
template <typename Klass, typename... Args>
|
|
805
|
+
static void register_constructor(const std::string& class_name) {
|
|
806
|
+
LocalFactory::inject_create_isolated_function<Klass, Args...>(class_name);
|
|
807
|
+
LocalFactory::inject_create_shared_function<Klass, Args...>(class_name);
|
|
808
|
+
LocalFactory::inject_delete_function<Klass>(class_name);
|
|
809
|
+
}
|
|
934
810
|
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
811
|
+
template <typename Klass,
|
|
812
|
+
typename Func,
|
|
813
|
+
Func f,
|
|
814
|
+
typename Ret,
|
|
815
|
+
typename... Args>
|
|
816
|
+
static void register_member_function(const std::string& class_name,
|
|
817
|
+
const std::string& function_name) {
|
|
818
|
+
auto func = [](const std::shared_ptr<Klass>& ptr) {
|
|
819
|
+
return vrpc::variadic_bind_member<Klass, Func, Args...>(f, ptr);
|
|
820
|
+
};
|
|
821
|
+
auto funcT =
|
|
822
|
+
std::make_shared<MemberFunction<Klass, decltype(func), Ret, Args...>>(
|
|
823
|
+
func);
|
|
824
|
+
detail::init<LocalFactory>()
|
|
825
|
+
._class_function_registry[class_name][function_name] =
|
|
826
|
+
std::static_pointer_cast<Function>(funcT);
|
|
827
|
+
_VRPC_DEBUG << "Registered: " << class_name << "::" << function_name
|
|
828
|
+
<< std::endl;
|
|
829
|
+
}
|
|
946
830
|
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
831
|
+
template <typename Func, Func f, typename Ret, typename... Args>
|
|
832
|
+
static void register_static_function(const std::string& class_name,
|
|
833
|
+
const std::string& function_name) {
|
|
834
|
+
auto func = []() { return vrpc::variadic_bind<Func, Args...>(f); };
|
|
835
|
+
auto funcT =
|
|
836
|
+
std::make_shared<StaticFunction<decltype(func), Ret, Args...>>(func);
|
|
837
|
+
detail::init<LocalFactory>()._function_registry[class_name][function_name] =
|
|
838
|
+
std::static_pointer_cast<Function>(funcT);
|
|
839
|
+
_VRPC_DEBUG << "Registered: " << class_name << "::" << function_name
|
|
840
|
+
<< std::endl;
|
|
841
|
+
}
|
|
958
842
|
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
843
|
+
static void register_meta_data(const std::string& class_name,
|
|
844
|
+
const std::string& function_name,
|
|
845
|
+
const std::string& description,
|
|
846
|
+
const json& params,
|
|
847
|
+
const json& ret) {
|
|
848
|
+
LocalFactory& rf = detail::init<LocalFactory>();
|
|
849
|
+
json& j = rf._meta_data[class_name];
|
|
850
|
+
j[function_name]["description"] = description;
|
|
851
|
+
j[function_name]["params"] = params;
|
|
852
|
+
j[function_name]["ret"] = ret;
|
|
853
|
+
}
|
|
966
854
|
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
if (
|
|
971
|
-
|
|
972
|
-
functions.push_back(kv.first);
|
|
973
|
-
}
|
|
974
|
-
}
|
|
975
|
-
return functions;
|
|
855
|
+
static std::vector<std::string> get_instances(const std::string& class_name) {
|
|
856
|
+
std::vector<std::string> instances;
|
|
857
|
+
for (const auto& kv : detail::init<LocalFactory>()._shared_instances) {
|
|
858
|
+
if (kv.second == class_name)
|
|
859
|
+
instances.push_back(kv.first);
|
|
976
860
|
}
|
|
861
|
+
return instances;
|
|
862
|
+
}
|
|
977
863
|
|
|
978
|
-
|
|
979
|
-
const std::string& class_name
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
}
|
|
864
|
+
static std::vector<std::string> get_member_functions(
|
|
865
|
+
const std::string& class_name) {
|
|
866
|
+
std::vector<std::string> functions;
|
|
867
|
+
const auto& it =
|
|
868
|
+
detail::init<LocalFactory>()._class_function_registry.find(class_name);
|
|
869
|
+
if (it != detail::init<LocalFactory>()._class_function_registry.end()) {
|
|
870
|
+
for (const auto& kv : it->second) {
|
|
871
|
+
functions.push_back(kv.first);
|
|
987
872
|
}
|
|
988
|
-
return functions;
|
|
989
873
|
}
|
|
874
|
+
return functions;
|
|
875
|
+
}
|
|
990
876
|
|
|
991
|
-
|
|
992
|
-
std::
|
|
993
|
-
|
|
994
|
-
|
|
877
|
+
static std::vector<std::string> get_static_functions(
|
|
878
|
+
const std::string& class_name) {
|
|
879
|
+
std::vector<std::string> functions;
|
|
880
|
+
const auto& it =
|
|
881
|
+
detail::init<LocalFactory>()._function_registry.find(class_name);
|
|
882
|
+
if (it != detail::init<LocalFactory>()._function_registry.end()) {
|
|
883
|
+
for (const auto& kv : it->second) {
|
|
884
|
+
functions.push_back(kv.first);
|
|
995
885
|
}
|
|
996
|
-
return classes;
|
|
997
886
|
}
|
|
887
|
+
return functions;
|
|
888
|
+
}
|
|
998
889
|
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
890
|
+
static std::vector<std::string> get_classes() {
|
|
891
|
+
std::vector<std::string> classes;
|
|
892
|
+
for (const auto& kv :
|
|
893
|
+
detail::init<LocalFactory>()._class_function_registry) {
|
|
894
|
+
classes.push_back(kv.first);
|
|
1002
895
|
}
|
|
896
|
+
return classes;
|
|
897
|
+
}
|
|
1003
898
|
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
return json.dump();
|
|
1009
|
-
}
|
|
899
|
+
static json get_meta_data(const std::string& class_name) {
|
|
900
|
+
LocalFactory& rf = detail::init<LocalFactory>();
|
|
901
|
+
return rf._meta_data[class_name];
|
|
902
|
+
}
|
|
1010
903
|
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
904
|
+
static std::string call(const std::string& jsonString) {
|
|
905
|
+
json json;
|
|
906
|
+
json = json::parse(jsonString);
|
|
907
|
+
LocalFactory::call(json);
|
|
908
|
+
return json.dump();
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
static void call(json& json) {
|
|
912
|
+
const std::string context = json["c"].get<std::string>();
|
|
913
|
+
std::string function = json["f"].get<std::string>();
|
|
914
|
+
function += vrpc::get_signature(json["a"]);
|
|
915
|
+
_VRPC_DEBUG << "Calling function: " << function
|
|
916
|
+
<< " with payload: " << json["a"] << std::endl;
|
|
917
|
+
auto it_t = detail::init<LocalFactory>()._function_registry.find(context);
|
|
918
|
+
if (it_t != detail::init<LocalFactory>()._function_registry.end()) {
|
|
919
|
+
auto it_f = it_t->second.find(function);
|
|
920
|
+
if (it_f != it_t->second.end()) {
|
|
921
|
+
it_f->second->call_function(json);
|
|
1026
922
|
return;
|
|
1027
923
|
}
|
|
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
|
|
924
|
+
json["e"] = "Could not find function: " + function;
|
|
925
|
+
return;
|
|
1041
926
|
}
|
|
927
|
+
json["e"] = "Could not find context: " + context;
|
|
928
|
+
}
|
|
1042
929
|
|
|
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();
|
|
930
|
+
static void load_bindings(const std::string& path) {
|
|
931
|
+
#if defined(VRPC_WITH_DL) && !defined(_WIN32)
|
|
932
|
+
void* libHandle = dlopen(path.c_str(), RTLD_LAZY);
|
|
933
|
+
if (libHandle == 0) {
|
|
934
|
+
throw std::runtime_error("Problem loading bindings: " +
|
|
935
|
+
std::string(dlerror()));
|
|
1058
936
|
}
|
|
937
|
+
#else
|
|
938
|
+
_VRPC_DEBUG << "Ignored call, dynamic loading is disabled" << std::endl;
|
|
939
|
+
#endif
|
|
940
|
+
}
|
|
1059
941
|
|
|
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
|
-
};
|
|
942
|
+
private:
|
|
943
|
+
LocalFactory() {}
|
|
1177
944
|
|
|
1178
|
-
|
|
1179
|
-
struct RegisterCtorX {
|
|
1180
|
-
static const CtorXRegistrar<Klass, Args...> registerAs;
|
|
1181
|
-
};
|
|
945
|
+
LocalFactory(const LocalFactory&) = default;
|
|
1182
946
|
|
|
947
|
+
virtual ~LocalFactory() = default;
|
|
1183
948
|
|
|
1184
|
-
|
|
1185
|
-
|
|
949
|
+
template <typename Klass>
|
|
950
|
+
static std::string create_instance_id(
|
|
951
|
+
const std::shared_ptr<Klass>& ptr) noexcept {
|
|
952
|
+
std::ostringstream ss;
|
|
953
|
+
ss << reinterpret_cast<std::uintptr_t>(ptr.get());
|
|
954
|
+
return ss.str();
|
|
955
|
+
}
|
|
1186
956
|
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
957
|
+
template <typename Klass, typename... Args>
|
|
958
|
+
static void inject_create_isolated_function(const std::string& class_name) {
|
|
959
|
+
auto func = [=](const std::string& instance_id, Args... args) {
|
|
960
|
+
LocalFactory& rf = detail::init<LocalFactory>();
|
|
961
|
+
const auto& it = rf._instances.find(instance_id);
|
|
962
|
+
if (it != rf._instances.end())
|
|
963
|
+
return instance_id;
|
|
964
|
+
// Create instance
|
|
965
|
+
auto ptr = std::shared_ptr<Klass>(new Klass(args...));
|
|
966
|
+
// Bind member functions
|
|
967
|
+
for (auto& i : rf._class_function_registry[class_name]) {
|
|
968
|
+
auto functionCallback = i.second->clone();
|
|
969
|
+
functionCallback->bind_instance(ptr);
|
|
970
|
+
rf._function_registry[instance_id][i.first] = functionCallback;
|
|
1197
971
|
}
|
|
972
|
+
// Keep instance alive by saving the shared_ptr
|
|
973
|
+
rf._instances[instance_id] = Value(ptr);
|
|
974
|
+
return instance_id;
|
|
1198
975
|
};
|
|
976
|
+
auto funcT = std::make_shared<
|
|
977
|
+
ConstructorFunction<decltype(func), const std::string&, Args...>>(func);
|
|
978
|
+
const std::string func_name("__createIsolated__" +
|
|
979
|
+
vrpc::get_signature<std::string, Args...>());
|
|
980
|
+
detail::init<LocalFactory>()._function_registry[class_name][func_name] =
|
|
981
|
+
std::static_pointer_cast<Function>(funcT);
|
|
982
|
+
_VRPC_DEBUG << "Registered: " << class_name << "::" << func_name
|
|
983
|
+
<< std::endl;
|
|
984
|
+
}
|
|
1199
985
|
|
|
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);
|
|
986
|
+
template <typename Klass, typename... Args>
|
|
987
|
+
static void inject_create_shared_function(const std::string& class_name) {
|
|
988
|
+
auto func = [=](const std::string& instance_id, Args... args) {
|
|
989
|
+
LocalFactory& rf = detail::init<LocalFactory>();
|
|
990
|
+
const auto& it = rf._instances.find(instance_id);
|
|
991
|
+
if (it != rf._instances.end())
|
|
992
|
+
return instance_id;
|
|
993
|
+
// Create instance
|
|
994
|
+
auto ptr = std::shared_ptr<Klass>(new Klass(args...));
|
|
995
|
+
// Bind member functions
|
|
996
|
+
for (auto& i : rf._class_function_registry[class_name]) {
|
|
997
|
+
auto functionCallback = i.second->clone();
|
|
998
|
+
functionCallback->bind_instance(ptr);
|
|
999
|
+
rf._function_registry[instance_id][i.first] = functionCallback;
|
|
1221
1000
|
}
|
|
1001
|
+
// Keep instance alive by saving the shared_ptr
|
|
1002
|
+
rf._instances[instance_id] = Value(ptr);
|
|
1003
|
+
// Store shared instance
|
|
1004
|
+
rf._shared_instances.insert({instance_id, class_name});
|
|
1005
|
+
return instance_id;
|
|
1222
1006
|
};
|
|
1007
|
+
auto funcT = std::make_shared<
|
|
1008
|
+
ConstructorFunction<decltype(func), const std::string&, Args...>>(func);
|
|
1009
|
+
const std::string func_name("__createShared__" +
|
|
1010
|
+
vrpc::get_signature<std::string, Args...>());
|
|
1011
|
+
detail::init<LocalFactory>()._function_registry[class_name][func_name] =
|
|
1012
|
+
std::static_pointer_cast<Function>(funcT);
|
|
1013
|
+
_VRPC_DEBUG << "Registered: " << class_name << "::" << func_name
|
|
1014
|
+
<< std::endl;
|
|
1015
|
+
}
|
|
1223
1016
|
|
|
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
|
-
}
|
|
1017
|
+
template <typename Klass>
|
|
1018
|
+
static void inject_delete_function(const std::string& class_name) {
|
|
1019
|
+
auto func = [=](const std::string& instance_id) {
|
|
1020
|
+
LocalFactory& rf = detail::init<LocalFactory>();
|
|
1021
|
+
const auto& it = rf._instances.find(instance_id);
|
|
1022
|
+
if (it == rf._instances.end())
|
|
1023
|
+
return false;
|
|
1024
|
+
rf._function_registry.erase(instance_id);
|
|
1025
|
+
rf._instances.erase(instance_id);
|
|
1026
|
+
rf._shared_instances.erase(instance_id);
|
|
1027
|
+
return true;
|
|
1243
1028
|
};
|
|
1029
|
+
auto funcT = std::make_shared<
|
|
1030
|
+
ConstructorFunction<decltype(func), const std::string&>>(func);
|
|
1031
|
+
const std::string func_name("__delete__" +
|
|
1032
|
+
vrpc::get_signature<std::string>());
|
|
1033
|
+
detail::init<LocalFactory>()._function_registry[class_name][func_name] =
|
|
1034
|
+
std::static_pointer_cast<Function>(funcT);
|
|
1035
|
+
_VRPC_DEBUG << "Registered: " << class_name << "::" << func_name
|
|
1036
|
+
<< std::endl;
|
|
1037
|
+
}
|
|
1038
|
+
};
|
|
1244
1039
|
|
|
1245
|
-
|
|
1246
|
-
struct RegisterStaticFunction {
|
|
1247
|
-
static const StaticFunctionRegistrar<Func, f, Ret, Args...> registerAs;
|
|
1248
|
-
};
|
|
1040
|
+
namespace detail {
|
|
1249
1041
|
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1042
|
+
template <class Klass, typename... Args>
|
|
1043
|
+
struct CtorRegistrar {
|
|
1044
|
+
CtorRegistrar(const std::string& class_name) {
|
|
1045
|
+
LocalFactory::register_constructor<Klass, Args...>(class_name);
|
|
1046
|
+
}
|
|
1047
|
+
};
|
|
1048
|
+
|
|
1049
|
+
template <class Klass, typename... Args>
|
|
1050
|
+
struct RegisterCtor {
|
|
1051
|
+
static const CtorRegistrar<Klass, Args...> registerAs;
|
|
1052
|
+
};
|
|
1053
|
+
|
|
1054
|
+
template <class Klass, typename... Args>
|
|
1055
|
+
struct CtorXRegistrar {
|
|
1056
|
+
CtorXRegistrar(const std::string& class_name,
|
|
1057
|
+
const std::string& ctor_description,
|
|
1058
|
+
const ret<std::string>& ret,
|
|
1059
|
+
const std::vector<param> params = {}) {
|
|
1060
|
+
LocalFactory::register_constructor<Klass, Args...>(class_name);
|
|
1061
|
+
const std::string ctor_name("__createShared__" +
|
|
1062
|
+
vrpc::get_signature<std::string, Args...>());
|
|
1063
|
+
json jp;
|
|
1064
|
+
for (const auto& param : params) {
|
|
1065
|
+
jp.push_back(param.j);
|
|
1066
|
+
}
|
|
1067
|
+
LocalFactory::register_meta_data(class_name, ctor_name, ctor_description,
|
|
1068
|
+
jp, ret.j);
|
|
1069
|
+
}
|
|
1070
|
+
};
|
|
1071
|
+
|
|
1072
|
+
template <class Klass, typename... Args>
|
|
1073
|
+
struct RegisterCtorX {
|
|
1074
|
+
static const CtorXRegistrar<Klass, Args...> registerAs;
|
|
1075
|
+
};
|
|
1076
|
+
|
|
1077
|
+
template <class Klass, typename Func, Func f, typename Ret, typename... Args>
|
|
1078
|
+
struct MemberFunctionRegistrar {
|
|
1079
|
+
MemberFunctionRegistrar(const std::string& class_name,
|
|
1080
|
+
const std::string& function_name) {
|
|
1081
|
+
const std::string full_function_name(function_name +
|
|
1082
|
+
vrpc::get_signature<Args...>());
|
|
1083
|
+
LocalFactory::register_member_function<Klass, Func, f, Ret, Args...>(
|
|
1084
|
+
class_name, full_function_name);
|
|
1085
|
+
}
|
|
1086
|
+
};
|
|
1087
|
+
|
|
1088
|
+
template <class Klass, typename Func, Func f, typename Ret, typename... Args>
|
|
1089
|
+
struct MemberFunctionXRegistrar {
|
|
1090
|
+
MemberFunctionXRegistrar(const std::string& class_name,
|
|
1091
|
+
const std::string& function_name,
|
|
1092
|
+
const std::string& function_description,
|
|
1093
|
+
const ret<Ret>& ret,
|
|
1094
|
+
const std::vector<param> params = {}) {
|
|
1095
|
+
const std::string full_function_name(function_name +
|
|
1096
|
+
vrpc::get_signature<Args...>());
|
|
1097
|
+
LocalFactory::register_member_function<Klass, Func, f, Ret, Args...>(
|
|
1098
|
+
class_name, full_function_name);
|
|
1099
|
+
json jp;
|
|
1100
|
+
for (const auto& param : params) {
|
|
1101
|
+
jp.push_back(param.j);
|
|
1102
|
+
}
|
|
1103
|
+
LocalFactory::register_meta_data(class_name, full_function_name,
|
|
1104
|
+
function_description, jp, ret.j);
|
|
1105
|
+
}
|
|
1106
|
+
};
|
|
1107
|
+
|
|
1108
|
+
template <class Klass, typename Func, Func f, typename Ret, typename... Args>
|
|
1109
|
+
struct RegisterMemberFunction {
|
|
1110
|
+
static const MemberFunctionRegistrar<Klass, Func, f, Ret, Args...> registerAs;
|
|
1111
|
+
};
|
|
1112
|
+
|
|
1113
|
+
template <class Klass, typename Func, Func f, typename Ret, typename... Args>
|
|
1114
|
+
struct RegisterMemberFunctionX {
|
|
1115
|
+
static const MemberFunctionXRegistrar<Klass, Func, f, Ret, Args...>
|
|
1116
|
+
registerAs;
|
|
1117
|
+
};
|
|
1118
|
+
|
|
1119
|
+
template <typename Func, Func f, typename Ret, typename... Args>
|
|
1120
|
+
struct StaticFunctionRegistrar {
|
|
1121
|
+
StaticFunctionRegistrar(const std::string& class_name,
|
|
1122
|
+
const std::string& function_name) {
|
|
1123
|
+
const std::string full_function_name(function_name +
|
|
1124
|
+
vrpc::get_signature<Args...>());
|
|
1125
|
+
LocalFactory::register_static_function<Func, f, Ret, Args...>(
|
|
1126
|
+
class_name, full_function_name);
|
|
1127
|
+
}
|
|
1128
|
+
};
|
|
1129
|
+
|
|
1130
|
+
template <typename Func, Func f, typename Ret, typename... Args>
|
|
1131
|
+
struct RegisterStaticFunction {
|
|
1132
|
+
static const StaticFunctionRegistrar<Func, f, Ret, Args...> registerAs;
|
|
1133
|
+
};
|
|
1134
|
+
|
|
1135
|
+
template <typename Func, Func f, typename Ret, typename... Args>
|
|
1136
|
+
struct StaticFunctionXRegistrar {
|
|
1137
|
+
StaticFunctionXRegistrar(const std::string& class_name,
|
|
1138
|
+
const std::string& function_name,
|
|
1139
|
+
const std::string& function_description,
|
|
1140
|
+
const ret<Ret>& ret,
|
|
1141
|
+
const std::vector<param> params = {}) {
|
|
1142
|
+
const std::string full_function_name(function_name +
|
|
1143
|
+
vrpc::get_signature<Args...>());
|
|
1144
|
+
LocalFactory::register_static_function<Func, f, Ret, Args...>(
|
|
1145
|
+
class_name, full_function_name);
|
|
1146
|
+
json jp;
|
|
1147
|
+
for (const auto& param : params) {
|
|
1148
|
+
jp.push_back(param.j);
|
|
1149
|
+
}
|
|
1150
|
+
LocalFactory::register_meta_data(class_name, full_function_name,
|
|
1151
|
+
function_description, jp, ret.j);
|
|
1152
|
+
}
|
|
1153
|
+
};
|
|
1269
1154
|
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1155
|
+
template <typename Func, Func f, typename Ret, typename... Args>
|
|
1156
|
+
struct RegisterStaticFunctionX {
|
|
1157
|
+
static const StaticFunctionXRegistrar<Func, f, Ret, Args...> registerAs;
|
|
1158
|
+
};
|
|
1159
|
+
} // namespace detail
|
|
1275
1160
|
|
|
1276
|
-
|
|
1161
|
+
// ####################### Macro utility #######################
|
|
1277
1162
|
|
|
1278
1163
|
#define CAT(A, B) A##B
|
|
1279
1164
|
#define SELECT(NAME, NUM) CAT(_##NAME##_, NUM)
|
|
@@ -1298,7 +1183,7 @@ namespace vrpc {
|
|
|
1298
1183
|
#define VRPC_STATIC_FUNCTION_X(...) \
|
|
1299
1184
|
VA_SELECT(VRPC_STATIC_FUNCTION_X, __VA_ARGS__)
|
|
1300
1185
|
|
|
1301
|
-
|
|
1186
|
+
// deprecate
|
|
1302
1187
|
#define VRPC_MEMBER_FUNCTION_CONST(...) \
|
|
1303
1188
|
VA_SELECT(VRPC_CONST_MEMBER_FUNCTION, __VA_ARGS__)
|
|
1304
1189
|
#define VRPC_VOID_MEMBER_FUNCTION(...) \
|
|
@@ -1308,17 +1193,18 @@ namespace vrpc {
|
|
|
1308
1193
|
#define VRPC_VOID_STATIC_FUNCTION(...) \
|
|
1309
1194
|
VA_SELECT(VRPC_VOID_STATIC_FUNCTION, __VA_ARGS__)
|
|
1310
1195
|
|
|
1311
|
-
|
|
1196
|
+
// ####################### Callbacks #######################
|
|
1312
1197
|
|
|
1313
|
-
#define VRPC_CALLBACK(
|
|
1198
|
+
#define VRPC_CALLBACK(...) const std::function<void(__VA_ARGS__)>&
|
|
1314
1199
|
|
|
1315
|
-
|
|
1200
|
+
// ####################### Constructors #######################
|
|
1316
1201
|
|
|
1317
1202
|
#define _VRPC_CTOR_RET_DESC "returns the id of the created instance"
|
|
1318
1203
|
|
|
1319
|
-
#define _VRPC_CTOR_VA_ARGS(Klass, ...)
|
|
1320
|
-
|
|
1321
|
-
|
|
1204
|
+
#define _VRPC_CTOR_VA_ARGS(Klass, ...) \
|
|
1205
|
+
template <> \
|
|
1206
|
+
const vrpc::detail::CtorRegistrar<Klass, __VA_ARGS__> \
|
|
1207
|
+
vrpc::detail::RegisterCtor<Klass, __VA_ARGS__>::registerAs(#Klass);
|
|
1322
1208
|
|
|
1323
1209
|
#define _VRPC_CTOR_1(Klass) \
|
|
1324
1210
|
template <> \
|
|
@@ -1408,13 +1294,13 @@ namespace vrpc {
|
|
|
1408
1294
|
{A5Name, A5Default, A5Desc}, \
|
|
1409
1295
|
{A6Name, A6Default, A6Desc}});
|
|
1410
1296
|
|
|
1411
|
-
|
|
1297
|
+
// deprecate
|
|
1412
1298
|
#define VRPC_VOID_CTOR(Klass) \
|
|
1413
1299
|
template <> \
|
|
1414
1300
|
const vrpc::detail::CtorRegistrar<Klass> \
|
|
1415
1301
|
vrpc::detail::RegisterCtor<Klass>::registerAs(#Klass);
|
|
1416
1302
|
|
|
1417
|
-
|
|
1303
|
+
// ####################### Zero arguments #######################
|
|
1418
1304
|
|
|
1419
1305
|
#define _VRPC_MEMBER_FUNCTION_3(Klass, Ret, Function) \
|
|
1420
1306
|
template <> \
|
|
@@ -1476,7 +1362,7 @@ namespace vrpc {
|
|
|
1476
1362
|
Ret>::registerAs(#Klass, #Function, FunctionDesc, {RetDesc});
|
|
1477
1363
|
|
|
1478
1364
|
#define _VRPC_VOID_MEMBER_FUNCTION_2(Klass, Function) \
|
|
1479
|
-
_VRPC_MEMBER_FUNCTION_3(Klass,
|
|
1365
|
+
_VRPC_MEMBER_FUNCTION_3(Klass, void, Function)
|
|
1480
1366
|
|
|
1481
1367
|
#define _VRPC_VOID_MEMBER_FUNCTION_CONST_2(Klass, Function) \
|
|
1482
1368
|
_VRPC_CONST_MEMBER_FUNCTION_3(Klass, void, Function)
|
|
@@ -1484,7 +1370,7 @@ namespace vrpc {
|
|
|
1484
1370
|
#define _VRPC_VOID_STATIC_FUNCTION_2(Klass, Function) \
|
|
1485
1371
|
_VRPC_STATIC_FUNCTION_3(Klass, void, Function)
|
|
1486
1372
|
|
|
1487
|
-
|
|
1373
|
+
// ####################### One argument #######################
|
|
1488
1374
|
|
|
1489
1375
|
#define _VRPC_MEMBER_FUNCTION_4(Klass, Ret, Function, A1) \
|
|
1490
1376
|
template <> \
|
|
@@ -1566,7 +1452,7 @@ namespace vrpc {
|
|
|
1566
1452
|
#define _VRPC_VOID_STATIC_FUNCTION_3(Klass, Function, A1) \
|
|
1567
1453
|
_VRPC_STATIC_FUNCTION_4(Klass, void, Function, A1)
|
|
1568
1454
|
|
|
1569
|
-
|
|
1455
|
+
// ####################### Two arguments #######################
|
|
1570
1456
|
|
|
1571
1457
|
#define _VRPC_MEMBER_FUNCTION_5(Klass, Ret, Function, A1, A2) \
|
|
1572
1458
|
template <> \
|
|
@@ -1586,8 +1472,8 @@ namespace vrpc {
|
|
|
1586
1472
|
&Klass::Function, Ret, A1, A2> \
|
|
1587
1473
|
vrpc::detail::RegisterMemberFunction< \
|
|
1588
1474
|
Klass, \
|
|
1589
|
-
decltype(
|
|
1590
|
-
|
|
1475
|
+
decltype(static_cast<Ret (Klass::*)(A1, A2) const>( \
|
|
1476
|
+
&Klass::Function)), \
|
|
1591
1477
|
&Klass::Function, Ret, A1, A2>::registerAs(#Klass, #Function);
|
|
1592
1478
|
|
|
1593
1479
|
#define _VRPC_STATIC_FUNCTION_5(Klass, Ret, Function, A1, A2) \
|
|
@@ -1626,8 +1512,8 @@ namespace vrpc {
|
|
|
1626
1512
|
&Klass::Function, Ret, A1, A2> \
|
|
1627
1513
|
vrpc::detail::RegisterMemberFunctionX< \
|
|
1628
1514
|
Klass, \
|
|
1629
|
-
decltype(
|
|
1630
|
-
|
|
1515
|
+
decltype(static_cast<Ret (Klass::*)(A1, A2) const>( \
|
|
1516
|
+
&Klass::Function)), \
|
|
1631
1517
|
&Klass::Function, Ret, A1, A2>::registerAs(#Klass, #Function, \
|
|
1632
1518
|
FunctionDesc, {RetDesc}, \
|
|
1633
1519
|
{{A1Name, A1Default, \
|
|
@@ -1660,7 +1546,7 @@ namespace vrpc {
|
|
|
1660
1546
|
#define _VRPC_VOID_STATIC_FUNCTION_4(Klass, Function, A1, A2) \
|
|
1661
1547
|
_VRPC_STATIC_FUNCTION_5(Klass, void, Function, A1, A2)
|
|
1662
1548
|
|
|
1663
|
-
|
|
1549
|
+
// ####################### Three arguments #######################
|
|
1664
1550
|
|
|
1665
1551
|
#define _VRPC_MEMBER_FUNCTION_6(Klass, Ret, Function, A1, A2, A3) \
|
|
1666
1552
|
template <> \
|
|
@@ -1673,17 +1559,17 @@ namespace vrpc {
|
|
|
1673
1559
|
decltype(static_cast<Ret (Klass::*)(A1, A2, A3)>(&Klass::Function)), \
|
|
1674
1560
|
&Klass::Function, Ret, A1, A2, A3>::registerAs(#Klass, #Function);
|
|
1675
1561
|
|
|
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)),
|
|
1562
|
+
#define _VRPC_CONST_MEMBER_FUNCTION_6(Klass, Ret, Function, A1, A2, A3) \
|
|
1563
|
+
template <> \
|
|
1564
|
+
const vrpc::detail::MemberFunctionRegistrar< \
|
|
1565
|
+
Klass, \
|
|
1566
|
+
decltype(static_cast<Ret (Klass::*)(A1, A2, A3) const>( \
|
|
1567
|
+
&Klass::Function)), \
|
|
1568
|
+
&Klass::Function, Ret, A1, A2, A3> \
|
|
1569
|
+
vrpc::detail::RegisterMemberFunction< \
|
|
1570
|
+
Klass, \
|
|
1571
|
+
decltype(static_cast<Ret (Klass::*)(A1, A2, A3) const>( \
|
|
1572
|
+
&Klass::Function)), \
|
|
1687
1573
|
&Klass::Function, Ret, A1, A2, A3>::registerAs(#Klass, #Function);
|
|
1688
1574
|
|
|
1689
1575
|
#define _VRPC_STATIC_FUNCTION_6(Klass, Ret, Function, A1, A2, A3) \
|
|
@@ -1712,23 +1598,23 @@ namespace vrpc {
|
|
|
1712
1598
|
{A2Name, A2Default, A2Desc}, \
|
|
1713
1599
|
{A3Name, A3Default, A3Desc}});
|
|
1714
1600
|
|
|
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},
|
|
1601
|
+
#define _VRPC_CONST_MEMBER_FUNCTION_X_17( \
|
|
1602
|
+
Klass, Ret, RetDesc, Function, FunctionDesc, A1, A1Name, A1Default, \
|
|
1603
|
+
A1Desc, A2, A2Name, A2Default, A2Desc, A3, A3Name, A3Default, A3Desc) \
|
|
1604
|
+
template <> \
|
|
1605
|
+
const vrpc::detail::MemberFunctionXRegistrar< \
|
|
1606
|
+
Klass, \
|
|
1607
|
+
decltype(static_cast<Ret (Klass::*)(A1, A2, A3) const>( \
|
|
1608
|
+
&Klass::Function)), \
|
|
1609
|
+
&Klass::Function, Ret, A1, A2, A3> \
|
|
1610
|
+
vrpc::detail::RegisterMemberFunctionX< \
|
|
1611
|
+
Klass, \
|
|
1612
|
+
decltype(static_cast<Ret (Klass::*)(A1, A2, A3) const>( \
|
|
1613
|
+
&Klass::Function)), \
|
|
1614
|
+
&Klass::Function, Ret, A1, A2, \
|
|
1615
|
+
A3>::registerAs(#Klass, #Function, FunctionDesc, {RetDesc}, \
|
|
1616
|
+
{{A1Name, A1Default, A1Desc}, \
|
|
1617
|
+
{A2Name, A2Default, A2Desc}, \
|
|
1732
1618
|
{A3Name, A3Default, A3Desc}});
|
|
1733
1619
|
|
|
1734
1620
|
#define _VRPC_STATIC_FUNCTION_X_17( \
|
|
@@ -1755,7 +1641,7 @@ namespace vrpc {
|
|
|
1755
1641
|
#define _VRPC_VOID_STATIC_FUNCTION_5(Klass, Function, A1, A2, A3) \
|
|
1756
1642
|
_VRPC_STATIC_FUNCTION_6(Klass, void, Function, A1, A2, A3)
|
|
1757
1643
|
|
|
1758
|
-
|
|
1644
|
+
// ####################### Four arguments #######################
|
|
1759
1645
|
|
|
1760
1646
|
#define _VRPC_MEMBER_FUNCTION_7(Klass, Ret, Function, A1, A2, A3, A4) \
|
|
1761
1647
|
template <> \
|
|
@@ -1765,8 +1651,8 @@ namespace vrpc {
|
|
|
1765
1651
|
&Klass::Function, Ret, A1, A2, A3, A4> \
|
|
1766
1652
|
vrpc::detail::RegisterMemberFunction< \
|
|
1767
1653
|
Klass, \
|
|
1768
|
-
decltype(
|
|
1769
|
-
|
|
1654
|
+
decltype(static_cast<Ret (Klass::*)(A1, A2, A3, A4)>( \
|
|
1655
|
+
&Klass::Function)), \
|
|
1770
1656
|
&Klass::Function, Ret, A1, A2, A3, A4>::registerAs(#Klass, \
|
|
1771
1657
|
#Function);
|
|
1772
1658
|
|
|
@@ -1805,8 +1691,8 @@ namespace vrpc {
|
|
|
1805
1691
|
&Klass::Function, Ret, A1, A2, A3, A4> \
|
|
1806
1692
|
vrpc::detail::RegisterMemberFunctionX< \
|
|
1807
1693
|
Klass, \
|
|
1808
|
-
decltype(
|
|
1809
|
-
|
|
1694
|
+
decltype(static_cast<Ret (Klass::*)(A1, A2, A3, A4)>( \
|
|
1695
|
+
&Klass::Function)), \
|
|
1810
1696
|
&Klass::Function, Ret, A1, A2, A3, \
|
|
1811
1697
|
A4>::registerAs(#Klass, #Function, FunctionDesc, {RetDesc}, \
|
|
1812
1698
|
{{A1Name, A1Default, A1Desc}, \
|
|
@@ -1861,20 +1747,20 @@ namespace vrpc {
|
|
|
1861
1747
|
#define _VRPC_VOID_STATIC_FUNCTION_6(Klass, Function, A1, A2, A3, A4) \
|
|
1862
1748
|
_VRPC_STATIC_FUNCTION_7(Klass, void, Function, A1, A2, A3, A4)
|
|
1863
1749
|
|
|
1864
|
-
|
|
1750
|
+
// ####################### Five arguments #######################
|
|
1865
1751
|
|
|
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,
|
|
1752
|
+
#define _VRPC_MEMBER_FUNCTION_8(Klass, Ret, Function, A1, A2, A3, A4, A5) \
|
|
1753
|
+
template <> \
|
|
1754
|
+
const vrpc::detail::MemberFunctionRegistrar< \
|
|
1755
|
+
Klass, \
|
|
1756
|
+
decltype(static_cast<Ret (Klass::*)(A1, A2, A3, A4, A5)>( \
|
|
1757
|
+
&Klass::Function)), \
|
|
1758
|
+
&Klass::Function, Ret, A1, A2, A3, A4, A5> \
|
|
1759
|
+
vrpc::detail::RegisterMemberFunction< \
|
|
1760
|
+
Klass, \
|
|
1761
|
+
decltype(static_cast<Ret (Klass::*)(A1, A2, A3, A4, A5)>( \
|
|
1762
|
+
&Klass::Function)), \
|
|
1763
|
+
&Klass::Function, Ret, A1, A2, A3, A4, A5>::registerAs(#Klass, \
|
|
1878
1764
|
#Function);
|
|
1879
1765
|
|
|
1880
1766
|
#define _VRPC_CONST_MEMBER_FUNCTION_8(Klass, Ret, Function, A1, A2, A3, A4, \
|
|
@@ -1909,8 +1795,8 @@ namespace vrpc {
|
|
|
1909
1795
|
template <> \
|
|
1910
1796
|
const vrpc::detail::MemberFunctionXRegistrar< \
|
|
1911
1797
|
Klass, \
|
|
1912
|
-
decltype(
|
|
1913
|
-
|
|
1798
|
+
decltype(static_cast<Ret (Klass::*)(A1, A2, A3, A4, A5)>( \
|
|
1799
|
+
&Klass::Function)), \
|
|
1914
1800
|
&Klass::Function, Ret, A1, A2, A3, A4, A5> \
|
|
1915
1801
|
vrpc::detail::RegisterMemberFunctionX< \
|
|
1916
1802
|
Klass, \
|
|
@@ -1974,7 +1860,7 @@ namespace vrpc {
|
|
|
1974
1860
|
#define _VRPC_VOID_STATIC_FUNCTION_7(Klass, Function, A1, A2, A3, A4, A5) \
|
|
1975
1861
|
_VRPC_STATIC_FUNCTION_8(Klass, void, Function, A1, A2, A3, A4, A5)
|
|
1976
1862
|
|
|
1977
|
-
|
|
1863
|
+
// ####################### Six arguments #######################
|
|
1978
1864
|
|
|
1979
1865
|
#define _VRPC_MEMBER_FUNCTION_9(Klass, Ret, Function, A1, A2, A3, A4, A5, A6) \
|
|
1980
1866
|
template <> \
|
|
@@ -2011,8 +1897,8 @@ namespace vrpc {
|
|
|
2011
1897
|
decltype(static_cast<Ret (*)(A1, A2, A3, A4, A5, A6)>(Klass::Function)), \
|
|
2012
1898
|
&Klass::Function, Ret, A1, A2, A3, A4, A5, A6> \
|
|
2013
1899
|
vrpc::detail::RegisterStaticFunction< \
|
|
2014
|
-
decltype(
|
|
2015
|
-
|
|
1900
|
+
decltype(static_cast<Ret (*)(A1, A2, A3, A4, A5, A6)>( \
|
|
1901
|
+
Klass::Function)), \
|
|
2016
1902
|
&Klass::Function, Ret, A1, A2, A3, A4, A5, \
|
|
2017
1903
|
A6>::registerAs(#Klass, #Function);
|
|
2018
1904
|
|
|
@@ -2074,8 +1960,8 @@ namespace vrpc {
|
|
|
2074
1960
|
decltype(static_cast<Ret (*)(A1, A2, A3, A4, A5, A6)>(Klass::Function)), \
|
|
2075
1961
|
&Klass::Function, Ret, A1, A2, A3, A4, A5, A6> \
|
|
2076
1962
|
vrpc::detail::RegisterStaticFunctionX< \
|
|
2077
|
-
decltype(
|
|
2078
|
-
|
|
1963
|
+
decltype(static_cast<Ret (*)(A1, A2, A3, A4, A5, A6)>( \
|
|
1964
|
+
Klass::Function)), \
|
|
2079
1965
|
&Klass::Function, Ret, A1, A2, A3, A4, A5, \
|
|
2080
1966
|
A6>::registerAs(#Klass, #Function, FunctionDesc, {RetDesc}, \
|
|
2081
1967
|
{{A1Name, A1Default, A1Desc}, \
|
|
@@ -2095,6 +1981,6 @@ namespace vrpc {
|
|
|
2095
1981
|
#define _VRPC_VOID_STATIC_FUNCTION_8(Klass, Function, A1, A2, A3, A4, A5, A6) \
|
|
2096
1982
|
_VRPC_STATIC_FUNCTION_9(Klass, void, Function, A1, A2, A3, A4, A5, A6)
|
|
2097
1983
|
|
|
2098
|
-
}
|
|
1984
|
+
} // namespace vrpc
|
|
2099
1985
|
|
|
2100
1986
|
#endif
|