55
66'use strict ';
77
8- const StructType = require('ref-struct');
9- const ref = require('ref');
10- const ArrayType = require('ref-array');
11- const primitiveTypes = require('../../rosidl_gen/generator_primitive.js');
12- const deallocator = require('../../rosidl_gen/deallocator.js');
13-
148{{
159let objectWrapper = it.spec.msgName + 'Wrapper';
1610let arrayWrapper = it.spec.msgName + 'ArrayWrapper';
@@ -73,39 +67,63 @@ function getPrimitiveNameByType(type) {
7367}
7468
7569function getTypedArrayName(type) {
76- if (type.type === 'int8') {
70+ const t = type.type.toLowerCase();
71+ if (t === 'int8') {
7772 return 'Int8Array';
78- } else if (type.type === 'uint8') {
73+ } else if (t === 'uint8') {
7974 return 'Uint8Array';
80- } else if (type.type === 'int16') {
75+ } else if (t === 'int16') {
8176 return 'Int16Array';
82- } else if (type.type === 'uint16') {
77+ } else if (t === 'uint16') {
8378 return 'Uint16Array';
84- } else if (type.type === 'int32') {
79+ } else if (t === 'int32') {
8580 return 'Int32Array';
86- } else if (type.type === 'uint32') {
81+ } else if (t === 'uint32') {
8782 return 'Uint32Array';
88- } else if (type.type === 'int64') {
89- return 'Int64Array';
90- } else if (type.type === 'uint64') {
91- return 'Uint64Array';
92- } else if (type.type === 'float64') {
83+ } else if (t === 'float64') {
9384 return 'Float64Array';
94- } else if (type.type === 'float32') {
85+ } else if (t === 'float32') {
9586 return 'Float32Array';
96- } else if (type.type === 'char') {
87+ } else if (t === 'char') {
9788 return 'Int8Array';
98- } else if (type.type === 'byte') {
89+ } else if (t === 'byte') {
9990 return 'Uint8Array';
10091 } else {
10192 return '';
10293 }
10394}
10495
96+ function getTypedArrayElementName(type) {
97+ const t = type.type.toLowerCase();
98+ if (t === 'int8') {
99+ return 'int8';
100+ } else if (t === 'uint8') {
101+ return 'uint8';
102+ } else if (t === 'int16') {
103+ return 'int16';
104+ } else if (t === 'uint16') {
105+ return 'uint16';
106+ } else if (t === 'int32') {
107+ return 'int32';
108+ } else if (t === 'uint32') {
109+ return 'uint32';
110+ } else if (t === 'float64') {
111+ return 'double';
112+ } else if (t === 'float32') {
113+ return 'float';
114+ } else if (t === 'char') {
115+ return 'int8';
116+ } else if (t === 'byte') {
117+ return 'uint8';
118+ } else {
119+ return '';
120+ }
121+ }
122+
105123const primitiveBaseType = ['Bool', 'Int8', 'UInt8', 'Int16', 'UInt16', 'Int32', 'UInt32',
106124 'Int64', 'UInt64', 'Float64', 'Float32', 'Char', 'Byte', 'String'];
107125const typedArrayType = ['int8', 'uint8', 'int16', 'uint16', 'int32', 'uint32',
108- 'int64', 'uint64', ' float64', 'float32', 'char', 'byte'];
126+ 'float64', 'float32', 'char', 'byte'];
109127
110128let existedModules = [];
111129
@@ -118,9 +136,13 @@ function isPrimitivePackage(baseType) {
118136}
119137
120138function isTypedArrayType(type) {
121- return typedArrayType.indexOf(type.type) !== -1;
139+ return typedArrayType.indexOf(type.type.toLowerCase() ) !== -1;
122140}
123141
142+ const usePlainTypedArray = isTypedArrayType(it.spec.baseType);
143+ const currentTypedArray = getTypedArrayName(it.spec.baseType);
144+ const currentTypedArrayElementType = getTypedArrayElementName(it.spec.baseType);
145+
124146function shouldRequire(baseType, fieldType) {
125147 let requiredModule = '{{=getPackageNameByType(fieldType)}}/{{=getJSFileNameByType(fieldType)}}';
126148 let shouldRequire = !isPrimitivePackage(baseType) && (fieldType.isArray || !fieldType.isPrimitiveType || fieldType.type === 'string');
@@ -158,6 +180,15 @@ function getPackageNameByType(type) {
158180}
159181}}
160182
183+ {{? usePlainTypedArray}}
184+ const rclnodejs = require('bindings')('rclnodejs');
185+ {{?}}
186+ const StructType = require('ref-struct');
187+ const ref = require('ref');
188+ const ArrayType = require('ref-array');
189+ const primitiveTypes = require('../../rosidl_gen/generator_primitive.js');
190+ const deallocator = require('../../rosidl_gen/deallocator.js');
191+
161192{{~ it.spec.fields :field}}
162193{{? shouldRequire(it.spec.baseType, field.type)}}
163194let {{=getWrapperNameByType(field.type)}} = require('../../generated/{{=getPackageNameByType(field.type)}}/{{=getJSFileNameByType(field.type)}}');
@@ -182,7 +213,11 @@ const {{=refObjectType}} = StructType({
182213
183214const {{=refArrayType}} = ArrayType({{=refObjectType}});
184215const {{=refObjectArrayType}} = StructType({
185- data: ArrayType({{=refObjectType}}),
216+ {{? usePlainTypedArray }}
217+ data: ref.refType(ref.types.{{=currentTypedArrayElementType}}),
218+ {{?? true}}
219+ data: {{=refArrayType}},
220+ {{?}}
186221 size : ref.types.size_t,
187222 capacity: ref.types.size_t,
188223});
@@ -283,7 +318,11 @@ class {{=objectWrapper}} {
283318 {{? field.type.isArray}}
284319 if (refObject.{{=field.name}}.size != 0) {
285320 {{=getWrapperNameByType(field.type)}}.ArrayType.freeArray(refObject.{{=field.name}});
286- deallocator.freeStructMember(refObject.{{=field.name}}, {{=getWrapperNameByType(field.type)}}.refObjectArrayType, 'data');
321+ if ({{=getWrapperNameByType(field.type)}}.ArrayType.useTypedArray) {
322+ deallocator.delayFreeStructMember(refObject.{{=field.name}}, {{=getWrapperNameByType(field.type)}}.refObjectArrayType, 'data');
323+ } else {
324+ deallocator.freeStructMember(refObject.{{=field.name}}, {{=getWrapperNameByType(field.type)}}.refObjectArrayType, 'data');
325+ }
287326 }
288327 {{?? !field.type.isPrimitiveType || (field.type.type === 'string' && it.spec.msgName !== 'String')}}
289328 {{=getWrapperNameByType(field.type)}}.freeStruct(refObject.{{=field.name}});
@@ -312,12 +351,7 @@ class {{=objectWrapper}} {
312351 {{~ it.spec.fields :field}}
313352 get {{=field.name}}() {
314353 {{? field.type.isArray && isTypedArrayType(field.type)}}
315- const src = this._wrapperFields['{{=field.name}}'].data;
316- let values = new {{=getTypedArrayName(field.type)}}(src.length);
317- for (let i = 0; i < src.length; ++i) {
318- values[i] = src[i].data;
319- }
320- return values;
354+ return this._wrapperFields['{{=field.name}}'].data;
321355 {{?? field.type.isArray && field.type.isPrimitiveType}}
322356 let values = [];
323357 this._wrapperFields['{{=field.name}}'].data.forEach((wrapper, index) => {
@@ -394,30 +428,49 @@ class {{=arrayWrapper}} {
394428 }
395429
396430 fill(values) {
431+ {{? usePlainTypedArray }}
432+ if (Array.isArray(values)) {
433+ // Convert JavaScript array
434+ this._wrappers = new {{=currentTypedArray}}(values);
435+ } else {
436+ this._wrappers = values;
437+ }
438+ {{?? isPrimitivePackage(it.spec.baseType) }}
439+ // Now only for string/bool array
397440 const length = values.length;
398441 this._resize(length);
399- {{? isPrimitivePackage(it.spec.baseType)}}
400- // Use for loop to make it also work for TypedArray
401442 for (let i = 0; i < length; ++i) {
402443 let wrapper = new {{=objectWrapper}}();
403444 wrapper.data = values[i];
404445 this._wrappers[i] = wrapper;
405446 }
406- {{?? !isPrimitivePackage(it.spec.baseType)}}
447+ {{?? true}}
448+ const length = values.length;
449+ this._resize(length);
407450 values.forEach((value, index) => {
408451 this._wrappers[index].copy(value);
409452 });
410453 {{?}}
411454 }
412455
456+ // Put all data currently stored in `this._wrappers` into `this._refObject`
413457 freeze(own) {
458+ {{? usePlainTypedArray }}
459+ // When it's a TypedArray: no need to copy to `this._refArray`
460+ {{?? true}}
414461 this._wrappers.forEach((wrapper, index) => {
415462 wrapper.freeze(own);
416463 this._refArray[index] = wrapper.refObject;
417464 });
465+ {{?}}
418466 this._refObject.size = this._wrappers.length;
419467 this._refObject.capacity = this._wrappers.length;
468+ {{? usePlainTypedArray }}
469+ const buffer = Buffer.from(new Uint8Array(this._wrappers.buffer));
470+ this._refObject.data = buffer;
471+ {{?? true}}
420472 this._refObject.data = this._refArray.buffer;
473+ {{?}}
421474 }
422475
423476 get refObject() {
@@ -460,26 +513,43 @@ class {{=arrayWrapper}} {
460513 throw new RangeError('Invalid argument: should provide a positive number');
461514 return;
462515 }
516+ {{? usePlainTypedArray }}
517+ this._refArray = undefined;
518+ {{?? true }}
463519 this._refArray = new {{=refArrayType}}(size );
520+ {{?}}
464521 this._refObject = new {{=refObjectArrayType}}();
465522 this._refObject.size = size ;
466523 this._refObject.capacity = size ;
467524
525+ {{? usePlainTypedArray }}
526+ this._wrappers = new {{=currentTypedArray}}(size );
527+ {{?? true }}
468528 this._wrappers = new Array();
469529 for (let i = 0; i < size ; i++) {
470530 this._wrappers.push(new {{=objectWrapper}}());
471531 }
532+ {{?}}
472533 }
473534
535+ // Copy all data from `this._refObject` into `this._wrappers`
474536 copyRefObject(refObject) {
475537 this._refObject = refObject;
538+
539+ {{? usePlainTypedArray }}
540+ const byteLen = refObject.size * ref.types.{{=currentTypedArrayElementType}}.size ;
541+ // An ArrayBuffer object that doesn't hold the ownership of the address
542+ const arrayBuffer = rclnodejs.createArrayBufferFromAddress(refObject.data, byteLen);
543+ this._wrappers = new {{=currentTypedArray}}(arrayBuffer);
544+ {{?? true }}
476545 let refObjectArray = this._refObject.data;
477546 refObjectArray.length = this._refObject.size ;
478547 this._resize(this._refObject.size );
479548
480549 for (let index = 0; index < this._refObject.size ; index++) {
481550 this._wrappers[index].copyRefObject(refObjectArray[index]);
482551 }
552+ {{?}}
483553 }
484554
485555 copy(other) {
@@ -488,18 +558,26 @@ class {{=arrayWrapper}} {
488558 }
489559
490560 this._resize(other.size );
561+ {{? usePlainTypedArray }}
562+ this._wrappers = other._wrappers.slice();
563+ {{?? true }}
491564 // Array deep copy
492565 other._wrappers.forEach((wrapper, index) => {
493566 this._wrappers[index].copy(wrapper);
494567 });
568+ {{?}}
495569 }
496570
497571 static freeArray(refObject) {
572+ {{? usePlainTypedArray }}
573+ // For TypedArray: .data will be 'free()'-ed in parent struct
574+ {{?? true }}
498575 let refObjectArray = refObject.data;
499576 refObjectArray.length = refObject.size ;
500577 for (let index = 0; index < refObject.size ; index++) {
501578 {{=objectWrapper}}.freeStruct(refObjectArray[index]);
502579 }
580+ {{?}}
503581 }
504582
505583 static get elementType() {
@@ -510,6 +588,14 @@ class {{=arrayWrapper}} {
510588 return true;
511589 }
512590
591+ static get isROSArray() {
592+ return true;
593+ }
594+
595+ static get useTypedArray() {
596+ return {{=usePlainTypedArray}};
597+ }
598+
513599 get classType() {
514600 return {{=arrayWrapper}};
515601 }
0 commit comments