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.
Files changed (68) hide show
  1. package/README.md +3 -3
  2. package/binding.gyp +17 -2
  3. package/lib/client.js +2 -3
  4. package/lib/context.js +8 -0
  5. package/lib/logging.js +26 -9
  6. package/lib/node.js +68 -1
  7. package/lib/publisher.js +8 -0
  8. package/lib/service.js +9 -2
  9. package/lib/subscription.js +8 -0
  10. package/lib/timer.js +32 -0
  11. package/package.json +4 -4
  12. package/rostsd_gen/index.js +167 -67
  13. package/scripts/config.js +1 -0
  14. package/scripts/npmjs-readme.md +3 -3
  15. package/src/addon.cpp +54 -53
  16. package/src/executor.cpp +19 -10
  17. package/src/{executor.hpp → executor.h} +7 -5
  18. package/src/handle_manager.cpp +30 -56
  19. package/src/{handle_manager.hpp → handle_manager.h} +8 -7
  20. package/src/{macros.hpp → macros.h} +7 -5
  21. package/src/rcl_action_client_bindings.cpp +231 -0
  22. package/src/{rcl_action_bindings.hpp → rcl_action_client_bindings.h} +6 -11
  23. package/src/rcl_action_goal_bindings.cpp +117 -0
  24. package/src/rcl_action_goal_bindings.h +26 -0
  25. package/src/rcl_action_server_bindings.cpp +470 -0
  26. package/src/rcl_action_server_bindings.h +26 -0
  27. package/src/rcl_bindings.cpp +42 -1979
  28. package/src/{rcl_bindings.hpp → rcl_bindings.h} +5 -25
  29. package/src/rcl_client_bindings.cpp +183 -0
  30. package/src/rcl_client_bindings.h +26 -0
  31. package/src/rcl_context_bindings.cpp +156 -0
  32. package/src/rcl_context_bindings.h +26 -0
  33. package/src/rcl_graph_bindings.cpp +280 -0
  34. package/src/rcl_graph_bindings.h +26 -0
  35. package/src/rcl_guard_condition_bindings.cpp +75 -0
  36. package/src/rcl_guard_condition_bindings.h +26 -0
  37. package/src/rcl_handle.cpp +41 -57
  38. package/src/{rcl_handle.hpp → rcl_handle.h} +18 -17
  39. package/src/rcl_lifecycle_bindings.cpp +135 -114
  40. package/src/{rcl_lifecycle_bindings.hpp → rcl_lifecycle_bindings.h} +5 -7
  41. package/src/rcl_logging_bindings.cpp +96 -0
  42. package/src/rcl_logging_bindings.h +26 -0
  43. package/src/rcl_names_bindings.cpp +255 -0
  44. package/src/rcl_names_bindings.h +26 -0
  45. package/src/rcl_node_bindings.cpp +447 -0
  46. package/src/rcl_node_bindings.h +26 -0
  47. package/src/rcl_publisher_bindings.cpp +141 -0
  48. package/src/rcl_publisher_bindings.h +26 -0
  49. package/src/rcl_service_bindings.cpp +185 -0
  50. package/src/rcl_service_bindings.h +26 -0
  51. package/src/rcl_subscription_bindings.cpp +335 -0
  52. package/src/rcl_subscription_bindings.h +26 -0
  53. package/src/rcl_time_point_bindings.cpp +194 -0
  54. package/src/rcl_time_point_bindings.h +26 -0
  55. package/src/rcl_timer_bindings.cpp +237 -0
  56. package/src/rcl_timer_bindings.h +26 -0
  57. package/src/rcl_utilities.cpp +166 -1
  58. package/src/{rcl_utilities.hpp → rcl_utilities.h} +21 -3
  59. package/src/shadow_node.cpp +56 -75
  60. package/src/{shadow_node.hpp → shadow_node.h} +18 -17
  61. package/types/context.d.ts +6 -0
  62. package/types/interfaces.d.ts +4377 -0
  63. package/types/node.d.ts +53 -0
  64. package/types/publisher.d.ts +6 -0
  65. package/types/service.d.ts +6 -0
  66. package/types/subscription.d.ts +6 -0
  67. package/types/timer.d.ts +18 -0
  68. package/src/rcl_action_bindings.cpp +0 -826
