rclnodejs 1.2.0 → 1.4.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/README.md +1 -1
- package/binding.gyp +1 -0
- package/index.js +26 -3
- package/lib/context.js +4 -2
- package/lib/lifecycle.js +9 -0
- package/lib/node.js +106 -18
- package/lib/serialization.js +60 -0
- package/lib/type_description_service.js +27 -1
- package/package.json +3 -1
- package/rosidl_convertor/README.md +298 -0
- package/rosidl_convertor/idl_convertor.js +49 -0
- package/rosidl_convertor/idl_convertor.py +1176 -0
- package/rosidl_gen/generator.json +2 -2
- package/rosidl_gen/index.js +21 -4
- package/rosidl_gen/packages.js +65 -32
- package/rosidl_gen/templates/message.dot +1 -1
- package/scripts/npmjs-readme.md +1 -1
- package/src/addon.cpp +2 -0
- package/src/macros.h +17 -1
- package/src/rcl_action_client_bindings.cpp +3 -2
- package/src/rcl_action_goal_bindings.cpp +3 -2
- package/src/rcl_action_server_bindings.cpp +7 -5
- package/src/rcl_client_bindings.cpp +4 -3
- package/src/rcl_context_bindings.cpp +29 -19
- package/src/rcl_guard_condition_bindings.cpp +3 -2
- package/src/rcl_lifecycle_bindings.cpp +18 -4
- package/src/rcl_node_bindings.cpp +105 -3
- package/src/rcl_publisher_bindings.cpp +4 -3
- package/src/rcl_serialization_bindings.cpp +116 -0
- package/src/rcl_serialization_bindings.h +26 -0
- package/src/rcl_service_bindings.cpp +4 -3
- package/src/rcl_subscription_bindings.cpp +3 -2
- package/src/rcl_time_point_bindings.cpp +3 -2
- package/src/rcl_timer_bindings.cpp +8 -6
- package/src/rcl_utilities.cpp +31 -0
- package/src/rcl_utilities.h +7 -0
- package/tsconfig.json +2 -2
- package/types/context.d.ts +3 -2
- package/types/index.d.ts +26 -1
- package/types/lifecycle.d.ts +7 -0
- package/types/node.d.ts +48 -8
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rosidl-generator",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Generate JavaScript object from ROS IDL(.msg) files",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Generate JavaScript object from ROS IDL(.msg/.srv/.action/.idl) files",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"authors": [
|
|
7
7
|
"Minggang Wang <minggang.wang@intel.com>",
|
package/rosidl_gen/index.js
CHANGED
|
@@ -18,18 +18,35 @@ const fse = require('fs-extra');
|
|
|
18
18
|
const generateJSStructFromIDL = require('./idl_generator.js');
|
|
19
19
|
const packages = require('./packages.js');
|
|
20
20
|
const path = require('path');
|
|
21
|
-
|
|
21
|
+
const idlConvertor = require('../rosidl_convertor/idl_convertor.js');
|
|
22
22
|
const generatedRoot = path.join(__dirname, '../generated/');
|
|
23
23
|
const serviceMsgPath = path.join(generatedRoot, 'srv_msg');
|
|
24
|
+
const idlPath = path.join(generatedRoot, 'share');
|
|
25
|
+
const useIDL = !!process.argv.find((arg) => arg === '--idl');
|
|
24
26
|
|
|
25
27
|
function getInstalledPackagePaths() {
|
|
26
28
|
return process.env.AMENT_PREFIX_PATH.split(path.delimiter);
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
async function generateInPath(path) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
let pkgsInfo = null;
|
|
33
|
+
if (!useIDL) {
|
|
34
|
+
pkgsInfo = Array.from(
|
|
35
|
+
(await packages.findPackagesInDirectory(path)).values()
|
|
36
|
+
);
|
|
37
|
+
} else {
|
|
38
|
+
const idlPkgs = await packages.findPackagesInDirectory(path, useIDL);
|
|
39
|
+
await fse.ensureDir(idlPath);
|
|
40
|
+
const promises = [];
|
|
41
|
+
idlPkgs.forEach((pkg) => {
|
|
42
|
+
pkg.idls.forEach((idl) => {
|
|
43
|
+
promises.push(idlConvertor(idl.pkgName, idl.filePath, idlPath));
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
await Promise.all(promises);
|
|
47
|
+
const pkgsFromIdl = await packages.findPackagesInDirectory(idlPath, false);
|
|
48
|
+
pkgsInfo = Array.from(pkgsFromIdl.values());
|
|
49
|
+
}
|
|
33
50
|
|
|
34
51
|
await Promise.all(
|
|
35
52
|
pkgsInfo.map((pkgInfo) => generateJSStructFromIDL(pkgInfo, generatedRoot))
|
package/rosidl_gen/packages.js
CHANGED
|
@@ -70,7 +70,13 @@ function grabInterfaceInfo(filePath, amentExecuted) {
|
|
|
70
70
|
function addInterfaceInfo(info, type, pkgMap) {
|
|
71
71
|
let pkgName = info.pkgName;
|
|
72
72
|
if (!pkgMap.has(pkgName)) {
|
|
73
|
-
pkgMap.set(pkgName, {
|
|
73
|
+
pkgMap.set(pkgName, {
|
|
74
|
+
messages: [],
|
|
75
|
+
services: [],
|
|
76
|
+
actions: [],
|
|
77
|
+
idls: [],
|
|
78
|
+
pkgName,
|
|
79
|
+
});
|
|
74
80
|
}
|
|
75
81
|
let pkg = pkgMap.get(pkgName);
|
|
76
82
|
pkg[type].push(info);
|
|
@@ -157,26 +163,32 @@ async function generateMsgForSrv(filePath, interfaceInfo, pkgMap) {
|
|
|
157
163
|
}
|
|
158
164
|
}
|
|
159
165
|
|
|
160
|
-
async function addInterfaceInfos(filePath, dir, pkgMap) {
|
|
161
|
-
const interfaceInfo = grabInterfaceInfo(filePath, true);
|
|
166
|
+
async function addInterfaceInfos(filePath, dir, pkgMap, useIDL) {
|
|
167
|
+
const interfaceInfo = grabInterfaceInfo(filePath, /*amentExecuted=*/ true);
|
|
162
168
|
const ignore = pkgFilters.matchesAny(interfaceInfo);
|
|
163
169
|
if (!ignore) {
|
|
164
|
-
if (
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
if (path.dirname(dir).split(path.sep).pop() !== 'action') {
|
|
168
|
-
addInterfaceInfo(interfaceInfo, 'messages', pkgMap);
|
|
169
|
-
}
|
|
170
|
-
} else if (path.extname(filePath) === '.srv') {
|
|
171
|
-
const requestMsgName = `${path.parse(filePath).name}_Request.msg`;
|
|
172
|
-
if (!fs.existsSync(path.join(path.dirname(filePath), requestMsgName))) {
|
|
173
|
-
await generateMsgForSrv(filePath, interfaceInfo, pkgMap);
|
|
170
|
+
if (useIDL) {
|
|
171
|
+
if (path.extname(filePath) === '.idl') {
|
|
172
|
+
addInterfaceInfo(interfaceInfo, 'idls', pkgMap);
|
|
174
173
|
}
|
|
175
|
-
addInterfaceInfo(interfaceInfo, 'services', pkgMap);
|
|
176
|
-
} else if (path.extname(filePath) === '.action') {
|
|
177
|
-
addInterfaceInfo(interfaceInfo, 'actions', pkgMap);
|
|
178
174
|
} else {
|
|
179
|
-
|
|
175
|
+
if (path.extname(filePath) === '.msg') {
|
|
176
|
+
// Some .msg files were generated prior to 0.3.2 for .action files,
|
|
177
|
+
// which has been disabled. So these files should be ignored here.
|
|
178
|
+
if (path.dirname(dir).split(path.sep).pop() !== 'action') {
|
|
179
|
+
addInterfaceInfo(interfaceInfo, 'messages', pkgMap);
|
|
180
|
+
}
|
|
181
|
+
} else if (path.extname(filePath) === '.srv') {
|
|
182
|
+
const requestMsgName = `${path.parse(filePath).name}_Request.msg`;
|
|
183
|
+
if (!fs.existsSync(path.join(path.dirname(filePath), requestMsgName))) {
|
|
184
|
+
await generateMsgForSrv(filePath, interfaceInfo, pkgMap);
|
|
185
|
+
}
|
|
186
|
+
addInterfaceInfo(interfaceInfo, 'services', pkgMap);
|
|
187
|
+
} else if (path.extname(filePath) === '.action') {
|
|
188
|
+
addInterfaceInfo(interfaceInfo, 'actions', pkgMap);
|
|
189
|
+
} else {
|
|
190
|
+
// we ignore all other files.
|
|
191
|
+
}
|
|
180
192
|
}
|
|
181
193
|
}
|
|
182
194
|
}
|
|
@@ -186,7 +198,7 @@ async function addInterfaceInfos(filePath, dir, pkgMap) {
|
|
|
186
198
|
* @param {string} dir - the directory to search in
|
|
187
199
|
* @return {Promise<Map<string, object>>} A mapping from the package name to some info about it.
|
|
188
200
|
*/
|
|
189
|
-
async function findAmentPackagesInDirectory(dir) {
|
|
201
|
+
async function findAmentPackagesInDirectory(dir, useIDL) {
|
|
190
202
|
const pkgs = await getAmentPackages(dir);
|
|
191
203
|
const files = await Promise.all(
|
|
192
204
|
pkgs.map((pkg) => getPackageDefinitionsFiles(pkg, dir))
|
|
@@ -195,7 +207,7 @@ async function findAmentPackagesInDirectory(dir) {
|
|
|
195
207
|
const rosFiles = files.flat();
|
|
196
208
|
const pkgMap = new Map();
|
|
197
209
|
await Promise.all(
|
|
198
|
-
rosFiles.map((filePath) => addInterfaceInfos(filePath, dir, pkgMap))
|
|
210
|
+
rosFiles.map((filePath) => addInterfaceInfos(filePath, dir, pkgMap, useIDL))
|
|
199
211
|
);
|
|
200
212
|
return pkgMap;
|
|
201
213
|
}
|
|
@@ -205,7 +217,7 @@ async function findAmentPackagesInDirectory(dir) {
|
|
|
205
217
|
* @param {string} dir - the directory to search in
|
|
206
218
|
* @return {Promise<Map<string, object>>} A mapping from the package name to some info about it.
|
|
207
219
|
*/
|
|
208
|
-
async function findPackagesInDirectory(dir) {
|
|
220
|
+
async function findPackagesInDirectory(dir, useIDL) {
|
|
209
221
|
return new Promise((resolve, reject) => {
|
|
210
222
|
let amentExecuted = true;
|
|
211
223
|
|
|
@@ -217,30 +229,51 @@ async function findPackagesInDirectory(dir) {
|
|
|
217
229
|
}
|
|
218
230
|
|
|
219
231
|
if (amentExecuted) {
|
|
220
|
-
return resolve(findAmentPackagesInDirectory(dir));
|
|
232
|
+
return resolve(findAmentPackagesInDirectory(dir, useIDL));
|
|
221
233
|
}
|
|
222
234
|
|
|
223
235
|
let walker = walk.walk(dir, { followLinks: true });
|
|
224
236
|
let pkgMap = new Map();
|
|
225
|
-
walker.on('file', (root, file, next) => {
|
|
237
|
+
walker.on('file', async (root, file, next) => {
|
|
226
238
|
const interfaceInfo = grabInterfaceInfo(
|
|
227
239
|
path.join(root, file.name),
|
|
228
240
|
amentExecuted
|
|
229
241
|
);
|
|
230
242
|
const ignore = pkgFilters.matchesAny(interfaceInfo);
|
|
231
243
|
if (!ignore) {
|
|
232
|
-
if (
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
if (path.dirname(root).split(path.sep).pop() !== 'action') {
|
|
236
|
-
addInterfaceInfo(interfaceInfo, 'messages', pkgMap);
|
|
244
|
+
if (useIDL) {
|
|
245
|
+
if (path.extname(file.name) === '.idl') {
|
|
246
|
+
addInterfaceInfo(interfaceInfo, 'idls', pkgMap);
|
|
237
247
|
}
|
|
238
|
-
} else if (path.extname(file.name) === '.srv') {
|
|
239
|
-
addInterfaceInfo(interfaceInfo, 'services', pkgMap);
|
|
240
|
-
} else if (path.extname(file.name) === '.action') {
|
|
241
|
-
addInterfaceInfo(interfaceInfo, 'actions', pkgMap);
|
|
242
248
|
} else {
|
|
243
|
-
|
|
249
|
+
if (path.extname(file.name) === '.msg') {
|
|
250
|
+
// Some .msg files were generated prior to 0.3.2 for .action files,
|
|
251
|
+
// which has been disabled. So these files should be ignored here.
|
|
252
|
+
if (path.dirname(root).split(path.sep).pop() !== 'action') {
|
|
253
|
+
addInterfaceInfo(interfaceInfo, 'messages', pkgMap);
|
|
254
|
+
}
|
|
255
|
+
} else if (path.extname(file.name) === '.srv') {
|
|
256
|
+
const requestMsgName = `${path.parse(interfaceInfo.filePath).name}_Request.msg`;
|
|
257
|
+
if (
|
|
258
|
+
!fs.existsSync(
|
|
259
|
+
path.join(
|
|
260
|
+
path.dirname(interfaceInfo.filePath),
|
|
261
|
+
requestMsgName
|
|
262
|
+
)
|
|
263
|
+
)
|
|
264
|
+
) {
|
|
265
|
+
await generateMsgForSrv(
|
|
266
|
+
interfaceInfo.filePath,
|
|
267
|
+
interfaceInfo,
|
|
268
|
+
pkgMap
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
addInterfaceInfo(interfaceInfo, 'services', pkgMap);
|
|
272
|
+
} else if (path.extname(file.name) === '.action') {
|
|
273
|
+
addInterfaceInfo(interfaceInfo, 'actions', pkgMap);
|
|
274
|
+
} else {
|
|
275
|
+
// we ignore all other files
|
|
276
|
+
}
|
|
244
277
|
}
|
|
245
278
|
}
|
|
246
279
|
next();
|
package/scripts/npmjs-readme.md
CHANGED
|
@@ -45,7 +45,7 @@ npm i rclnodejs@x.y.z
|
|
|
45
45
|
|
|
46
46
|
| RCLNODEJS Version | Compatible ROS 2 LTS |
|
|
47
47
|
| :----------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
|
|
48
|
-
| latest version (currently [v1.
|
|
48
|
+
| latest version (currently [v1.4.0](https://github.com/RobotWebTools/rclnodejs/tree/1.4.0)) | [Kilted](https://github.com/RobotWebTools/rclnodejs/tree/kilted)<br>[Jazzy](https://github.com/RobotWebTools/rclnodejs/tree/jazzy)<br>[Humble](https://github.com/RobotWebTools/rclnodejs/tree/humble-hawksbill) |
|
|
49
49
|
|
|
50
50
|
## Documentation
|
|
51
51
|
|
package/src/addon.cpp
CHANGED
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
#include "rcl_names_bindings.h"
|
|
31
31
|
#include "rcl_node_bindings.h"
|
|
32
32
|
#include "rcl_publisher_bindings.h"
|
|
33
|
+
#include "rcl_serialization_bindings.h"
|
|
33
34
|
#include "rcl_service_bindings.h"
|
|
34
35
|
#include "rcl_subscription_bindings.h"
|
|
35
36
|
#include "rcl_time_point_bindings.h"
|
|
@@ -88,6 +89,7 @@ Napi::Object InitModule(Napi::Env env, Napi::Object exports) {
|
|
|
88
89
|
rclnodejs::InitEventHandleBindings(env, exports);
|
|
89
90
|
#endif
|
|
90
91
|
rclnodejs::InitLifecycleBindings(env, exports);
|
|
92
|
+
rclnodejs::InitSerializationBindings(env, exports);
|
|
91
93
|
rclnodejs::ShadowNode::Init(env, exports);
|
|
92
94
|
rclnodejs::RclHandle::Init(env, exports);
|
|
93
95
|
|
package/src/macros.h
CHANGED
|
@@ -23,17 +23,33 @@
|
|
|
23
23
|
{ \
|
|
24
24
|
if (lhs op rhs) { \
|
|
25
25
|
rcl_reset_error(); \
|
|
26
|
-
Napi::Error::New(
|
|
26
|
+
Napi::Error::New(env, message) \
|
|
27
27
|
.ThrowAsJavaScriptException(); \
|
|
28
|
+
return env.Undefined(); \
|
|
28
29
|
} \
|
|
29
30
|
}
|
|
30
31
|
|
|
32
|
+
#define CHECK_OP_AND_THROW_ERROR_IF_NOT_TRUE_NO_RETURN(op, lhs, rhs, message) \
|
|
33
|
+
{ \
|
|
34
|
+
if (lhs op rhs) { \
|
|
35
|
+
rcl_reset_error(); \
|
|
36
|
+
Napi::Error::New(env, message) \
|
|
37
|
+
.ThrowAsJavaScriptException(); \
|
|
38
|
+
} \
|
|
39
|
+
}
|
|
40
|
+
|
|
31
41
|
#define THROW_ERROR_IF_NOT_EQUAL(lhs, rhs, message) \
|
|
32
42
|
CHECK_OP_AND_THROW_ERROR_IF_NOT_TRUE(!=, lhs, rhs, message)
|
|
33
43
|
|
|
34
44
|
#define THROW_ERROR_IF_EQUAL(lhs, rhs, message) \
|
|
35
45
|
CHECK_OP_AND_THROW_ERROR_IF_NOT_TRUE(==, lhs, rhs, message)
|
|
36
46
|
|
|
47
|
+
#define THROW_ERROR_IF_NOT_EQUAL_NO_RETURN(lhs, rhs, message) \
|
|
48
|
+
CHECK_OP_AND_THROW_ERROR_IF_NOT_TRUE_NO_RETURN(!=, lhs, rhs, message)
|
|
49
|
+
|
|
50
|
+
#define THROW_ERROR_IF_EQUAL_NO_RETURN(lhs, rhs, message) \
|
|
51
|
+
CHECK_OP_AND_THROW_ERROR_IF_NOT_TRUE_NO_RETURN(==, lhs, rhs, message)
|
|
52
|
+
|
|
37
53
|
#define PACKAGE_NAME "rclnodejs"
|
|
38
54
|
|
|
39
55
|
#ifdef DEBUG_ON
|
|
@@ -75,12 +75,13 @@ Napi::Value ActionCreateClient(const Napi::CallbackInfo& info) {
|
|
|
75
75
|
&action_client_ops),
|
|
76
76
|
RCL_RET_OK, rcl_get_error_string().str);
|
|
77
77
|
auto js_obj = RclHandle::NewInstance(
|
|
78
|
-
env, action_client, node_handle, [node](void* ptr) {
|
|
78
|
+
env, action_client, node_handle, [node, env](void* ptr) {
|
|
79
79
|
rcl_action_client_t* action_client =
|
|
80
80
|
reinterpret_cast<rcl_action_client_t*>(ptr);
|
|
81
81
|
rcl_ret_t ret = rcl_action_client_fini(action_client, node);
|
|
82
82
|
free(ptr);
|
|
83
|
-
|
|
83
|
+
THROW_ERROR_IF_NOT_EQUAL_NO_RETURN(RCL_RET_OK, ret,
|
|
84
|
+
rcl_get_error_string().str);
|
|
84
85
|
});
|
|
85
86
|
|
|
86
87
|
return js_obj;
|
|
@@ -49,12 +49,13 @@ Napi::Value ActionAcceptNewGoal(const Napi::CallbackInfo& info) {
|
|
|
49
49
|
malloc(sizeof(rcl_action_goal_handle_t)));
|
|
50
50
|
*goal_handle = *new_goal;
|
|
51
51
|
auto js_obj =
|
|
52
|
-
RclHandle::NewInstance(env, goal_handle, nullptr, [](void* ptr) {
|
|
52
|
+
RclHandle::NewInstance(env, goal_handle, nullptr, [env](void* ptr) {
|
|
53
53
|
rcl_action_goal_handle_t* goal_handle =
|
|
54
54
|
reinterpret_cast<rcl_action_goal_handle_t*>(ptr);
|
|
55
55
|
rcl_ret_t ret = rcl_action_goal_handle_fini(goal_handle);
|
|
56
56
|
free(ptr);
|
|
57
|
-
|
|
57
|
+
THROW_ERROR_IF_NOT_EQUAL_NO_RETURN(RCL_RET_OK, ret,
|
|
58
|
+
rcl_get_error_string().str);
|
|
58
59
|
});
|
|
59
60
|
|
|
60
61
|
return js_obj;
|
|
@@ -81,12 +81,13 @@ Napi::Value ActionCreateServer(const Napi::CallbackInfo& info) {
|
|
|
81
81
|
action_name.c_str(), &action_server_ops),
|
|
82
82
|
RCL_RET_OK, rcl_get_error_string().str);
|
|
83
83
|
auto js_obj = RclHandle::NewInstance(
|
|
84
|
-
env, action_server, node_handle, [node](void* ptr) {
|
|
84
|
+
env, action_server, node_handle, [node, env](void* ptr) {
|
|
85
85
|
rcl_action_server_t* action_server =
|
|
86
86
|
reinterpret_cast<rcl_action_server_t*>(ptr);
|
|
87
87
|
rcl_ret_t ret = rcl_action_server_fini(action_server, node);
|
|
88
88
|
free(ptr);
|
|
89
|
-
|
|
89
|
+
THROW_ERROR_IF_NOT_EQUAL_NO_RETURN(RCL_RET_OK, ret,
|
|
90
|
+
rcl_get_error_string().str);
|
|
90
91
|
});
|
|
91
92
|
|
|
92
93
|
return js_obj;
|
|
@@ -390,13 +391,14 @@ Napi::Value ActionProcessCancelRequest(const Napi::CallbackInfo& info) {
|
|
|
390
391
|
}
|
|
391
392
|
|
|
392
393
|
*response = cancel_response_ptr->msg;
|
|
393
|
-
auto js_obj =
|
|
394
|
-
|
|
394
|
+
auto js_obj = RclHandle::NewInstance(
|
|
395
|
+
env, cancel_response_ptr, nullptr, [env](void* ptr) {
|
|
395
396
|
rcl_action_cancel_response_t* cancel_response_ptr =
|
|
396
397
|
reinterpret_cast<rcl_action_cancel_response_t*>(ptr);
|
|
397
398
|
rcl_ret_t ret = rcl_action_cancel_response_fini(cancel_response_ptr);
|
|
398
399
|
free(ptr);
|
|
399
|
-
|
|
400
|
+
THROW_ERROR_IF_NOT_EQUAL_NO_RETURN(RCL_RET_OK, ret,
|
|
401
|
+
rcl_get_error_string().str);
|
|
400
402
|
});
|
|
401
403
|
return js_obj;
|
|
402
404
|
}
|
|
@@ -53,12 +53,13 @@ Napi::Value CreateClient(const Napi::CallbackInfo& info) {
|
|
|
53
53
|
rcl_client_init(client, node, ts, service_name.c_str(), &client_ops),
|
|
54
54
|
RCL_RET_OK, rcl_get_error_string().str);
|
|
55
55
|
|
|
56
|
-
auto js_obj =
|
|
57
|
-
|
|
56
|
+
auto js_obj = RclHandle::NewInstance(
|
|
57
|
+
env, client, node_handle, [node, env](void* ptr) {
|
|
58
58
|
rcl_client_t* client = reinterpret_cast<rcl_client_t*>(ptr);
|
|
59
59
|
rcl_ret_t ret = rcl_client_fini(client, node);
|
|
60
60
|
free(ptr);
|
|
61
|
-
|
|
61
|
+
THROW_ERROR_IF_NOT_EQUAL_NO_RETURN(RCL_RET_OK, ret,
|
|
62
|
+
rcl_get_error_string().str);
|
|
62
63
|
});
|
|
63
64
|
|
|
64
65
|
return js_obj;
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
#include <rcl/logging.h>
|
|
18
18
|
#include <rcl/rcl.h>
|
|
19
19
|
|
|
20
|
-
#include <
|
|
20
|
+
#include <rcpputils/scope_exit.hpp>
|
|
21
|
+
// NOLINTNEXTLINE
|
|
21
22
|
#include <string>
|
|
22
23
|
|
|
23
24
|
#include "macros.h"
|
|
@@ -35,6 +36,15 @@ Napi::Value Init(const Napi::CallbackInfo& info) {
|
|
|
35
36
|
rcl_init_options_init(&init_options, allocator),
|
|
36
37
|
rcl_get_error_string().str);
|
|
37
38
|
|
|
39
|
+
RCPPUTILS_SCOPE_EXIT({
|
|
40
|
+
rcl_ret_t fini_ret = rcl_init_options_fini(&init_options);
|
|
41
|
+
if (RCL_RET_OK != fini_ret) {
|
|
42
|
+
Napi::Error::New(env, rcl_get_error_string().str)
|
|
43
|
+
.ThrowAsJavaScriptException();
|
|
44
|
+
rcl_reset_error();
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
38
48
|
// Preprocess Context
|
|
39
49
|
RclHandle* context_handle = RclHandle::Unwrap(info[0].As<Napi::Object>());
|
|
40
50
|
rcl_context_t* context =
|
|
@@ -42,17 +52,20 @@ Napi::Value Init(const Napi::CallbackInfo& info) {
|
|
|
42
52
|
|
|
43
53
|
// Preprocess argc & argv
|
|
44
54
|
Napi::Array jsArgv = info[1].As<Napi::Array>();
|
|
45
|
-
|
|
46
|
-
char** argv =
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
size_t argc = jsArgv.Length();
|
|
56
|
+
char** argv = AbstractArgsFromNapiArray(jsArgv);
|
|
57
|
+
|
|
58
|
+
// Set up the domain id.
|
|
59
|
+
size_t domain_id = RCL_DEFAULT_DOMAIN_ID;
|
|
60
|
+
if (info.Length() > 2 && info[2].IsBigInt()) {
|
|
61
|
+
bool lossless;
|
|
62
|
+
domain_id = info[2].As<Napi::BigInt>().Uint64Value(&lossless);
|
|
63
|
+
}
|
|
64
|
+
rcl_ret_t ret = rcl_init_options_set_domain_id(&init_options, domain_id);
|
|
65
|
+
if (RCL_RET_OK != ret) {
|
|
66
|
+
Napi::Error::New(env, "failed to set domain id to init options")
|
|
67
|
+
.ThrowAsJavaScriptException();
|
|
68
|
+
return env.Undefined();
|
|
56
69
|
}
|
|
57
70
|
|
|
58
71
|
THROW_ERROR_IF_NOT_EQUAL(
|
|
@@ -64,11 +77,7 @@ Napi::Value Init(const Napi::CallbackInfo& info) {
|
|
|
64
77
|
RCL_RET_OK, rcl_logging_configure(&context->global_arguments, &allocator),
|
|
65
78
|
rcl_get_error_string().str);
|
|
66
79
|
|
|
67
|
-
|
|
68
|
-
free(argv[i]);
|
|
69
|
-
}
|
|
70
|
-
free(argv);
|
|
71
|
-
|
|
80
|
+
RCPPUTILS_SCOPE_EXIT({ FreeArgs(argv, argc); });
|
|
72
81
|
return env.Undefined();
|
|
73
82
|
}
|
|
74
83
|
|
|
@@ -111,7 +120,8 @@ Napi::Value CreateContext(const Napi::CallbackInfo& info) {
|
|
|
111
120
|
rcl_context_t* context = reinterpret_cast<rcl_context_t*>(ptr);
|
|
112
121
|
rcl_ret_t ret = DestroyContext(env, context);
|
|
113
122
|
free(ptr);
|
|
114
|
-
|
|
123
|
+
THROW_ERROR_IF_NOT_EQUAL_NO_RETURN(RCL_RET_OK, ret,
|
|
124
|
+
rcl_get_error_string().str);
|
|
115
125
|
});
|
|
116
126
|
|
|
117
127
|
return js_obj;
|
|
@@ -141,7 +151,7 @@ Napi::Value GetDomainId(const Napi::CallbackInfo& info) {
|
|
|
141
151
|
return env.Undefined();
|
|
142
152
|
}
|
|
143
153
|
|
|
144
|
-
return Napi::
|
|
154
|
+
return Napi::BigInt::New(env, domain_id);
|
|
145
155
|
}
|
|
146
156
|
|
|
147
157
|
Napi::Object InitContextBindings(Napi::Env env, Napi::Object exports) {
|
|
@@ -41,11 +41,12 @@ Napi::Value CreateGuardCondition(const Napi::CallbackInfo& info) {
|
|
|
41
41
|
rcl_guard_condition_init(gc, context, gc_options),
|
|
42
42
|
rcl_get_error_string().str);
|
|
43
43
|
|
|
44
|
-
auto handle = RclHandle::NewInstance(env, gc, nullptr, [](void* ptr) {
|
|
44
|
+
auto handle = RclHandle::NewInstance(env, gc, nullptr, [env](void* ptr) {
|
|
45
45
|
rcl_guard_condition_t* gc = reinterpret_cast<rcl_guard_condition_t*>(ptr);
|
|
46
46
|
rcl_ret_t ret = rcl_guard_condition_fini(gc);
|
|
47
47
|
free(ptr);
|
|
48
|
-
|
|
48
|
+
THROW_ERROR_IF_NOT_EQUAL_NO_RETURN(RCL_RET_OK, ret,
|
|
49
|
+
rcl_get_error_string().str);
|
|
49
50
|
});
|
|
50
51
|
|
|
51
52
|
return handle;
|
|
@@ -83,12 +83,13 @@ Napi::Value CreateLifecycleStateMachine(const Napi::CallbackInfo& info) {
|
|
|
83
83
|
rcl_get_error_string().str);
|
|
84
84
|
|
|
85
85
|
auto js_obj = RclHandle::NewInstance(
|
|
86
|
-
env, state_machine, node_handle, [node](void* ptr) {
|
|
86
|
+
env, state_machine, node_handle, [node, env](void* ptr) {
|
|
87
87
|
rcl_lifecycle_state_machine_t* state_machine =
|
|
88
88
|
reinterpret_cast<rcl_lifecycle_state_machine_t*>(ptr);
|
|
89
89
|
rcl_ret_t ret = rcl_lifecycle_state_machine_fini(state_machine, node);
|
|
90
90
|
free(ptr);
|
|
91
|
-
|
|
91
|
+
THROW_ERROR_IF_NOT_EQUAL_NO_RETURN(RCL_RET_OK, ret,
|
|
92
|
+
rcl_get_error_string().str);
|
|
92
93
|
});
|
|
93
94
|
#else
|
|
94
95
|
const rcl_node_options_t* node_options =
|
|
@@ -101,13 +102,14 @@ Napi::Value CreateLifecycleStateMachine(const Napi::CallbackInfo& info) {
|
|
|
101
102
|
rcl_get_error_string().str);
|
|
102
103
|
|
|
103
104
|
auto js_obj = RclHandle::NewInstance(
|
|
104
|
-
env, state_machine, node_handle, [node, node_options](void* ptr) {
|
|
105
|
+
env, state_machine, node_handle, [node, node_options, env](void* ptr) {
|
|
105
106
|
rcl_lifecycle_state_machine_t* state_machine =
|
|
106
107
|
reinterpret_cast<rcl_lifecycle_state_machine_t*>(ptr);
|
|
107
108
|
rcl_ret_t ret = rcl_lifecycle_state_machine_fini(
|
|
108
109
|
state_machine, node, &node_options->allocator);
|
|
109
110
|
free(ptr);
|
|
110
|
-
|
|
111
|
+
THROW_ERROR_IF_NOT_EQUAL_NO_RETURN(RCL_RET_OK, ret,
|
|
112
|
+
rcl_get_error_string().str);
|
|
111
113
|
});
|
|
112
114
|
#endif
|
|
113
115
|
|
|
@@ -372,6 +374,17 @@ Napi::Value IsInitialized(const Napi::CallbackInfo& info) {
|
|
|
372
374
|
return Napi::Boolean::New(env, is_initialized);
|
|
373
375
|
}
|
|
374
376
|
|
|
377
|
+
Napi::Value Print(const Napi::CallbackInfo& info) {
|
|
378
|
+
Napi::Env env = info.Env();
|
|
379
|
+
RclHandle* state_machine_handle =
|
|
380
|
+
RclHandle::Unwrap(info[0].As<Napi::Object>());
|
|
381
|
+
rcl_lifecycle_state_machine_t* state_machine =
|
|
382
|
+
reinterpret_cast<rcl_lifecycle_state_machine_t*>(
|
|
383
|
+
state_machine_handle->ptr());
|
|
384
|
+
rcl_print_state_machine(state_machine);
|
|
385
|
+
return env.Undefined();
|
|
386
|
+
}
|
|
387
|
+
|
|
375
388
|
Napi::Object InitLifecycleBindings(Napi::Env env, Napi::Object exports) {
|
|
376
389
|
exports.Set("createLifecycleStateMachine",
|
|
377
390
|
Napi::Function::New(env, CreateLifecycleStateMachine));
|
|
@@ -396,6 +409,7 @@ Napi::Object InitLifecycleBindings(Napi::Env env, Napi::Object exports) {
|
|
|
396
409
|
exports.Set("getLifecycleShutdownTransitionLabel",
|
|
397
410
|
Napi::Function::New(env, GetLifecycleShutdownTransitionLabel));
|
|
398
411
|
exports.Set("isInitialized", Napi::Function::New(env, IsInitialized));
|
|
412
|
+
exports.Set("print", Napi::Function::New(env, Print));
|
|
399
413
|
return exports;
|
|
400
414
|
}
|
|
401
415
|
|