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 +6 -7
- package/index.js +4 -0
- package/lib/client.js +28 -0
- package/lib/lifecycle.js +4 -1
- package/lib/node_options.js +1 -1
- package/lib/service.js +38 -2
- package/lib/service_introspection.js +30 -0
- package/package.json +24 -24
- package/rosidl_gen/idl_generator.js +23 -3
- package/rosidl_gen/templates/service_event.dot +304 -0
- package/rostsd_gen/index.js +15 -12
- package/scripts/npmjs-readme.md +6 -7
- package/src/rcl_bindings.cpp +72 -1
- package/types/base.d.ts +1 -0
- package/types/client.d.ts +12 -0
- package/types/interfaces.d.ts +750 -0
- package/types/service.d.ts +12 -0
- package/types/service_introspection.d.ts +10 -0
- package/.github/workflows/identify-ros-distro.yml +0 -48
- package/.github/workflows/linux-build-and-test-compatibility.yml +0 -38
- package/.github/workflows/linux-build-and-test.yml +0 -53
- package/.github/workflows/windows-build-and-test-compatibility.yml +0 -54
- package/.github/workflows/windows-build-and-test.yml +0 -70
- package/.prettierrc.yml +0 -4
- package/.vscode/settings.json +0 -79
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# rclnodejs
|
|
1
|
+
# rclnodejs 
|
|
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
|
|
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
|
-
|
|
|
47
|
-
|
|
|
48
|
-
| [
|
|
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](
|
|
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
|
|
package/lib/node_options.js
CHANGED
|
@@ -88,7 +88,7 @@ class NodeOptions {
|
|
|
88
88
|
/**
|
|
89
89
|
* Get the automaticallyDeclareParametersFromOverrides.
|
|
90
90
|
*
|
|
91
|
-
* @returns {boolean} - True indicates that a node
|
|
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(
|
|
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.
|
|
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.
|
|
46
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
47
|
-
"@typescript-eslint/parser": "^
|
|
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.
|
|
50
|
-
"commander": "^
|
|
49
|
+
"clang-format": "^1.8.0",
|
|
50
|
+
"commander": "^11.0.0",
|
|
51
51
|
"deep-equal": "^1.1.1",
|
|
52
|
-
"eslint": "^
|
|
53
|
-
"eslint-config-prettier": "^
|
|
54
|
-
"eslint-plugin-prettier": "^
|
|
55
|
-
"husky": "^
|
|
56
|
-
"jsdoc": "^
|
|
57
|
-
"lint-staged": "^
|
|
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": "^
|
|
60
|
-
"rimraf": "^
|
|
61
|
-
"sinon": "^
|
|
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.
|
|
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
|
|
69
|
+
"array.prototype.flat": "^1.3.2",
|
|
70
70
|
"bindings": "^1.5.0",
|
|
71
|
-
"compare-versions": "^
|
|
72
|
-
"debug": "^4.
|
|
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": "^
|
|
75
|
+
"fs-extra": "^11.1.1",
|
|
76
76
|
"int64-napi": "^1.0.2",
|
|
77
77
|
"is-close": "^1.3.3",
|
|
78
|
-
"mkdirp": "^
|
|
78
|
+
"mkdirp": "^3.0.1",
|
|
79
79
|
"mz": "^2.7.0",
|
|
80
|
-
"nan": "^2.
|
|
81
|
-
"uuid": "^
|
|
82
|
-
"walk": "^2.3.
|
|
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
|
|
55
|
+
const generatedSrvCode = removeEmptyLines(
|
|
55
56
|
dots.service({ serviceInfo: serviceInfo })
|
|
56
57
|
);
|
|
57
|
-
|
|
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
|
+
|