rclnodejs 0.32.5 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/binding.gyp +17 -2
- package/lib/client.js +2 -3
- package/lib/context.js +8 -0
- package/lib/logging.js +26 -9
- package/lib/node.js +68 -1
- package/lib/publisher.js +8 -0
- package/lib/service.js +9 -2
- package/lib/subscription.js +8 -0
- package/lib/timer.js +32 -0
- package/package.json +4 -4
- package/rostsd_gen/index.js +167 -67
- package/scripts/config.js +1 -0
- package/scripts/npmjs-readme.md +3 -3
- package/src/addon.cpp +54 -53
- package/src/executor.cpp +19 -10
- package/src/{executor.hpp → executor.h} +7 -5
- package/src/handle_manager.cpp +30 -56
- package/src/{handle_manager.hpp → handle_manager.h} +8 -7
- package/src/{macros.hpp → macros.h} +7 -5
- package/src/rcl_action_client_bindings.cpp +231 -0
- package/src/{rcl_action_bindings.hpp → rcl_action_client_bindings.h} +6 -11
- package/src/rcl_action_goal_bindings.cpp +117 -0
- package/src/rcl_action_goal_bindings.h +26 -0
- package/src/rcl_action_server_bindings.cpp +470 -0
- package/src/rcl_action_server_bindings.h +26 -0
- package/src/rcl_bindings.cpp +42 -1979
- package/src/{rcl_bindings.hpp → rcl_bindings.h} +5 -25
- package/src/rcl_client_bindings.cpp +183 -0
- package/src/rcl_client_bindings.h +26 -0
- package/src/rcl_context_bindings.cpp +156 -0
- package/src/rcl_context_bindings.h +26 -0
- package/src/rcl_graph_bindings.cpp +280 -0
- package/src/rcl_graph_bindings.h +26 -0
- package/src/rcl_guard_condition_bindings.cpp +75 -0
- package/src/rcl_guard_condition_bindings.h +26 -0
- package/src/rcl_handle.cpp +41 -57
- package/src/{rcl_handle.hpp → rcl_handle.h} +18 -17
- package/src/rcl_lifecycle_bindings.cpp +135 -114
- package/src/{rcl_lifecycle_bindings.hpp → rcl_lifecycle_bindings.h} +5 -7
- package/src/rcl_logging_bindings.cpp +96 -0
- package/src/rcl_logging_bindings.h +26 -0
- package/src/rcl_names_bindings.cpp +255 -0
- package/src/rcl_names_bindings.h +26 -0
- package/src/rcl_node_bindings.cpp +447 -0
- package/src/rcl_node_bindings.h +26 -0
- package/src/rcl_publisher_bindings.cpp +141 -0
- package/src/rcl_publisher_bindings.h +26 -0
- package/src/rcl_service_bindings.cpp +185 -0
- package/src/rcl_service_bindings.h +26 -0
- package/src/rcl_subscription_bindings.cpp +335 -0
- package/src/rcl_subscription_bindings.h +26 -0
- package/src/rcl_time_point_bindings.cpp +194 -0
- package/src/rcl_time_point_bindings.h +26 -0
- package/src/rcl_timer_bindings.cpp +237 -0
- package/src/rcl_timer_bindings.h +26 -0
- package/src/rcl_utilities.cpp +166 -1
- package/src/{rcl_utilities.hpp → rcl_utilities.h} +21 -3
- package/src/shadow_node.cpp +56 -75
- package/src/{shadow_node.hpp → shadow_node.h} +18 -17
- package/types/context.d.ts +6 -0
- package/types/interfaces.d.ts +4377 -0
- package/types/node.d.ts +53 -0
- package/types/publisher.d.ts +6 -0
- package/types/service.d.ts +6 -0
- package/types/subscription.d.ts +6 -0
- package/types/timer.d.ts +18 -0
- package/src/rcl_action_bindings.cpp +0 -826
package/rostsd_gen/index.js
CHANGED
|
@@ -31,6 +31,8 @@ const fs = require('fs');
|
|
|
31
31
|
const loader = require('../lib/interface_loader.js');
|
|
32
32
|
const pkgFilters = require('../rosidl_gen/filter.js');
|
|
33
33
|
|
|
34
|
+
const descriptorInterfaceNamespace = 'descriptor';
|
|
35
|
+
|
|
34
36
|
async function generateAll() {
|
|
35
37
|
// load pkg and interface info (msgs and srvs)
|
|
36
38
|
const generatedPath = path.join(__dirname, '../generated/');
|
|
@@ -119,47 +121,30 @@ function savePkgInfoAsTSD(pkgInfos, fd) {
|
|
|
119
121
|
for (const subfolder of pkgInfo.subfolders.keys()) {
|
|
120
122
|
fs.writeSync(fd, ` namespace ${subfolder} {\n`);
|
|
121
123
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
if (!isInternalActionSrvInterface(rosInterface)) {
|
|
147
|
-
servicesMap[fullInterfaceName] = fullInterfaceConstructor;
|
|
148
|
-
}
|
|
149
|
-
} else if (isActionInterface(rosInterface)) {
|
|
150
|
-
if (!isValidAction(rosInterface, pkgInfo.subfolders.get(subfolder))) {
|
|
151
|
-
let type = rosInterface.type();
|
|
152
|
-
console.log(
|
|
153
|
-
`Incomplete action: ${type.pkgName}.${type.subFolder}.${type.interfaceName}.`
|
|
154
|
-
);
|
|
155
|
-
continue;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// create action interface
|
|
159
|
-
saveActionAsTSD(rosInterface, fd);
|
|
160
|
-
actionsMap[fullInterfaceName] = fullInterfaceConstructor;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
124
|
+
// generate real msg/srv/action interfaces
|
|
125
|
+
generateRosMsgInterfaces(
|
|
126
|
+
pkgInfo,
|
|
127
|
+
subfolder,
|
|
128
|
+
messagesMap,
|
|
129
|
+
servicesMap,
|
|
130
|
+
actionsMap,
|
|
131
|
+
fd
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
// generate descriptor msg/srv/action interfaces
|
|
135
|
+
fs.writeSync(fd, ` namespace ${descriptorInterfaceNamespace} {\n`);
|
|
136
|
+
const willGenerateDescriptorInterface = true;
|
|
137
|
+
generateRosMsgInterfaces(
|
|
138
|
+
pkgInfo,
|
|
139
|
+
subfolder,
|
|
140
|
+
messagesMap,
|
|
141
|
+
servicesMap,
|
|
142
|
+
actionsMap,
|
|
143
|
+
fd,
|
|
144
|
+
willGenerateDescriptorInterface
|
|
145
|
+
);
|
|
146
|
+
// close namespace descriptor declare
|
|
147
|
+
fs.writeSync(fd, ' }\n');
|
|
163
148
|
|
|
164
149
|
// close namespace declare
|
|
165
150
|
fs.writeSync(fd, ' }\n');
|
|
@@ -238,16 +223,96 @@ function savePkgInfoAsTSD(pkgInfos, fd) {
|
|
|
238
223
|
fs.writeSync(fd, '}\n');
|
|
239
224
|
}
|
|
240
225
|
|
|
241
|
-
function
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
226
|
+
function generateRosMsgInterfaces(
|
|
227
|
+
pkgInfo,
|
|
228
|
+
subfolder,
|
|
229
|
+
messagesMap,
|
|
230
|
+
servicesMap,
|
|
231
|
+
actionsMap,
|
|
232
|
+
fd,
|
|
233
|
+
willGenerateDescriptorInterface = false
|
|
234
|
+
) {
|
|
235
|
+
const descriptorNamespaceName = willGenerateDescriptorInterface
|
|
236
|
+
? `${descriptorInterfaceNamespace}/`
|
|
237
|
+
: '';
|
|
238
|
+
const descriptorNamespacePath = willGenerateDescriptorInterface
|
|
239
|
+
? `${descriptorInterfaceNamespace}.`
|
|
240
|
+
: '';
|
|
241
|
+
for (const rosInterface of pkgInfo.subfolders.get(subfolder)) {
|
|
242
|
+
const type = rosInterface.type();
|
|
243
|
+
const fullInterfaceName = `${type.pkgName}/${type.subFolder}/${descriptorNamespaceName}${type.interfaceName}`;
|
|
244
|
+
const fullInterfacePath = `${type.pkgName}.${type.subFolder}.${descriptorNamespacePath}${type.interfaceName}`;
|
|
245
|
+
const fullInterfaceConstructor = fullInterfacePath + 'Constructor';
|
|
246
|
+
|
|
247
|
+
const indentStartLevel = willGenerateDescriptorInterface ? 4 : 3;
|
|
248
|
+
if (isMsgInterface(rosInterface)) {
|
|
249
|
+
// create message interface
|
|
250
|
+
saveMsgAsTSD(
|
|
251
|
+
rosInterface,
|
|
252
|
+
fd,
|
|
253
|
+
indentStartLevel,
|
|
254
|
+
willGenerateDescriptorInterface
|
|
255
|
+
);
|
|
256
|
+
saveMsgConstructorAsTSD(rosInterface, fd, indentStartLevel);
|
|
257
|
+
messagesMap[fullInterfaceName] = fullInterfacePath;
|
|
258
|
+
} else if (isSrvInterface(rosInterface)) {
|
|
259
|
+
if (!isValidService(rosInterface, pkgInfo.subfolders.get(subfolder))) {
|
|
260
|
+
let type = rosInterface.type();
|
|
261
|
+
console.log(
|
|
262
|
+
`Incomplete service: ${type.pkgName}.${type.subFolder}.${type.interfaceName}.`
|
|
263
|
+
);
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// create service interface
|
|
268
|
+
saveSrvAsTSD(rosInterface, fd, indentStartLevel);
|
|
269
|
+
if (!isInternalActionSrvInterface(rosInterface)) {
|
|
270
|
+
servicesMap[fullInterfaceName] = fullInterfaceConstructor;
|
|
271
|
+
}
|
|
272
|
+
} else if (isActionInterface(rosInterface)) {
|
|
273
|
+
if (!isValidAction(rosInterface, pkgInfo.subfolders.get(subfolder))) {
|
|
274
|
+
let type = rosInterface.type();
|
|
275
|
+
console.log(
|
|
276
|
+
`Incomplete action: ${type.pkgName}.${type.subFolder}.${type.interfaceName}.`
|
|
277
|
+
);
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// create action interface
|
|
282
|
+
saveActionAsTSD(rosInterface, fd, indentStartLevel);
|
|
283
|
+
actionsMap[fullInterfaceName] = fullInterfaceConstructor;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function saveMsgAsTSD(
|
|
289
|
+
rosMsgInterface,
|
|
290
|
+
fd,
|
|
291
|
+
indentLevel = 3,
|
|
292
|
+
willGenerateDescriptorInterface = false
|
|
293
|
+
) {
|
|
294
|
+
const outerIndentSpacing = getIndentSpacing(indentLevel);
|
|
295
|
+
const tmpl = indentString(
|
|
296
|
+
`export interface ${rosMsgInterface.type().interfaceName} {\n`,
|
|
297
|
+
outerIndentSpacing
|
|
245
298
|
);
|
|
299
|
+
fs.writeSync(fd, tmpl);
|
|
246
300
|
const useSamePkg =
|
|
247
301
|
isInternalActionMsgInterface(rosMsgInterface) ||
|
|
248
302
|
isInternalServiceEventMsgInterface(rosMsgInterface);
|
|
249
|
-
|
|
250
|
-
|
|
303
|
+
const innerIndentLevel = indentLevel + 1;
|
|
304
|
+
const innerIndentSpacing = getIndentSpacing(innerIndentLevel);
|
|
305
|
+
saveMsgFieldsAsTSD(
|
|
306
|
+
rosMsgInterface,
|
|
307
|
+
fd,
|
|
308
|
+
innerIndentSpacing,
|
|
309
|
+
';',
|
|
310
|
+
'',
|
|
311
|
+
useSamePkg,
|
|
312
|
+
willGenerateDescriptorInterface
|
|
313
|
+
);
|
|
314
|
+
const tmplEnd = indentString('}\n', outerIndentSpacing);
|
|
315
|
+
fs.writeSync(fd, tmplEnd);
|
|
251
316
|
}
|
|
252
317
|
|
|
253
318
|
/**
|
|
@@ -261,6 +326,7 @@ function saveMsgAsTSD(rosMsgInterface, fd) {
|
|
|
261
326
|
* @param {string} typePrefix The prefix to put before the type name for
|
|
262
327
|
* non-primitive types
|
|
263
328
|
* @param {boolean} useSamePackageSubFolder Indicates if the sub folder name should be taken from the message
|
|
329
|
+
* @param {boolean} willGenerateDescriptorInterface Indicates if descriptor interface is being generated
|
|
264
330
|
* when the field type comes from the same package. This is needed for action interfaces. Defaults to false.
|
|
265
331
|
* @returns {undefined}
|
|
266
332
|
*/
|
|
@@ -270,7 +336,8 @@ function saveMsgFieldsAsTSD(
|
|
|
270
336
|
indent = 0,
|
|
271
337
|
lineEnd = ',',
|
|
272
338
|
typePrefix = '',
|
|
273
|
-
useSamePackageSubFolder = false
|
|
339
|
+
useSamePackageSubFolder = false,
|
|
340
|
+
willGenerateDescriptorInterface = false
|
|
274
341
|
) {
|
|
275
342
|
let type = rosMsgInterface.type();
|
|
276
343
|
let fields = rosMsgInterface.ROSMessageDef.fields;
|
|
@@ -280,49 +347,62 @@ function saveMsgFieldsAsTSD(
|
|
|
280
347
|
useSamePackageSubFolder && field.type.pkgName === type.pkgName
|
|
281
348
|
? type.subFolder
|
|
282
349
|
: 'msg';
|
|
283
|
-
let fieldType = fieldType2JSName(
|
|
350
|
+
let fieldType = fieldType2JSName(
|
|
351
|
+
field,
|
|
352
|
+
subFolder,
|
|
353
|
+
willGenerateDescriptorInterface
|
|
354
|
+
);
|
|
284
355
|
let tp = field.type.isPrimitiveType ? '' : typePrefix;
|
|
285
356
|
if (typePrefix === 'rclnodejs.') {
|
|
286
357
|
fieldType = 'any';
|
|
287
358
|
tp = '';
|
|
288
359
|
}
|
|
289
360
|
|
|
290
|
-
|
|
291
|
-
fs.writeSync(fd, tmpl);
|
|
361
|
+
let arrayString = '';
|
|
292
362
|
if (field.type.isArray) {
|
|
293
|
-
|
|
363
|
+
arrayString = '[]';
|
|
364
|
+
|
|
365
|
+
if (field.type.isFixedSizeArray && willGenerateDescriptorInterface) {
|
|
366
|
+
arrayString = `[${field.type.arraySize}]`;
|
|
367
|
+
}
|
|
294
368
|
|
|
295
|
-
if (fieldType === 'number') {
|
|
369
|
+
if (fieldType === 'number' && !willGenerateDescriptorInterface) {
|
|
296
370
|
// for number[] include alternate typed-array types, e.g., number[] | uint8[]
|
|
297
371
|
let jsTypedArrayName = fieldTypeArray2JSTypedArrayName(field.type.type);
|
|
298
372
|
|
|
299
373
|
if (jsTypedArrayName) {
|
|
300
|
-
|
|
374
|
+
arrayString += ` | ${jsTypedArrayName}`;
|
|
301
375
|
}
|
|
302
376
|
}
|
|
303
377
|
}
|
|
378
|
+
const fieldString = willGenerateDescriptorInterface
|
|
379
|
+
? `${field.name}: '${tp}${fieldType}${arrayString}'`
|
|
380
|
+
: `${field.name}: ${tp}${fieldType}${arrayString}`;
|
|
381
|
+
const tmpl = indentString(fieldString, indent);
|
|
382
|
+
fs.writeSync(fd, tmpl);
|
|
304
383
|
|
|
305
384
|
fs.writeSync(fd, lineEnd);
|
|
306
385
|
fs.writeSync(fd, '\n');
|
|
307
386
|
}
|
|
308
387
|
}
|
|
309
388
|
|
|
310
|
-
function saveMsgConstructorAsTSD(rosMsgInterface, fd) {
|
|
389
|
+
function saveMsgConstructorAsTSD(rosMsgInterface, fd, indentLevel = 3) {
|
|
311
390
|
const type = rosMsgInterface.type();
|
|
312
391
|
const msgName = type.interfaceName;
|
|
313
|
-
|
|
314
|
-
fs.writeSync(fd, ` export interface ${msgName}Constructor {\n`);
|
|
392
|
+
let interfaceTmpl = [`export interface ${msgName}Constructor {`];
|
|
315
393
|
|
|
316
394
|
for (const constant of rosMsgInterface.ROSMessageDef.constants) {
|
|
317
395
|
const constantType = primitiveType2JSName(constant.type);
|
|
318
|
-
|
|
396
|
+
interfaceTmpl.push(` readonly ${constant.name}: ${constantType};`);
|
|
319
397
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
398
|
+
interfaceTmpl.push(` new(other?: ${msgName}): ${msgName};`);
|
|
399
|
+
interfaceTmpl.push('}');
|
|
400
|
+
interfaceTmpl.push('');
|
|
401
|
+
const indentSpacing = getIndentSpacing(indentLevel);
|
|
402
|
+
fs.writeSync(fd, indentLines(interfaceTmpl, indentSpacing).join('\n'));
|
|
323
403
|
}
|
|
324
404
|
|
|
325
|
-
function saveSrvAsTSD(rosSrvInterface, fd) {
|
|
405
|
+
function saveSrvAsTSD(rosSrvInterface, fd, indentLevel = 3) {
|
|
326
406
|
const serviceName = rosSrvInterface.type().interfaceName;
|
|
327
407
|
|
|
328
408
|
const interfaceTemplate = [
|
|
@@ -332,11 +412,11 @@ function saveSrvAsTSD(rosSrvInterface, fd) {
|
|
|
332
412
|
'}',
|
|
333
413
|
'',
|
|
334
414
|
];
|
|
335
|
-
|
|
336
|
-
fs.writeSync(fd, indentLines(interfaceTemplate,
|
|
415
|
+
const indentSpacing = getIndentSpacing(indentLevel);
|
|
416
|
+
fs.writeSync(fd, indentLines(interfaceTemplate, indentSpacing).join('\n'));
|
|
337
417
|
}
|
|
338
418
|
|
|
339
|
-
function saveActionAsTSD(rosActionInterface, fd) {
|
|
419
|
+
function saveActionAsTSD(rosActionInterface, fd, indentLevel = 3) {
|
|
340
420
|
const actionName = rosActionInterface.type().interfaceName;
|
|
341
421
|
|
|
342
422
|
const interfaceTemplate = [
|
|
@@ -347,8 +427,19 @@ function saveActionAsTSD(rosActionInterface, fd) {
|
|
|
347
427
|
'}',
|
|
348
428
|
'',
|
|
349
429
|
];
|
|
430
|
+
const indentSpacing = getIndentSpacing(indentLevel);
|
|
431
|
+
fs.writeSync(fd, indentLines(interfaceTemplate, indentSpacing).join('\n'));
|
|
432
|
+
}
|
|
350
433
|
|
|
351
|
-
|
|
434
|
+
/**
|
|
435
|
+
* Get number of indent spaces for given level
|
|
436
|
+
*
|
|
437
|
+
* @param {*} indentLevel Indention level
|
|
438
|
+
* @param {*} spacesPerLevel Number of spaces per level
|
|
439
|
+
* @returns Total number of space
|
|
440
|
+
*/
|
|
441
|
+
function getIndentSpacing(indentLevel, spacesPerLevel = 2) {
|
|
442
|
+
return indentLevel * spacesPerLevel;
|
|
352
443
|
}
|
|
353
444
|
|
|
354
445
|
function isMsgInterface(rosInterface) {
|
|
@@ -451,7 +542,16 @@ function isValidAction(rosActionInterface, infos) {
|
|
|
451
542
|
return matches === SUCCESS_MATCH_COUNT;
|
|
452
543
|
}
|
|
453
544
|
|
|
454
|
-
function fieldType2JSName(
|
|
545
|
+
function fieldType2JSName(
|
|
546
|
+
fieldInfo,
|
|
547
|
+
subFolder = 'msg',
|
|
548
|
+
willGenerateDescriptorInterface = false
|
|
549
|
+
) {
|
|
550
|
+
if (willGenerateDescriptorInterface) {
|
|
551
|
+
return fieldInfo.type.isPrimitiveType
|
|
552
|
+
? `${fieldInfo.type.type}`
|
|
553
|
+
: `${fieldInfo.type.pkgName}/${subFolder}/${fieldInfo.type.type}`;
|
|
554
|
+
}
|
|
455
555
|
return fieldInfo.type.isPrimitiveType
|
|
456
556
|
? primitiveType2JSName(fieldInfo.type.type)
|
|
457
557
|
: `${fieldInfo.type.pkgName}.${subFolder}.${fieldInfo.type.type}`;
|
package/scripts/config.js
CHANGED
package/scripts/npmjs-readme.md
CHANGED
|
@@ -43,9 +43,9 @@ npm i rclnodejs@x.y.z
|
|
|
43
43
|
|
|
44
44
|
#### RCLNODEJS - ROS 2 Version Compatibility
|
|
45
45
|
|
|
46
|
-
|
|
|
47
|
-
|
|
|
48
|
-
| latest version (currently [
|
|
46
|
+
| RCLNODEJS Version | Compatible ROS 2 LTS |
|
|
47
|
+
| :----------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------: |
|
|
48
|
+
| latest version (currently [v1.0.0](https://github.com/RobotWebTools/rclnodejs/tree/1.0.0)) | [Humble](https://github.com/RobotWebTools/rclnodejs/tree/humble-hawksbill)<br>[Jazzy](https://github.com/RobotWebTools/rclnodejs/tree/jazzy) |
|
|
49
49
|
|
|
50
50
|
## Documentation
|
|
51
51
|
|
package/src/addon.cpp
CHANGED
|
@@ -12,29 +12,39 @@
|
|
|
12
12
|
// See the License for the specific language governing permissions and
|
|
13
13
|
// limitations under the License.
|
|
14
14
|
|
|
15
|
-
#include <
|
|
15
|
+
#include <node_api.h>
|
|
16
|
+
#include <rcutils/logging.h>
|
|
16
17
|
|
|
17
|
-
#include "macros.
|
|
18
|
-
#include "
|
|
19
|
-
#include "
|
|
20
|
-
#include "
|
|
21
|
-
#include "
|
|
22
|
-
#include "
|
|
23
|
-
#include "
|
|
24
|
-
#include "
|
|
18
|
+
#include "macros.h"
|
|
19
|
+
#include "rcl_action_client_bindings.h"
|
|
20
|
+
#include "rcl_action_goal_bindings.h"
|
|
21
|
+
#include "rcl_action_server_bindings.h"
|
|
22
|
+
#include "rcl_bindings.h"
|
|
23
|
+
#include "rcl_client_bindings.h"
|
|
24
|
+
#include "rcl_context_bindings.h"
|
|
25
|
+
#include "rcl_graph_bindings.h"
|
|
26
|
+
#include "rcl_guard_condition_bindings.h"
|
|
27
|
+
#include "rcl_handle.h"
|
|
28
|
+
#include "rcl_lifecycle_bindings.h"
|
|
29
|
+
#include "rcl_logging_bindings.h"
|
|
30
|
+
#include "rcl_names_bindings.h"
|
|
31
|
+
#include "rcl_node_bindings.h"
|
|
32
|
+
#include "rcl_publisher_bindings.h"
|
|
33
|
+
#include "rcl_service_bindings.h"
|
|
34
|
+
#include "rcl_subscription_bindings.h"
|
|
35
|
+
#include "rcl_time_point_bindings.h"
|
|
36
|
+
#include "rcl_timer_bindings.h"
|
|
37
|
+
#include "rcl_utilities.h"
|
|
38
|
+
#include "shadow_node.h"
|
|
25
39
|
|
|
26
|
-
bool IsRunningInElectronRenderer() {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
.ToLocalChecked();
|
|
32
|
-
auto process_type =
|
|
33
|
-
Nan::Get(process, Nan::New("type").ToLocalChecked()).ToLocalChecked();
|
|
34
|
-
return process_type->StrictEquals(Nan::New("renderer").ToLocalChecked());
|
|
40
|
+
bool IsRunningInElectronRenderer(const Napi::Env& env) {
|
|
41
|
+
Napi::Object global = env.Global();
|
|
42
|
+
Napi::Object process = global.Get("process").As<Napi::Object>();
|
|
43
|
+
Napi::Value processType = process.Get("type");
|
|
44
|
+
return processType.StrictEquals(Napi::String::New(env, "renderer"));
|
|
35
45
|
}
|
|
36
46
|
|
|
37
|
-
|
|
47
|
+
Napi::Object InitModule(Napi::Env env, Napi::Object exports) {
|
|
38
48
|
// workaround process name mangling by chromium
|
|
39
49
|
//
|
|
40
50
|
// rcl logging uses `program_invocation_name` to determine the log file,
|
|
@@ -43,7 +53,7 @@ void InitModule(v8::Local<v8::Object> exports) {
|
|
|
43
53
|
// occurence of ' -' with the null terminator. see:
|
|
44
54
|
// https://unix.stackexchange.com/questions/432419/unexpected-non-null-encoding-of-proc-pid-cmdline
|
|
45
55
|
#if defined(__linux__) && defined(__GLIBC__)
|
|
46
|
-
if (IsRunningInElectronRenderer()) {
|
|
56
|
+
if (IsRunningInElectronRenderer(env)) {
|
|
47
57
|
auto prog_name = program_invocation_name;
|
|
48
58
|
auto end = strstr(prog_name, " -");
|
|
49
59
|
assert(end);
|
|
@@ -51,44 +61,35 @@ void InitModule(v8::Local<v8::Object> exports) {
|
|
|
51
61
|
}
|
|
52
62
|
#endif
|
|
53
63
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
Nan::Set(
|
|
76
|
-
exports,
|
|
77
|
-
Nan::New(rclnodejs::lifecycle_binding_methods[i].name).ToLocalChecked(),
|
|
78
|
-
Nan::New<v8::FunctionTemplate>(
|
|
79
|
-
rclnodejs::lifecycle_binding_methods[i].function)
|
|
80
|
-
->GetFunction(context)
|
|
81
|
-
.ToLocalChecked());
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
rclnodejs::ShadowNode::Init(exports);
|
|
85
|
-
rclnodejs::RclHandle::Init(exports);
|
|
64
|
+
rclnodejs::StoreEnv(env);
|
|
65
|
+
// Init the C++ bindings.
|
|
66
|
+
rclnodejs::InitBindings(env, exports);
|
|
67
|
+
rclnodejs::InitActionClientBindings(env, exports);
|
|
68
|
+
rclnodejs::InitActionGoalBindings(env, exports);
|
|
69
|
+
rclnodejs::InitActionServerBindings(env, exports);
|
|
70
|
+
rclnodejs::InitClientBindings(env, exports);
|
|
71
|
+
rclnodejs::InitContextBindings(env, exports);
|
|
72
|
+
rclnodejs::InitGraphBindings(env, exports);
|
|
73
|
+
rclnodejs::InitGuardConditionBindings(env, exports);
|
|
74
|
+
rclnodejs::InitLoggingBindings(env, exports);
|
|
75
|
+
rclnodejs::InitNamesBindings(env, exports);
|
|
76
|
+
rclnodejs::InitNodeBindings(env, exports);
|
|
77
|
+
rclnodejs::InitPublisherBindings(env, exports);
|
|
78
|
+
rclnodejs::InitServiceBindings(env, exports);
|
|
79
|
+
rclnodejs::InitSubscriptionBindings(env, exports);
|
|
80
|
+
rclnodejs::InitTimePointBindings(env, exports);
|
|
81
|
+
rclnodejs::InitTimerBindings(env, exports);
|
|
82
|
+
rclnodejs::InitLifecycleBindings(env, exports);
|
|
83
|
+
rclnodejs::ShadowNode::Init(env, exports);
|
|
84
|
+
rclnodejs::RclHandle::Init(env, exports);
|
|
86
85
|
|
|
87
86
|
#ifdef DEBUG_ON
|
|
88
87
|
int result = rcutils_logging_set_logger_level(PACKAGE_NAME,
|
|
89
88
|
RCUTILS_LOG_SEVERITY_DEBUG);
|
|
90
89
|
RCUTILS_UNUSED(result);
|
|
91
90
|
#endif
|
|
91
|
+
|
|
92
|
+
return exports;
|
|
92
93
|
}
|
|
93
94
|
|
|
94
|
-
|
|
95
|
+
NODE_API_MODULE(rclnodejs, InitModule)
|
package/src/executor.cpp
CHANGED
|
@@ -12,16 +12,16 @@
|
|
|
12
12
|
// See the License for the specific language governing permissions and
|
|
13
13
|
// limitations under the License.
|
|
14
14
|
|
|
15
|
-
#include "executor.
|
|
15
|
+
#include "executor.h"
|
|
16
16
|
|
|
17
17
|
#include <rcl/error_handling.h>
|
|
18
18
|
|
|
19
19
|
#include <stdexcept>
|
|
20
20
|
#include <string>
|
|
21
21
|
|
|
22
|
-
#include "handle_manager.
|
|
23
|
-
#include "macros.
|
|
24
|
-
#include "rcl_bindings.
|
|
22
|
+
#include "handle_manager.h"
|
|
23
|
+
#include "macros.h"
|
|
24
|
+
#include "rcl_bindings.h"
|
|
25
25
|
|
|
26
26
|
#ifdef WIN32
|
|
27
27
|
#define UNUSED
|
|
@@ -41,12 +41,14 @@ struct RclResult {
|
|
|
41
41
|
std::string error_msg;
|
|
42
42
|
};
|
|
43
43
|
|
|
44
|
-
Executor::Executor(HandleManager* handle_manager,
|
|
44
|
+
Executor::Executor(Napi::Env env, HandleManager* handle_manager,
|
|
45
|
+
Delegate* delegate)
|
|
45
46
|
: async_(nullptr),
|
|
46
47
|
main_thread_(uv_thread_self()),
|
|
47
48
|
handle_manager_(handle_manager),
|
|
48
49
|
delegate_(delegate),
|
|
49
|
-
context_(nullptr)
|
|
50
|
+
context_(nullptr),
|
|
51
|
+
env_(env) {
|
|
50
52
|
running_.store(false);
|
|
51
53
|
}
|
|
52
54
|
|
|
@@ -74,12 +76,19 @@ void Executor::SpinOnce(rcl_context_t* context, int32_t time_out) {
|
|
|
74
76
|
rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set();
|
|
75
77
|
rcl_ret_t ret = rcl_wait_set_init(&wait_set, 0, 0, 0, 0, 0, 0, context,
|
|
76
78
|
rcl_get_default_allocator());
|
|
77
|
-
if (ret != RCL_RET_OK)
|
|
79
|
+
if (ret != RCL_RET_OK) {
|
|
80
|
+
Napi::Error::New(env_, rcl_get_error_string().str)
|
|
81
|
+
.ThrowAsJavaScriptException();
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
78
84
|
|
|
79
85
|
RclResult wait_result = WaitForReadyCallbacks(&wait_set, time_out);
|
|
80
86
|
|
|
81
|
-
if (wait_result.ret != RCL_RET_OK)
|
|
82
|
-
|
|
87
|
+
if (wait_result.ret != RCL_RET_OK) {
|
|
88
|
+
Napi::Error::New(env_, wait_result.error_msg.c_str())
|
|
89
|
+
.ThrowAsJavaScriptException();
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
83
92
|
|
|
84
93
|
if (handle_manager_->ready_handles_count() > 0) ExecuteReadyHandles();
|
|
85
94
|
|
|
@@ -87,7 +96,7 @@ void Executor::SpinOnce(rcl_context_t* context, int32_t time_out) {
|
|
|
87
96
|
std::string error_message =
|
|
88
97
|
std::string("Failed to destroy guard waitset:") +
|
|
89
98
|
std::string(rcl_get_error_string().str);
|
|
90
|
-
|
|
99
|
+
Napi::Error::New(env_, error_message.c_str()).ThrowAsJavaScriptException();
|
|
91
100
|
}
|
|
92
101
|
}
|
|
93
102
|
|
|
@@ -12,9 +12,10 @@
|
|
|
12
12
|
// See the License for the specific language governing permissions and
|
|
13
13
|
// limitations under the License.
|
|
14
14
|
|
|
15
|
-
#ifndef
|
|
16
|
-
#define
|
|
15
|
+
#ifndef SRC_EXECUTOR_H_
|
|
16
|
+
#define SRC_EXECUTOR_H_
|
|
17
17
|
|
|
18
|
+
#include <napi.h>
|
|
18
19
|
#include <rcl/wait.h>
|
|
19
20
|
#include <uv.h>
|
|
20
21
|
|
|
@@ -22,7 +23,7 @@
|
|
|
22
23
|
#include <exception>
|
|
23
24
|
#include <vector>
|
|
24
25
|
|
|
25
|
-
#include "rcl_handle.
|
|
26
|
+
#include "rcl_handle.h"
|
|
26
27
|
|
|
27
28
|
namespace rclnodejs {
|
|
28
29
|
|
|
@@ -37,7 +38,7 @@ class Executor {
|
|
|
37
38
|
virtual void CatchException(std::exception_ptr e_ptr) = 0;
|
|
38
39
|
};
|
|
39
40
|
|
|
40
|
-
Executor(HandleManager* handle_manager, Delegate* delegate);
|
|
41
|
+
Executor(Napi::Env env, HandleManager* handle_manager, Delegate* delegate);
|
|
41
42
|
~Executor();
|
|
42
43
|
|
|
43
44
|
void Start(rcl_context_t* context, int32_t time_out);
|
|
@@ -68,10 +69,11 @@ class Executor {
|
|
|
68
69
|
Delegate* delegate_;
|
|
69
70
|
rcl_context_t* context_;
|
|
70
71
|
int32_t time_out_;
|
|
72
|
+
Napi::Env env_;
|
|
71
73
|
|
|
72
74
|
std::atomic_bool running_;
|
|
73
75
|
};
|
|
74
76
|
|
|
75
77
|
} // namespace rclnodejs
|
|
76
78
|
|
|
77
|
-
#endif //
|
|
79
|
+
#endif // SRC_EXECUTOR_H_
|