rclnodejs 0.22.3 → 0.23.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 CHANGED
@@ -1,4 +1,4 @@
1
- # rclnodejs [![Build Status](https://travis-ci.org/RobotWebTools/rclnodejs.svg?branch=develop)](https://travis-ci.org/RobotWebTools/rclnodejs)
1
+ # rclnodejs ![GitHub Workflow Status](https://github.com/RobotWebTools/rclnodejs/actions/workflows/linux-build-and-test.yml/badge.svg?branch=iron-irwini)
2
2
 
3
3
  `rclnodejs` is a Node.js client for the Robot Operating System (ROS 2). It provides a simple and easy JavaScript API for ROS 2 programming. TypeScript declarations are included to support use of rclnodejs in TypeScript projects.
4
4
 
@@ -18,7 +18,7 @@ rclnodejs.init().then(() => {
18
18
 
19
19
  **Node.js**
20
20
 
21
- - [Node.js](https://nodejs.org/en/) version between 10.23 - 17.x.
21
+ - [Node.js](https://nodejs.org/en/) version >= 16.13.0.
22
22
 
23
23
  **ROS 2 SDK**
24
24
 
@@ -43,14 +43,13 @@ npm i rclnodejs@x.y.z
43
43
 
44
44
  #### RCLNODEJS - ROS 2 Version Compatibility
45
45
 
46
- | RCLNODEJS Version | Compatible ROS 2 Release |
47
- | :-------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
48
- | [0.21.4 (current)](https://www.npmjs.com/package/rclnodejs/v/0.21.4) ([API](http://robotwebtools.org/rclnodejs/docs/0.21.3/index.html)) | [Humble Hawksbill](https://github.com/ros2/ros2/releases/tag/release-humble-20220523)<br>[Galactic Geochelone](https://github.com/ros2/ros2/releases/tag/release-galactic-20210716)<br>[Foxy Fitzroy](https://github.com/ros2/ros2/releases/tag/release-foxy-20201211)<br>[Eloquent Elusor](https://github.com/ros2/ros2/releases/tag/release-eloquent-20200124) |
49
- | [0.10.3](https://github.com/RobotWebTools/rclnodejs/releases/tag/0.10.3) | [Dashing Diademata - Patch 4](https://github.com/ros2/ros2/releases/tag/release-dashing-20191018) |
46
+ | RCLNODEJS Version | Compatible ROS 2 LTS |
47
+ | :------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------: |
48
+ | latest version (currently [v0.22.3](https://github.com/RobotWebTools/rclnodejs/tree/0.22.3)) | [Humble](https://github.com/RobotWebTools/rclnodejs/tree/humble-hawksbill)<br>[Iron](https://github.com/RobotWebTools/rclnodejs/tree/iron-irwini) |
50
49
 
51
50
  ## Documentation
52
51
 
53
- API [documentation](http://robotwebtools.org/rclnodejs/docs/index.html) is available online.
52
+ API [documentation](https://robotwebtools.github.io/rclnodejs/docs/index.html) is available online.
54
53
 
55
54
  ## JavaScript Examples
56
55
 
package/index.js CHANGED
@@ -52,6 +52,7 @@ const {
52
52
  getActionServerNamesAndTypesByNode,
53
53
  getActionNamesAndTypes,
54
54
  } = require('./lib/action/graph.js');
55
+ const ServiceIntrospectionStates = require('./lib/service_introspection.js');
55
56
 
56
57
  /**
57
58
  * Get the version of the generator that was used for the currently present interfaces.
@@ -143,6 +144,9 @@ let rcl = {
143
144
  /** {@link ROSClock} class */
144
145
  ROSClock: ROSClock,
145
146
 
147
+ /** {@link ServiceIntrospectionStates} */
148
+ ServiceIntrospectionStates: ServiceIntrospectionStates,
149
+
146
150
  /** {@link Time} class */
147
151
  Time: Time,
148
152
 
package/lib/client.js CHANGED
@@ -15,6 +15,7 @@
15
15
  'use strict';
16
16
 
17
17
  const rclnodejs = require('bindings')('rclnodejs');
18
+ const DistroUtils = require('./distro.js');
18
19
  const Entity = require('./entity.js');
19
20
  const debug = require('debug')('rclnodejs:client');
20
21
 
@@ -129,6 +130,33 @@ class Client extends Entity {
129
130
  get serviceName() {
130
131
  return this._serviceName;
131
132
  }
133
+
134
+ /**
135
+ * Configure introspection.
136
+ * @param {Clock} clock - Clock to use for service event timestamps
137
+ * @param {QoS} qos - QoSProfile for the service event publisher
138
+ * @param {ServiceIntrospectionState} introspectionState - State to set introspection to
139
+ */
140
+ configureIntrospection(clock, qos, introspectionState) {
141
+ if (DistroUtils.getDistroId() <= DistroUtils.getDistroId('humble')) {
142
+ console.warn(
143
+ 'Service introspection is not supported by this versionof ROS 2'
144
+ );
145
+ return;
146
+ }
147
+
148
+ let type = this.typeClass.type();
149
+ rclnodejs.configureServiceIntrospection(
150
+ this.handle,
151
+ this._nodeHandle,
152
+ clock.handle,
153
+ type.interfaceName,
154
+ type.pkgName,
155
+ qos,
156
+ introspectionState,
157
+ false
158
+ );
159
+ }
132
160
  }
133
161
 
134
162
  module.exports = Client;
package/lib/lifecycle.js CHANGED
@@ -308,6 +308,7 @@ class LifecycleNode extends Node {
308
308
  'srv_get_state'
309
309
  );
310
310
  let service = new Service(
311
+ this.handle,
311
312
  srvHandleObj.handle,
312
313
  srvHandleObj.name,
313
314
  loader.loadInterface('lifecycle_msgs/srv/GetState'),
@@ -321,6 +322,7 @@ class LifecycleNode extends Node {
321
322
  'srv_get_available_states'
322
323
  );
323
324
  service = new Service(
325
+ this.handle,
324
326
  srvHandleObj.handle,
325
327
  srvHandleObj.name,
326
328
  loader.loadInterface('lifecycle_msgs/srv/GetAvailableStates'),
@@ -334,6 +336,7 @@ class LifecycleNode extends Node {
334
336
  'srv_get_available_transitions'
335
337
  );
336
338
  service = new Service(
339
+ this.handle,
337
340
  srvHandleObj.handle,
338
341
  srvHandleObj.name,
339
342
  loader.loadInterface('lifecycle_msgs/srv/GetAvailableTransitions'),
@@ -347,6 +350,7 @@ class LifecycleNode extends Node {
347
350
  'srv_change_state'
348
351
  );
349
352
  service = new Service(
353
+ this.handle,
350
354
  srvHandleObj.handle,
351
355
  srvHandleObj.name,
352
356
  loader.loadInterface('lifecycle_msgs/srv/ChangeState'),
@@ -354,7 +358,6 @@ class LifecycleNode extends Node {
354
358
  (request, response) => this._onChangeState(request, response)
355
359
  );
356
360
  this._services.push(service);
357
-
358
361
  this.syncHandles();
359
362
  }
360
363
 
@@ -88,7 +88,7 @@ class NodeOptions {
88
88
  /**
89
89
  * Get the automaticallyDeclareParametersFromOverrides.
90
90
  *
91
- * @returns {boolean} - True indicates that a node shold declare declare parameters from
91
+ * @returns {boolean} - True indicates that a node should declare parameters from
92
92
  * it's parameter-overrides
93
93
  */
94
94
  get automaticallyDeclareParametersFromOverrides() {
package/lib/service.js CHANGED
@@ -15,6 +15,7 @@
15
15
  'use strict';
16
16
 
17
17
  const rclnodejs = require('bindings')('rclnodejs');
18
+ const DistroUtils = require('./distro.js');
18
19
  const Entity = require('./entity.js');
19
20
  const debug = require('debug')('rclnodejs:service');
20
21
 
@@ -63,8 +64,9 @@ class Response {
63
64
  */
64
65
 
65
66
  class Service extends Entity {
66
- constructor(handle, serviceName, typeClass, options, callback) {
67
+ constructor(nodeHandle, handle, serviceName, typeClass, options, callback) {
67
68
  super(handle, typeClass, options);
69
+ this._nodeHandle = nodeHandle;
68
70
  this._callback = callback;
69
71
  }
70
72
 
@@ -95,7 +97,14 @@ class Service extends Entity {
95
97
  type.pkgName,
96
98
  options.qos
97
99
  );
98
- return new Service(handle, serviceName, typeClass, options, callback);
100
+ return new Service(
101
+ nodeHandle,
102
+ handle,
103
+ serviceName,
104
+ typeClass,
105
+ options,
106
+ callback
107
+ );
99
108
  }
100
109
 
101
110
  /**
@@ -105,6 +114,33 @@ class Service extends Entity {
105
114
  const fullServiceName = rclnodejs.getServiceName(this._handle); // returns /my_node/myservice
106
115
  return fullServiceName.split('/').pop();
107
116
  }
117
+
118
+ /**
119
+ * Configure introspection.
120
+ * @param {Clock} clock - Clock to use for service event timestamps
121
+ * @param {QoS} qos - QoSProfile for the service event publisher
122
+ * @param {ServiceIntrospectionState} introspectionState - State to set introspection to
123
+ */
124
+ configureIntrospection(clock, qos, introspectionState) {
125
+ if (DistroUtils.getDistroId() <= DistroUtils.getDistroId('humble')) {
126
+ console.warn(
127
+ 'Service introspection is not supported by this versionof ROS 2'
128
+ );
129
+ return;
130
+ }
131
+
132
+ let type = this.typeClass.type();
133
+ rclnodejs.configureServiceIntrospection(
134
+ this.handle,
135
+ this._nodeHandle,
136
+ clock.handle,
137
+ type.interfaceName,
138
+ type.pkgName,
139
+ qos,
140
+ introspectionState,
141
+ true
142
+ );
143
+ }
108
144
  }
109
145
 
110
146
  module.exports = Service;
@@ -0,0 +1,30 @@
1
+ // Copyright (c) 2023 Wayne Parrott. All rights reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ /**
16
+ * @typedef {number} ServiceIntrospectionState
17
+ **/
18
+
19
+ /**
20
+ * Enum for service introspection states.
21
+ * @readonly
22
+ * @enum {ServiceIntrospectionState}
23
+ */
24
+ const ServiceIntrospectionStates = {
25
+ OFF: 0,
26
+ METADATA: 1,
27
+ CONTENTS: 2,
28
+ };
29
+
30
+ module.exports = ServiceIntrospectionStates;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rclnodejs",
3
- "version": "0.22.3",
3
+ "version": "0.23.0",
4
4
  "description": "ROS2.0 JavaScript client with Node.js",
5
5
  "main": "index.js",
6
6
  "types": "types/index.d.ts",
@@ -42,44 +42,44 @@
42
42
  "url": "git+https://github.com/RobotWebTools/rclnodejs.git"
43
43
  },
44
44
  "devDependencies": {
45
- "@babel/eslint-parser": "^7.12.1",
46
- "@typescript-eslint/eslint-plugin": "^4.5.0",
47
- "@typescript-eslint/parser": "^4.5.0",
45
+ "@babel/eslint-parser": "^7.22.15",
46
+ "@typescript-eslint/eslint-plugin": "^6.6.0",
47
+ "@typescript-eslint/parser": "^6.6.0",
48
48
  "babel-eslint": "^10.1.0",
49
- "clang-format": "^1.4.0",
50
- "commander": "^6.0.0",
49
+ "clang-format": "^1.8.0",
50
+ "commander": "^11.0.0",
51
51
  "deep-equal": "^1.1.1",
52
- "eslint": "^7.5.0",
53
- "eslint-config-prettier": "^6.11.0",
54
- "eslint-plugin-prettier": "^3.1.4",
55
- "husky": "^4.2.5",
56
- "jsdoc": "^3.6.7",
57
- "lint-staged": "^10.2.11",
52
+ "eslint": "^8.49.0",
53
+ "eslint-config-prettier": "^9.0.0",
54
+ "eslint-plugin-prettier": "^5.0.0",
55
+ "husky": "^8.0.3",
56
+ "jsdoc": "^4.0.2",
57
+ "lint-staged": "^14.0.1",
58
58
  "mocha": "^10.2.0",
59
- "prettier": "^2.0.5",
60
- "rimraf": "^3.0.2",
61
- "sinon": "^9.0.2",
59
+ "prettier": "^3.0.3",
60
+ "rimraf": "^5.0.1",
61
+ "sinon": "^15.2.0",
62
62
  "tree-kill": "^1.2.2",
63
- "typescript": "^4.0.3"
63
+ "typescript": "^4.9.3"
64
64
  },
65
65
  "dependencies": {
66
66
  "@rclnodejs/ref-array-di": "^1.2.2",
67
67
  "@rclnodejs/ref-napi": "^4.0.0",
68
68
  "@rclnodejs/ref-struct-di": "^1.1.1",
69
- "array.prototype.flat": "^1.2.4",
69
+ "array.prototype.flat": "^1.3.2",
70
70
  "bindings": "^1.5.0",
71
- "compare-versions": "^3.6.0",
72
- "debug": "^4.1.1",
71
+ "compare-versions": "^6.1.0",
72
+ "debug": "^4.3.4",
73
73
  "dot": "^1.1.3",
74
74
  "dtslint": "^4.2.1",
75
- "fs-extra": "^10.0.0",
75
+ "fs-extra": "^11.1.1",
76
76
  "int64-napi": "^1.0.2",
77
77
  "is-close": "^1.3.3",
78
- "mkdirp": "^1.0.4",
78
+ "mkdirp": "^3.0.1",
79
79
  "mz": "^2.7.0",
80
- "nan": "^2.14.2",
81
- "uuid": "^8.2.0",
82
- "walk": "^2.3.14"
80
+ "nan": "^2.17.0",
81
+ "uuid": "^9.0.0",
82
+ "walk": "^2.3.15"
83
83
  },
84
84
  "husky": {
85
85
  "hooks": {
@@ -19,6 +19,7 @@ const fse = require('fs-extra');
19
19
  const path = require('path');
20
20
  const parser = require('../rosidl_parser/rosidl_parser.js');
21
21
  const actionMsgs = require('./action_msgs.js');
22
+ const DistroUtils = require('../lib/distro.js');
22
23
 
23
24
  dot.templateSettings.strip = false;
24
25
  dot.log = process.env.RCLNODEJS_LOG_VERBOSE || false;
@@ -42,7 +43,7 @@ async function writeGeneratedCode(dir, fileName, code) {
42
43
  await fse.writeFile(path.join(dir, fileName), code);
43
44
  }
44
45
 
45
- function generateServiceJSStruct(serviceInfo, dir) {
46
+ async function generateServiceJSStruct(serviceInfo, dir) {
46
47
  dir = path.join(dir, `${serviceInfo.pkgName}`);
47
48
  const fileName =
48
49
  serviceInfo.pkgName +
@@ -51,10 +52,29 @@ function generateServiceJSStruct(serviceInfo, dir) {
51
52
  '__' +
52
53
  serviceInfo.interfaceName +
53
54
  '.js';
54
- const generatedCode = removeEmptyLines(
55
+ const generatedSrvCode = removeEmptyLines(
55
56
  dots.service({ serviceInfo: serviceInfo })
56
57
  );
57
- return writeGeneratedCode(dir, fileName, generatedCode);
58
+ let result = writeGeneratedCode(dir, fileName, generatedSrvCode);
59
+
60
+ if (DistroUtils.getDistroId() <= DistroUtils.getDistroId('humble')) {
61
+ return result;
62
+ }
63
+
64
+ // Otherwise, for post-Humble ROS 2 releases generate service_event msgs
65
+ await result;
66
+ const eventFileName =
67
+ serviceInfo.pkgName +
68
+ '__' +
69
+ serviceInfo.subFolder +
70
+ '__' +
71
+ serviceInfo.interfaceName +
72
+ '_Event.js';
73
+ const generatedSrvEventCode = removeEmptyLines(
74
+ dots.service_event({ serviceInfo: serviceInfo })
75
+ );
76
+
77
+ return writeGeneratedCode(dir, eventFileName, generatedSrvEventCode);
58
78
  }
59
79
 
60
80
  async function generateMessageJSStruct(messageInfo, dir) {
@@ -0,0 +1,304 @@
1
+ // This file is automatically generated by Intel rclnodejs
2
+ //
3
+ // *** DO NOT EDIT directly
4
+ //
5
+ 'use strict';
6
+
7
+ {{
8
+ const interfaceName = it.serviceInfo.interfaceName;
9
+ const pkgName = it.serviceInfo.pkgName;
10
+ const subFolder = it.serviceInfo.subFolder;
11
+
12
+ const baseName = it.serviceInfo.pkgName + '__' + it.serviceInfo.subFolder + '__' + it.serviceInfo.interfaceName;
13
+ }}
14
+
15
+ const ref = require('@rclnodejs/ref-napi');
16
+ const StructType = require('@rclnodejs/ref-struct-di')(ref);
17
+ const ArrayType = require('@rclnodejs/ref-array-di')(ref);
18
+ const primitiveTypes = require('../../rosidl_gen/primitive_types.js');
19
+ const deallocator = require('../../rosidl_gen/deallocator.js');
20
+ const translator = require('../../rosidl_gen/message_translator.js');
21
+ const ServiceEventInfoWrapper = require('../service_msgs/service_msgs__msg__ServiceEventInfo.js');
22
+ const {{=interfaceName}}_RequestWrapper = require('./{{=pkgName}}__{{=subFolder}}__{{=interfaceName}}_Request.js');
23
+ const {{=interfaceName}}_ResponseWrapper = require('./{{=pkgName}}__{{=subFolder}}__{{=interfaceName}}_Response.js');
24
+ const {{=interfaceName}}_EventRefStruct = StructType({
25
+ info: ServiceEventInfoWrapper.refObjectType,
26
+ request: {{=interfaceName}}_RequestWrapper.refObjectArrayType,
27
+ response: {{=interfaceName}}_ResponseWrapper.refObjectArrayType,
28
+ });
29
+ const {{=interfaceName}}_EventRefArray = ArrayType({{=interfaceName}}_EventRefStruct);
30
+ const {{=interfaceName}}_EventRefStructArray = StructType({
31
+ data: {{=interfaceName}}_EventRefArray,
32
+ size: ref.types.size_t,
33
+ capacity: ref.types.size_t
34
+ });
35
+ // Define the wrapper class.
36
+ class {{=interfaceName}}_EventWrapper {
37
+ constructor(other) {
38
+ this._wrapperFields = {};
39
+ if (typeof other === 'object' && other._refObject) {
40
+ this._refObject = new {{=interfaceName}}_EventRefStruct(other._refObject.toObject());
41
+ this._wrapperFields.info = new ServiceEventInfoWrapper(other._wrapperFields.info);
42
+ this._wrapperFields.request = {{=interfaceName}}_RequestWrapper.createArray();
43
+ this._wrapperFields.request.copy(other._wrapperFields.request);
44
+ this._wrapperFields.response = {{=interfaceName}}_ResponseWrapper.createArray();
45
+ this._wrapperFields.response.copy(other._wrapperFields.response);
46
+ } else if (typeof other !== 'undefined') {
47
+ this._initMembers();
48
+ translator.constructFromPlanObject(this, other);
49
+ } else {
50
+ this._initMembers();
51
+ }
52
+ this.freeze();
53
+ }
54
+ _initMembers() {
55
+ this._refObject = new {{=interfaceName}}_EventRefStruct();
56
+ this._wrapperFields.info = new ServiceEventInfoWrapper();
57
+ this._wrapperFields.request = {{=interfaceName}}_RequestWrapper.createArray();
58
+ this._wrapperFields.response = {{=interfaceName}}_ResponseWrapper.createArray();
59
+ }
60
+ static createFromRefObject(refObject) {
61
+ let self = new {{=interfaceName}}_EventWrapper();
62
+ self.copyRefObject(refObject);
63
+ return self;
64
+ }
65
+ static createArray() {
66
+ return new {{=interfaceName}}_EventArrayWrapper;
67
+ }
68
+ static get ArrayType() {
69
+ return {{=interfaceName}}_EventArrayWrapper;
70
+ }
71
+ static get refObjectArrayType() {
72
+ return {{=interfaceName}}_EventRefStructArray
73
+ }
74
+ static get refObjectType() {
75
+ return {{=interfaceName}}_EventRefStruct;
76
+ }
77
+ toRawROS() {
78
+ this.freeze(true);
79
+ return this._refObject.ref();
80
+ }
81
+ freeze(own = false, checkConsistency = false) {
82
+ if (checkConsistency) {
83
+ }
84
+ this._wrapperFields.info.freeze(own, checkConsistency);
85
+ this._refObject.info = this._wrapperFields.info.refObject;
86
+ this._wrapperFields.request.freeze(own, checkConsistency);
87
+ this._refObject.request = this._wrapperFields.request.refObject;
88
+ this._wrapperFields.response.freeze(own, checkConsistency);
89
+ this._refObject.response = this._wrapperFields.response.refObject;
90
+ }
91
+ serialize() {
92
+ this.freeze(false, true);
93
+ return this._refObject.ref();
94
+ }
95
+ deserialize(refObject) {
96
+ this._wrapperFields.info.copyRefObject(refObject.info);
97
+ this._wrapperFields.request.copyRefObject(refObject.request);
98
+ this._wrapperFields.response.copyRefObject(refObject.response);
99
+ }
100
+ toPlainObject(enableTypedArray) {
101
+ return translator.toPlainObject(this, enableTypedArray);
102
+ }
103
+ static freeStruct(refObject) {
104
+ ServiceEventInfoWrapper.freeStruct(refObject.info);
105
+ if (refObject.request.size != 0) {
106
+ {{=interfaceName}}_RequestWrapper.ArrayType.freeArray(refObject.request);
107
+ if ({{=interfaceName}}_RequestWrapper.ArrayType.useTypedArray) {
108
+ // Do nothing, the v8 will take the ownership of the ArrayBuffer used by the typed array.
109
+ } else {
110
+ deallocator.freeStructMember(refObject.request, {{=interfaceName}}_RequestWrapper.refObjectArrayType, 'data');
111
+ }
112
+ }
113
+ if (refObject.response.size != 0) {
114
+ {{=interfaceName}}_ResponseWrapper.ArrayType.freeArray(refObject.response);
115
+ if ({{=interfaceName}}_ResponseWrapper.ArrayType.useTypedArray) {
116
+ // Do nothing, the v8 will take the ownership of the ArrayBuffer used by the typed array.
117
+ } else {
118
+ deallocator.freeStructMember(refObject.response, {{=interfaceName}}_ResponseWrapper.refObjectArrayType, 'data');
119
+ }
120
+ }
121
+ }
122
+ static destoryRawROS(msg) {
123
+ {{=interfaceName}}_EventWrapper.freeStruct(msg.refObject);
124
+ }
125
+ static type() {
126
+ return {pkgName: '{{=pkgName}}', subFolder: '{{=subFolder}}', interfaceName: '{{=interfaceName}}_Event'};
127
+ }
128
+ static isPrimitive() {
129
+ return false;
130
+ }
131
+ static get isROSArray() {
132
+ return false;
133
+ }
134
+ get refObject() {
135
+ return this._refObject;
136
+ }
137
+ get info() {
138
+ return this._wrapperFields.info;
139
+ }
140
+ set info(value) {
141
+ if (value instanceof ServiceEventInfoWrapper) {
142
+ this._wrapperFields.info.copy(value);
143
+ } else {
144
+ this._wrapperFields.info.copy(new ServiceEventInfoWrapper(value));
145
+ }
146
+ }
147
+ get request() {
148
+ return this._wrapperFields.request;
149
+ }
150
+ set request(value) {
151
+ if (value.length > 1) {
152
+ throw new RangeError('The length of array request must be <= 1.');
153
+ }
154
+ this._wrapperFields.request.fill(value);
155
+ }
156
+ get response() {
157
+ return this._wrapperFields.response;
158
+ }
159
+ set response(value) {
160
+ if (value.length > 1) {
161
+ throw new RangeError('The length of array response must be <= 1.');
162
+ }
163
+ this._wrapperFields.response.fill(value);
164
+ }
165
+ copyRefObject(refObject) {
166
+ this._refObject = new {{=interfaceName}}_EventRefStruct(refObject.toObject());
167
+ this._wrapperFields.info.copyRefObject(this._refObject.info);
168
+ this._wrapperFields.request.copyRefObject(this._refObject.request);
169
+ this._wrapperFields.response.copyRefObject(this._refObject.response);
170
+ }
171
+ copy(other) {
172
+ this._refObject = new {{=interfaceName}}_EventRefStruct(other._refObject.toObject());
173
+ this._wrapperFields.info.copy(other._wrapperFields.info);
174
+ this._wrapperFields.request.copy(other._wrapperFields.request);
175
+ this._wrapperFields.response.copy(other._wrapperFields.response);
176
+ }
177
+ static get classType() {
178
+ return {{=interfaceName}}_EventWrapper;
179
+ }
180
+ static get ROSMessageDef() {
181
+ return {"constants":[],"fields":[{"name":"info","type":{"isArray":false,"arraySize":null,"isUpperBound":false,"isDynamicArray":false,"isFixedSizeArray":false,"pkgName":"service_msgs","type":"ServiceEventInfo","stringUpperBound":null,"isPrimitiveType":false},"default_value":null},{"name":"request","type":{"isArray":true,"arraySize":1,"isUpperBound":true,"isDynamicArray":true,"isFixedSizeArray":false,"pkgName":"{{=pkgName}}","type":"{{=interfaceName}}_Request","stringUpperBound":null,"isPrimitiveType":false},"default_value":null},{"name":"response","type":{"isArray":true,"arraySize":1,"isUpperBound":true,"isDynamicArray":true,"isFixedSizeArray":false,"pkgName":"{{=pkgName}}","type":"{{=interfaceName}}_Response","stringUpperBound":null,"isPrimitiveType":false},"default_value":null}],"baseType":{"pkgName":"{{=pkgName}}","type":"{{=interfaceName}}_Event","stringUpperBound":null,"isPrimitiveType":false},"msgName":"{{=interfaceName}}_Event"};
182
+ }
183
+ hasMember(name) {
184
+ let memberNames = ["info","request","response"];
185
+ return memberNames.indexOf(name) !== -1;
186
+ }
187
+ }
188
+ // Define the wrapper of array class.
189
+ class {{=interfaceName}}_EventArrayWrapper {
190
+ constructor(size = 0) {
191
+ this._resize(size);
192
+ }
193
+ toRawROS() {
194
+ return this._refObject.ref();
195
+ }
196
+ fill(values) {
197
+ const length = values.length;
198
+ this._resize(length);
199
+ values.forEach((value, index) => {
200
+ if (value instanceof {{=interfaceName}}_EventWrapper) {
201
+ this._wrappers[index].copy(value);
202
+ } else {
203
+ this._wrappers[index] = new {{=interfaceName}}_EventWrapper(value);
204
+ }
205
+ });
206
+ }
207
+ // Put all data currently stored in `this._wrappers` into `this._refObject`
208
+ freeze(own) {
209
+ this._wrappers.forEach((wrapper, index) => {
210
+ wrapper.freeze(own);
211
+ this._refArray[index] = wrapper.refObject;
212
+ });
213
+ this._refObject.size = this._wrappers.length;
214
+ this._refObject.capacity = this._wrappers.length;
215
+ if (this._refObject.capacity === 0) {
216
+ this._refObject.data = null
217
+ } else {
218
+ this._refObject.data = this._refArray.buffer;
219
+ }
220
+ }
221
+ get refObject() {
222
+ return this._refObject;
223
+ }
224
+ get data() {
225
+ return this._wrappers;
226
+ }
227
+ get size() {
228
+ return this._wrappers.length;
229
+ }
230
+ set size(value) {
231
+ if (typeof value != 'number') {
232
+ throw new TypeError('Invalid argument: should provide a number to {{=interfaceName}}_EventArrayWrapper.size setter');
233
+ return;
234
+ }
235
+ return this._resize(value);
236
+ }
237
+ get capacity() {
238
+ return this._wrappers.length;
239
+ }
240
+ set capacity(value) {
241
+ if (typeof value != 'number') {
242
+ throw new TypeError('Invalid argument: should provide a number to {{=interfaceName}}_EventArrayWrapper.capacity setter');
243
+ }
244
+ return this._resize(value);
245
+ }
246
+ get refObject() {
247
+ return this._refObject;
248
+ }
249
+ _resize(size) {
250
+ if (size < 0) {
251
+ throw new RangeError('Invalid argument: should provide a positive number');
252
+ return;
253
+ }
254
+ this._refArray = new {{=interfaceName}}_EventRefArray(size);
255
+ this._refObject = new {{=interfaceName}}_EventRefStructArray();
256
+ this._refObject.size = size;
257
+ this._refObject.capacity = size;
258
+ this._wrappers = new Array();
259
+ for (let i = 0; i < size; i++) {
260
+ this._wrappers.push(new {{=interfaceName}}_EventWrapper());
261
+ }
262
+ }
263
+ // Copy all data from `this._refObject` into `this._wrappers`
264
+ copyRefObject(refObject) {
265
+ this._refObject = refObject;
266
+ let refObjectArray = this._refObject.data;
267
+ refObjectArray.length = this._refObject.size;
268
+ this._resize(this._refObject.size);
269
+ for (let index = 0; index < this._refObject.size; index++) {
270
+ this._wrappers[index].copyRefObject(refObjectArray[index]);
271
+ }
272
+ }
273
+ copy(other) {
274
+ if (! (other instanceof {{=interfaceName}}_EventArrayWrapper)) {
275
+ throw new TypeError('Invalid argument: should provide "{{=interfaceName}}_EventArrayWrapper".');
276
+ }
277
+ this._resize(other.size);
278
+ // Array deep copy
279
+ other._wrappers.forEach((wrapper, index) => {
280
+ this._wrappers[index].copy(wrapper);
281
+ });
282
+ }
283
+ static freeArray(refObject) {
284
+ let refObjectArray = refObject.data;
285
+ refObjectArray.length = refObject.size;
286
+ for (let index = 0; index < refObject.size; index++) {
287
+ {{=interfaceName}}_EventWrapper.freeStruct(refObjectArray[index]);
288
+ }
289
+ }
290
+ static get elementType() {
291
+ return {{=interfaceName}}_EventWrapper;
292
+ }
293
+ static get isROSArray() {
294
+ return true;
295
+ }
296
+ static get useTypedArray() {
297
+ return false;
298
+ }
299
+ get classType() {
300
+ return {{=interfaceName}}_EventArrayWrapper;
301
+ }
302
+ }
303
+ module.exports = {{=interfaceName}}_EventWrapper;
304
+