@@ -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
- for (const rosInterface of pkgInfo.subfolders.get(subfolder)) {
123
- const type = rosInterface.type();
124
- const fullInterfaceName = `${type.pkgName}/${type.subFolder}/${type.interfaceName}`;
125
- const fullInterfacePath = `${type.pkgName}.${type.subFolder}.${type.interfaceName}`;
126
- const fullInterfaceConstructor = fullInterfacePath + 'Constructor';
127
-
128
- if (isMsgInterface(rosInterface)) {
129
- // create message interface
130
- saveMsgAsTSD(rosInterface, fd);
131
- saveMsgConstructorAsTSD(rosInterface, fd);
132
- messagesMap[fullInterfaceName] = fullInterfacePath;
133
- } else if (isSrvInterface(rosInterface)) {
134
- if (
135
- !isValidService(rosInterface, pkgInfo.subfolders.get(subfolder))
136
- ) {
137
- let type = rosInterface.type();
138
- console.log(
139
- `Incomplete service: ${type.pkgName}.${type.subFolder}.${type.interfaceName}.`
140
- );
141
- continue;
142
- }
143
-
144
- // create service interface
145
- saveSrvAsTSD(rosInterface, fd);
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 saveMsgAsTSD(rosMsgInterface, fd) {
242
- fs.writeSync(
243
- fd,
244
- ` export interface ${rosMsgInterface.type().interfaceName} {\n`
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
- saveMsgFieldsAsTSD(rosMsgInterface, fd, 8, ';', '', useSamePkg);
250
- fs.writeSync(fd, ' }\n');
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(field, subFolder);
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
- const tmpl = indentString(`${field.name}: ${tp}${fieldType}`, indent);
291
- fs.writeSync(fd, tmpl);
361
+ let arrayString = '';
292
362
  if (field.type.isArray) {
293
- fs.writeSync(fd, '[]');
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
- fs.writeSync(fd, ` | ${jsTypedArrayName}`);
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
- fs.writeSync(fd, ` readonly ${constant.name}: ${constantType};\n`);
396
+ interfaceTmpl.push(` readonly ${constant.name}: ${constantType};`);
319
397
  }
320
-
321
- fs.writeSync(fd, ` new(other?: ${msgName}): ${msgName};\n`);
322
- fs.writeSync(fd, ' }\n');
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, 6).join('\n'));
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
- fs.writeSync(fd, indentLines(interfaceTemplate, 6).join('\n'));
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(fieldInfo, subFolder = 'msg') {
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
@@ -29,6 +29,7 @@ const dependencies = [
29
29
  'builtin_interfaces',
30
30
  'rcl_lifecycle',
31
31
  'lifecycle_msgs',
32
+ 'rcpputils',
32
33
  'rosidl_runtime_c',
33
34
  'rosidl_dynamic_typesupport',
34
35
  'type_description_interfaces',
@@ -43,9 +43,9 @@ npm i rclnodejs@x.y.z
43
43
 
44
44
  #### RCLNODEJS - ROS 2 Version Compatibility
45
45
 
46
- | RCLNODEJS Version | Compatible ROS 2 LTS |
47
- | :------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------: |
48
- | latest version (currently [v0.32.5](https://github.com/RobotWebTools/rclnodejs/tree/0.32.5)) | [Humble](https://github.com/RobotWebTools/rclnodejs/tree/humble-hawksbill)<br>[Jazzy](https://github.com/RobotWebTools/rclnodejs/tree/jazzy) |
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 <nan.h>
15
+ #include <node_api.h>
16
+ #include <rcutils/logging.h>
16
17
 
17
- #include "macros.hpp"
18
- #include "rcl_action_bindings.hpp"
19
- #include "rcl_bindings.hpp"
20
- #include "rcl_handle.hpp"
21
- #include "rcl_lifecycle_bindings.hpp"
22
- #include "rcutils/logging.h"
23
- #include "rcutils/macros.h"
24
- #include "shadow_node.hpp"
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
- auto global = Nan::GetCurrentContext()->Global();
28
- auto process =
29
- Nan::To<v8::Object>(Nan::Get(global, Nan::New("process").ToLocalChecked())
30
- .ToLocalChecked())
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
- void InitModule(v8::Local<v8::Object> exports) {
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
- v8::Local<v8::Context> context = exports->GetIsolate()->GetCurrentContext();
55
-
56
- for (uint32_t i = 0; i < rclnodejs::binding_methods.size(); i++) {
57
- Nan::Set(
58
- exports, Nan::New(rclnodejs::binding_methods[i].name).ToLocalChecked(),
59
- Nan::New<v8::FunctionTemplate>(rclnodejs::binding_methods[i].function)
60
- ->GetFunction(context)
61
- .ToLocalChecked());
62
- }
63
-
64
- for (uint32_t i = 0; i < rclnodejs::action_binding_methods.size(); i++) {
65
- Nan::Set(
66
- exports,
67
- Nan::New(rclnodejs::action_binding_methods[i].name).ToLocalChecked(),
68
- Nan::New<v8::FunctionTemplate>(
69
- rclnodejs::action_binding_methods[i].function)
70
- ->GetFunction(context)
71
- .ToLocalChecked());
72
- }
73
-
74
- for (uint32_t i = 0; i < rclnodejs::lifecycle_binding_methods.size(); i++) {
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
- NODE_MODULE(rclnodejs, InitModule);
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.hpp"
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.hpp"
23
- #include "macros.hpp"
24
- #include "rcl_bindings.hpp"
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, Delegate* delegate)
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) Nan::ThrowError(rcl_get_error_string().str);
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
- Nan::ThrowError(wait_result.error_msg.c_str());
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
- Nan::ThrowError(error_message.c_str());
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 SRC_EXECUTOR_HPP_
16
- #define SRC_EXECUTOR_HPP_
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.hpp"
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 // SRC_EXECUTOR_HPP_
79
+ #endif // SRC_EXECUTOR_H_