nitrogen 0.29.5 → 0.29.7
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/lib/autolinking/android/createCMakeExtension.js +7 -7
- package/lib/syntax/HybridObjectSpec.d.ts +13 -0
- package/lib/syntax/swift/SwiftCxxBridgedType.js +29 -10
- package/lib/syntax/swift/SwiftCxxTypeHelper.d.ts +18 -0
- package/lib/syntax/swift/SwiftCxxTypeHelper.js +44 -14
- package/lib/views/kotlin/KotlinHybridViewManager.js +5 -1
- package/package.json +4 -4
- package/src/autolinking/android/createCMakeExtension.ts +7 -7
- package/src/getFiles.ts +3 -1
- package/src/syntax/swift/SwiftCxxBridgedType.ts +27 -9
- package/src/syntax/swift/SwiftCxxTypeHelper.ts +45 -14
- package/src/views/kotlin/KotlinHybridViewManager.ts +5 -1
|
@@ -32,6 +32,12 @@ ${createFileMetadataString(`${name}+autolinking.cmake`, '#')}
|
|
|
32
32
|
# include(\${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/${name}+autolinking.cmake)
|
|
33
33
|
# \`\`\`
|
|
34
34
|
|
|
35
|
+
# Define a flag to check if we are building properly
|
|
36
|
+
add_definitions(-D${buildingWithDefinition})
|
|
37
|
+
|
|
38
|
+
# Enable Raw Props parsing in react-native (for Nitro Views)
|
|
39
|
+
add_definitions(-DRN_SERIALIZABLE_STATE)
|
|
40
|
+
|
|
35
41
|
# Add all headers that were generated by Nitrogen
|
|
36
42
|
include_directories(
|
|
37
43
|
"../nitrogen/generated/shared/c++"
|
|
@@ -51,15 +57,9 @@ target_sources(
|
|
|
51
57
|
${indent(androidFiles.join('\n'), ' ')}
|
|
52
58
|
)
|
|
53
59
|
|
|
54
|
-
# Define a flag to check if we are building properly
|
|
55
|
-
add_definitions(-D${buildingWithDefinition})
|
|
56
|
-
|
|
57
|
-
# Enable Raw Props parsing in react-native (for Nitro Views)
|
|
58
|
-
add_compile_options(-DRN_SERIALIZABLE_STATE=1)
|
|
59
|
-
|
|
60
60
|
# From node_modules/react-native/ReactAndroid/cmake-utils/folly-flags.cmake
|
|
61
61
|
# Used in node_modules/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake
|
|
62
|
-
|
|
62
|
+
target_compile_definitions(
|
|
63
63
|
${name} PRIVATE
|
|
64
64
|
-DFOLLY_NO_CONFIG=1
|
|
65
65
|
-DFOLLY_HAVE_CLOCK_GETTIME=1
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { NitroConfig } from '../config/NitroConfig.js';
|
|
2
|
+
import type { Language } from '../getPlatformSpecs.js';
|
|
3
|
+
import type { Method } from './Method.js';
|
|
4
|
+
import type { Property } from './Property.js';
|
|
5
|
+
export interface HybridObjectSpec {
|
|
6
|
+
name: string;
|
|
7
|
+
language: Language;
|
|
8
|
+
properties: Property[];
|
|
9
|
+
methods: Method[];
|
|
10
|
+
baseTypes: HybridObjectSpec[];
|
|
11
|
+
isHybridView: boolean;
|
|
12
|
+
config: NitroConfig;
|
|
13
|
+
}
|
|
@@ -14,7 +14,7 @@ import { StructType } from '../types/StructType.js';
|
|
|
14
14
|
import { TupleType } from '../types/TupleType.js';
|
|
15
15
|
import { VariantType } from '../types/VariantType.js';
|
|
16
16
|
import { getReferencedTypes } from '../getReferencedTypes.js';
|
|
17
|
-
import { createSwiftCxxHelpers, } from './SwiftCxxTypeHelper.js';
|
|
17
|
+
import { createSwiftCxxHelpers, isPrimitivelyCopyable, } from './SwiftCxxTypeHelper.js';
|
|
18
18
|
import { createSwiftEnumBridge } from './SwiftEnum.js';
|
|
19
19
|
import { createSwiftStructBridge } from './SwiftStruct.js';
|
|
20
20
|
import { createSwiftVariant } from './SwiftVariant.js';
|
|
@@ -68,17 +68,11 @@ export class SwiftCxxBridgedType {
|
|
|
68
68
|
case 'tuple':
|
|
69
69
|
// (A, B) <> std::tuple<A, B>
|
|
70
70
|
return true;
|
|
71
|
-
case 'struct':
|
|
72
|
-
// SomeStruct (Swift extension) <> SomeStruct (C++)
|
|
73
|
-
return true;
|
|
74
71
|
case 'function':
|
|
75
72
|
// (@ecaping () -> Void) <> std::function<...>
|
|
76
73
|
return true;
|
|
77
74
|
case 'array-buffer':
|
|
78
75
|
// ArrayBufferHolder <> std::shared_ptr<ArrayBuffer>
|
|
79
|
-
if (this.isBridgingToDirectCppTarget) {
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
76
|
return true;
|
|
83
77
|
case 'date':
|
|
84
78
|
// Date <> double
|
|
@@ -452,7 +446,21 @@ export class SwiftCxxBridgedType {
|
|
|
452
446
|
const wrapping = new SwiftCxxBridgedType(array.itemType, true);
|
|
453
447
|
switch (language) {
|
|
454
448
|
case 'swift':
|
|
455
|
-
|
|
449
|
+
if (isPrimitivelyCopyable(array.itemType)) {
|
|
450
|
+
// We can primitively copy the data, raw:
|
|
451
|
+
const bridge = this.getBridgeOrThrow();
|
|
452
|
+
const getDataFunc = `bridge.get_data_${bridge.specializationName}`;
|
|
453
|
+
return `
|
|
454
|
+
{ () -> ${array.getCode('swift')} in
|
|
455
|
+
let __data = ${getDataFunc}(${cppParameterName})
|
|
456
|
+
let __size = ${cppParameterName}.size()
|
|
457
|
+
return Array(UnsafeBufferPointer(start: __data, count: __size))
|
|
458
|
+
}()`.trim();
|
|
459
|
+
}
|
|
460
|
+
else {
|
|
461
|
+
// We have to iterate the element one by one to create a resulting Array (mapped)
|
|
462
|
+
return `${cppParameterName}.map({ __item in ${wrapping.parseFromCppToSwift('__item', 'swift')} })`.trim();
|
|
463
|
+
}
|
|
456
464
|
default:
|
|
457
465
|
return cppParameterName;
|
|
458
466
|
}
|
|
@@ -698,12 +706,22 @@ case ${i}:
|
|
|
698
706
|
}
|
|
699
707
|
case 'array': {
|
|
700
708
|
const bridge = this.getBridgeOrThrow();
|
|
701
|
-
const makeFunc = `bridge.${bridge.funcName}`;
|
|
702
709
|
const array = getTypeAs(this.type, ArrayType);
|
|
703
710
|
const wrapping = new SwiftCxxBridgedType(array.itemType, true);
|
|
704
711
|
switch (language) {
|
|
705
712
|
case 'swift':
|
|
706
|
-
|
|
713
|
+
if (isPrimitivelyCopyable(array.itemType)) {
|
|
714
|
+
// memory can be copied primitively
|
|
715
|
+
const copyFunc = `bridge.${bridge.funcName}`;
|
|
716
|
+
return `
|
|
717
|
+
${swiftParameterName}.withUnsafeBufferPointer { __pointer -> bridge.${bridge.specializationName} in
|
|
718
|
+
return ${copyFunc}(__pointer.baseAddress!, ${swiftParameterName}.count)
|
|
719
|
+
}`.trim();
|
|
720
|
+
}
|
|
721
|
+
else {
|
|
722
|
+
// array has to be iterated and converted one-by-one
|
|
723
|
+
const makeFunc = `bridge.${bridge.funcName}`;
|
|
724
|
+
return `
|
|
707
725
|
{ () -> bridge.${bridge.specializationName} in
|
|
708
726
|
var __vector = ${makeFunc}(${swiftParameterName}.count)
|
|
709
727
|
for __item in ${swiftParameterName} {
|
|
@@ -711,6 +729,7 @@ case ${i}:
|
|
|
711
729
|
}
|
|
712
730
|
return __vector
|
|
713
731
|
}()`.trim();
|
|
732
|
+
}
|
|
714
733
|
default:
|
|
715
734
|
return swiftParameterName;
|
|
716
735
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { SourceImport } from '../SourceFile.js';
|
|
2
|
+
import type { Type } from '../types/Type.js';
|
|
3
|
+
export interface SwiftCxxHelper {
|
|
4
|
+
cxxHeader: {
|
|
5
|
+
code: string;
|
|
6
|
+
requiredIncludes: SourceImport[];
|
|
7
|
+
};
|
|
8
|
+
cxxImplementation?: {
|
|
9
|
+
code: string;
|
|
10
|
+
requiredIncludes: SourceImport[];
|
|
11
|
+
};
|
|
12
|
+
funcName: string;
|
|
13
|
+
specializationName: string;
|
|
14
|
+
cxxType: string;
|
|
15
|
+
dependencies: SwiftCxxHelper[];
|
|
16
|
+
}
|
|
17
|
+
export declare function createSwiftCxxHelpers(type: Type): SwiftCxxHelper | undefined;
|
|
18
|
+
export declare function isPrimitivelyCopyable(type: Type): boolean;
|
|
@@ -115,17 +115,17 @@ return ${cxxNamespace}::get_${internalName}(cppType);
|
|
|
115
115
|
* Specialized version of \`${escapeComments(actualType)}\`.
|
|
116
116
|
*/
|
|
117
117
|
using ${name} = ${actualType};
|
|
118
|
-
${actualType} create_${name}(void*
|
|
119
|
-
void*
|
|
118
|
+
${actualType} create_${name}(void* NON_NULL swiftUnsafePointer) noexcept;
|
|
119
|
+
void* NON_NULL get_${name}(${name} cppType) noexcept;
|
|
120
120
|
`.trim(),
|
|
121
121
|
requiredIncludes: type.getRequiredImports('c++'),
|
|
122
122
|
},
|
|
123
123
|
cxxImplementation: {
|
|
124
124
|
code: `
|
|
125
|
-
${actualType} create_${name}(void*
|
|
125
|
+
${actualType} create_${name}(void* NON_NULL swiftUnsafePointer) noexcept {
|
|
126
126
|
${indent(createImplementation, ' ')}
|
|
127
127
|
}
|
|
128
|
-
void*
|
|
128
|
+
void* NON_NULL get_${name}(${name} cppType) noexcept {
|
|
129
129
|
${indent(getImplementation, ' ')}
|
|
130
130
|
}
|
|
131
131
|
`.trim(),
|
|
@@ -219,6 +219,10 @@ inline ${wrappedBridge.getTypeCode('c++')} get_${name}(const ${actualType}& opti
|
|
|
219
219
|
dependencies: [],
|
|
220
220
|
};
|
|
221
221
|
}
|
|
222
|
+
export function isPrimitivelyCopyable(type) {
|
|
223
|
+
const bridgedType = new SwiftCxxBridgedType(type, true);
|
|
224
|
+
return !bridgedType.needsSpecialHandling;
|
|
225
|
+
}
|
|
222
226
|
/**
|
|
223
227
|
* Creates a C++ `create_vector_T<T>(size)` function that can be called from Swift.
|
|
224
228
|
*/
|
|
@@ -226,12 +230,27 @@ function createCxxVectorSwiftHelper(type) {
|
|
|
226
230
|
const actualType = type.getCode('c++');
|
|
227
231
|
const bridgedType = new SwiftCxxBridgedType(type);
|
|
228
232
|
const name = escapeCppName(actualType);
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
233
|
+
let code;
|
|
234
|
+
let funcName;
|
|
235
|
+
if (isPrimitivelyCopyable(type.itemType)) {
|
|
236
|
+
const itemType = type.itemType.getCode('c++');
|
|
237
|
+
funcName = `copy_${name}`;
|
|
238
|
+
code = `
|
|
239
|
+
/**
|
|
240
|
+
* Specialized version of \`${escapeComments(actualType)}\`.
|
|
241
|
+
*/
|
|
242
|
+
using ${name} = ${actualType};
|
|
243
|
+
inline ${actualType} copy_${name}(const ${itemType}* CONTIGUOUS_MEMORY NON_NULL data, size_t size) noexcept {
|
|
244
|
+
return margelo::nitro::FastVectorCopy<${itemType}>(data, size);
|
|
245
|
+
}
|
|
246
|
+
inline const ${itemType}* CONTIGUOUS_MEMORY NON_NULL get_data_${name}(const ${actualType}& vector) noexcept {
|
|
247
|
+
return vector.data();
|
|
248
|
+
}
|
|
249
|
+
`.trim();
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
funcName = `create_${name}`;
|
|
253
|
+
code = `
|
|
235
254
|
/**
|
|
236
255
|
* Specialized version of \`${escapeComments(actualType)}\`.
|
|
237
256
|
*/
|
|
@@ -240,14 +259,25 @@ inline ${actualType} create_${name}(size_t size) noexcept {
|
|
|
240
259
|
${actualType} vector;
|
|
241
260
|
vector.reserve(size);
|
|
242
261
|
return vector;
|
|
243
|
-
}
|
|
244
|
-
|
|
262
|
+
}`.trim();
|
|
263
|
+
}
|
|
264
|
+
return {
|
|
265
|
+
cxxType: actualType,
|
|
266
|
+
funcName: funcName,
|
|
267
|
+
specializationName: name,
|
|
268
|
+
cxxHeader: {
|
|
269
|
+
code: code,
|
|
245
270
|
requiredIncludes: [
|
|
246
271
|
{
|
|
247
272
|
name: 'vector',
|
|
248
273
|
space: 'system',
|
|
249
274
|
language: 'c++',
|
|
250
275
|
},
|
|
276
|
+
{
|
|
277
|
+
name: 'NitroModules/FastVectorCopy.hpp',
|
|
278
|
+
space: 'system',
|
|
279
|
+
language: 'c++',
|
|
280
|
+
},
|
|
251
281
|
...bridgedType.getRequiredImports('c++'),
|
|
252
282
|
],
|
|
253
283
|
},
|
|
@@ -382,7 +412,7 @@ public:
|
|
|
382
412
|
private:
|
|
383
413
|
std::unique_ptr<${actualType}> _function;
|
|
384
414
|
} SWIFT_NONCOPYABLE;
|
|
385
|
-
${name} create_${name}(void*
|
|
415
|
+
${name} create_${name}(void* NON_NULL swiftClosureWrapper) noexcept;
|
|
386
416
|
inline ${wrapperName} wrap_${name}(${name} value) noexcept {
|
|
387
417
|
return ${wrapperName}(std::move(value));
|
|
388
418
|
}
|
|
@@ -403,7 +433,7 @@ inline ${wrapperName} wrap_${name}(${name} value) noexcept {
|
|
|
403
433
|
},
|
|
404
434
|
cxxImplementation: {
|
|
405
435
|
code: `
|
|
406
|
-
${name} create_${name}(void*
|
|
436
|
+
${name} create_${name}(void* NON_NULL swiftClosureWrapper) noexcept {
|
|
407
437
|
auto swiftClosure = ${swiftClassName}::fromUnsafe(swiftClosureWrapper);
|
|
408
438
|
return [swiftClosure = std::move(swiftClosure)](${paramsSignature.join(', ')}) mutable -> ${type.returnType.getCode('c++')} {
|
|
409
439
|
${indent(body, ' ')}
|
|
@@ -31,7 +31,7 @@ import ${javaNamespace}.*
|
|
|
31
31
|
/**
|
|
32
32
|
* Represents the React Native \`ViewManager\` for the "${spec.name}" Nitro HybridView.
|
|
33
33
|
*/
|
|
34
|
-
class ${manager}: SimpleViewManager<View>() {
|
|
34
|
+
open class ${manager}: SimpleViewManager<View>() {
|
|
35
35
|
private val views = hashMapOf<View, ${viewImplementation}>()
|
|
36
36
|
|
|
37
37
|
override fun getName(): String {
|
|
@@ -89,6 +89,10 @@ ${createFileMetadataString(`J${stateUpdaterName}.hpp`)}
|
|
|
89
89
|
|
|
90
90
|
#pragma once
|
|
91
91
|
|
|
92
|
+
#ifndef RN_SERIALIZABLE_STATE
|
|
93
|
+
#error ${spec.config.getAndroidCxxLibName()} was compiled without the 'RN_SERIALIZABLE_STATE' flag. This flag is required for Nitro Views - set it in your CMakeLists!
|
|
94
|
+
#endif
|
|
95
|
+
|
|
92
96
|
#include <fbjni/fbjni.h>
|
|
93
97
|
#include <react/fabric/StateWrapperImpl.h>
|
|
94
98
|
#include <react/fabric/CoreComponentsRegistry.h>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nitrogen",
|
|
3
|
-
"version": "0.29.
|
|
3
|
+
"version": "0.29.7",
|
|
4
4
|
"description": "The code-generator for react-native-nitro-modules.",
|
|
5
5
|
"main": "lib/index",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -36,13 +36,13 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"chalk": "^5.3.0",
|
|
39
|
-
"react-native-nitro-modules": "^0.29.
|
|
40
|
-
"ts-morph": "^
|
|
39
|
+
"react-native-nitro-modules": "^0.29.7",
|
|
40
|
+
"ts-morph": "^27.0.0",
|
|
41
41
|
"yargs": "^17.7.2",
|
|
42
42
|
"zod": "^4.0.5"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@types/node": "^
|
|
45
|
+
"@types/node": "^24.5.2"
|
|
46
46
|
},
|
|
47
47
|
"release-it": {
|
|
48
48
|
"npm": {
|
|
@@ -49,6 +49,12 @@ ${createFileMetadataString(`${name}+autolinking.cmake`, '#')}
|
|
|
49
49
|
# include(\${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/${name}+autolinking.cmake)
|
|
50
50
|
# \`\`\`
|
|
51
51
|
|
|
52
|
+
# Define a flag to check if we are building properly
|
|
53
|
+
add_definitions(-D${buildingWithDefinition})
|
|
54
|
+
|
|
55
|
+
# Enable Raw Props parsing in react-native (for Nitro Views)
|
|
56
|
+
add_definitions(-DRN_SERIALIZABLE_STATE)
|
|
57
|
+
|
|
52
58
|
# Add all headers that were generated by Nitrogen
|
|
53
59
|
include_directories(
|
|
54
60
|
"../nitrogen/generated/shared/c++"
|
|
@@ -68,15 +74,9 @@ target_sources(
|
|
|
68
74
|
${indent(androidFiles.join('\n'), ' ')}
|
|
69
75
|
)
|
|
70
76
|
|
|
71
|
-
# Define a flag to check if we are building properly
|
|
72
|
-
add_definitions(-D${buildingWithDefinition})
|
|
73
|
-
|
|
74
|
-
# Enable Raw Props parsing in react-native (for Nitro Views)
|
|
75
|
-
add_compile_options(-DRN_SERIALIZABLE_STATE=1)
|
|
76
|
-
|
|
77
77
|
# From node_modules/react-native/ReactAndroid/cmake-utils/folly-flags.cmake
|
|
78
78
|
# Used in node_modules/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake
|
|
79
|
-
|
|
79
|
+
target_compile_definitions(
|
|
80
80
|
${name} PRIVATE
|
|
81
81
|
-DFOLLY_NO_CONFIG=1
|
|
82
82
|
-DFOLLY_HAVE_CLOCK_GETTIME=1
|
package/src/getFiles.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { Dirent, promises as fs } from 'fs'
|
|
2
2
|
import path from 'path'
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
type DirentCompat = Dirent & { path?: string }
|
|
5
|
+
|
|
6
|
+
function getFilePath(file: DirentCompat, rootDir: string): string {
|
|
5
7
|
const dir = file.parentPath ?? file.path ?? rootDir
|
|
6
8
|
return path.join(dir, file.name)
|
|
7
9
|
}
|
|
@@ -22,6 +22,7 @@ import { VariantType } from '../types/VariantType.js'
|
|
|
22
22
|
import { getReferencedTypes } from '../getReferencedTypes.js'
|
|
23
23
|
import {
|
|
24
24
|
createSwiftCxxHelpers,
|
|
25
|
+
isPrimitivelyCopyable,
|
|
25
26
|
type SwiftCxxHelper,
|
|
26
27
|
} from './SwiftCxxTypeHelper.js'
|
|
27
28
|
import { createSwiftEnumBridge } from './SwiftEnum.js'
|
|
@@ -84,17 +85,11 @@ export class SwiftCxxBridgedType implements BridgedType<'swift', 'c++'> {
|
|
|
84
85
|
case 'tuple':
|
|
85
86
|
// (A, B) <> std::tuple<A, B>
|
|
86
87
|
return true
|
|
87
|
-
case 'struct':
|
|
88
|
-
// SomeStruct (Swift extension) <> SomeStruct (C++)
|
|
89
|
-
return true
|
|
90
88
|
case 'function':
|
|
91
89
|
// (@ecaping () -> Void) <> std::function<...>
|
|
92
90
|
return true
|
|
93
91
|
case 'array-buffer':
|
|
94
92
|
// ArrayBufferHolder <> std::shared_ptr<ArrayBuffer>
|
|
95
|
-
if (this.isBridgingToDirectCppTarget) {
|
|
96
|
-
return false
|
|
97
|
-
}
|
|
98
93
|
return true
|
|
99
94
|
case 'date':
|
|
100
95
|
// Date <> double
|
|
@@ -492,7 +487,20 @@ export class SwiftCxxBridgedType implements BridgedType<'swift', 'c++'> {
|
|
|
492
487
|
const wrapping = new SwiftCxxBridgedType(array.itemType, true)
|
|
493
488
|
switch (language) {
|
|
494
489
|
case 'swift':
|
|
495
|
-
|
|
490
|
+
if (isPrimitivelyCopyable(array.itemType)) {
|
|
491
|
+
// We can primitively copy the data, raw:
|
|
492
|
+
const bridge = this.getBridgeOrThrow()
|
|
493
|
+
const getDataFunc = `bridge.get_data_${bridge.specializationName}`
|
|
494
|
+
return `
|
|
495
|
+
{ () -> ${array.getCode('swift')} in
|
|
496
|
+
let __data = ${getDataFunc}(${cppParameterName})
|
|
497
|
+
let __size = ${cppParameterName}.size()
|
|
498
|
+
return Array(UnsafeBufferPointer(start: __data, count: __size))
|
|
499
|
+
}()`.trim()
|
|
500
|
+
} else {
|
|
501
|
+
// We have to iterate the element one by one to create a resulting Array (mapped)
|
|
502
|
+
return `${cppParameterName}.map({ __item in ${wrapping.parseFromCppToSwift('__item', 'swift')} })`.trim()
|
|
503
|
+
}
|
|
496
504
|
default:
|
|
497
505
|
return cppParameterName
|
|
498
506
|
}
|
|
@@ -749,12 +757,21 @@ case ${i}:
|
|
|
749
757
|
}
|
|
750
758
|
case 'array': {
|
|
751
759
|
const bridge = this.getBridgeOrThrow()
|
|
752
|
-
const makeFunc = `bridge.${bridge.funcName}`
|
|
753
760
|
const array = getTypeAs(this.type, ArrayType)
|
|
754
761
|
const wrapping = new SwiftCxxBridgedType(array.itemType, true)
|
|
755
762
|
switch (language) {
|
|
756
763
|
case 'swift':
|
|
757
|
-
|
|
764
|
+
if (isPrimitivelyCopyable(array.itemType)) {
|
|
765
|
+
// memory can be copied primitively
|
|
766
|
+
const copyFunc = `bridge.${bridge.funcName}`
|
|
767
|
+
return `
|
|
768
|
+
${swiftParameterName}.withUnsafeBufferPointer { __pointer -> bridge.${bridge.specializationName} in
|
|
769
|
+
return ${copyFunc}(__pointer.baseAddress!, ${swiftParameterName}.count)
|
|
770
|
+
}`.trim()
|
|
771
|
+
} else {
|
|
772
|
+
// array has to be iterated and converted one-by-one
|
|
773
|
+
const makeFunc = `bridge.${bridge.funcName}`
|
|
774
|
+
return `
|
|
758
775
|
{ () -> bridge.${bridge.specializationName} in
|
|
759
776
|
var __vector = ${makeFunc}(${swiftParameterName}.count)
|
|
760
777
|
for __item in ${swiftParameterName} {
|
|
@@ -762,6 +779,7 @@ case ${i}:
|
|
|
762
779
|
}
|
|
763
780
|
return __vector
|
|
764
781
|
}()`.trim()
|
|
782
|
+
}
|
|
765
783
|
default:
|
|
766
784
|
return swiftParameterName
|
|
767
785
|
}
|
|
@@ -147,17 +147,17 @@ return ${cxxNamespace}::get_${internalName}(cppType);
|
|
|
147
147
|
* Specialized version of \`${escapeComments(actualType)}\`.
|
|
148
148
|
*/
|
|
149
149
|
using ${name} = ${actualType};
|
|
150
|
-
${actualType} create_${name}(void*
|
|
151
|
-
void*
|
|
150
|
+
${actualType} create_${name}(void* NON_NULL swiftUnsafePointer) noexcept;
|
|
151
|
+
void* NON_NULL get_${name}(${name} cppType) noexcept;
|
|
152
152
|
`.trim(),
|
|
153
153
|
requiredIncludes: type.getRequiredImports('c++'),
|
|
154
154
|
},
|
|
155
155
|
cxxImplementation: {
|
|
156
156
|
code: `
|
|
157
|
-
${actualType} create_${name}(void*
|
|
157
|
+
${actualType} create_${name}(void* NON_NULL swiftUnsafePointer) noexcept {
|
|
158
158
|
${indent(createImplementation, ' ')}
|
|
159
159
|
}
|
|
160
|
-
void*
|
|
160
|
+
void* NON_NULL get_${name}(${name} cppType) noexcept {
|
|
161
161
|
${indent(getImplementation, ' ')}
|
|
162
162
|
}
|
|
163
163
|
`.trim(),
|
|
@@ -260,6 +260,11 @@ inline ${wrappedBridge.getTypeCode('c++')} get_${name}(const ${actualType}& opti
|
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
+
export function isPrimitivelyCopyable(type: Type): boolean {
|
|
264
|
+
const bridgedType = new SwiftCxxBridgedType(type, true)
|
|
265
|
+
return !bridgedType.needsSpecialHandling
|
|
266
|
+
}
|
|
267
|
+
|
|
263
268
|
/**
|
|
264
269
|
* Creates a C++ `create_vector_T<T>(size)` function that can be called from Swift.
|
|
265
270
|
*/
|
|
@@ -267,12 +272,26 @@ function createCxxVectorSwiftHelper(type: ArrayType): SwiftCxxHelper {
|
|
|
267
272
|
const actualType = type.getCode('c++')
|
|
268
273
|
const bridgedType = new SwiftCxxBridgedType(type)
|
|
269
274
|
const name = escapeCppName(actualType)
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
275
|
+
let code: string
|
|
276
|
+
let funcName: string
|
|
277
|
+
if (isPrimitivelyCopyable(type.itemType)) {
|
|
278
|
+
const itemType = type.itemType.getCode('c++')
|
|
279
|
+
funcName = `copy_${name}`
|
|
280
|
+
code = `
|
|
281
|
+
/**
|
|
282
|
+
* Specialized version of \`${escapeComments(actualType)}\`.
|
|
283
|
+
*/
|
|
284
|
+
using ${name} = ${actualType};
|
|
285
|
+
inline ${actualType} copy_${name}(const ${itemType}* CONTIGUOUS_MEMORY NON_NULL data, size_t size) noexcept {
|
|
286
|
+
return margelo::nitro::FastVectorCopy<${itemType}>(data, size);
|
|
287
|
+
}
|
|
288
|
+
inline const ${itemType}* CONTIGUOUS_MEMORY NON_NULL get_data_${name}(const ${actualType}& vector) noexcept {
|
|
289
|
+
return vector.data();
|
|
290
|
+
}
|
|
291
|
+
`.trim()
|
|
292
|
+
} else {
|
|
293
|
+
funcName = `create_${name}`
|
|
294
|
+
code = `
|
|
276
295
|
/**
|
|
277
296
|
* Specialized version of \`${escapeComments(actualType)}\`.
|
|
278
297
|
*/
|
|
@@ -281,14 +300,26 @@ inline ${actualType} create_${name}(size_t size) noexcept {
|
|
|
281
300
|
${actualType} vector;
|
|
282
301
|
vector.reserve(size);
|
|
283
302
|
return vector;
|
|
284
|
-
}
|
|
285
|
-
|
|
303
|
+
}`.trim()
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return {
|
|
307
|
+
cxxType: actualType,
|
|
308
|
+
funcName: funcName,
|
|
309
|
+
specializationName: name,
|
|
310
|
+
cxxHeader: {
|
|
311
|
+
code: code,
|
|
286
312
|
requiredIncludes: [
|
|
287
313
|
{
|
|
288
314
|
name: 'vector',
|
|
289
315
|
space: 'system',
|
|
290
316
|
language: 'c++',
|
|
291
317
|
},
|
|
318
|
+
{
|
|
319
|
+
name: 'NitroModules/FastVectorCopy.hpp',
|
|
320
|
+
space: 'system',
|
|
321
|
+
language: 'c++',
|
|
322
|
+
},
|
|
292
323
|
...bridgedType.getRequiredImports('c++'),
|
|
293
324
|
],
|
|
294
325
|
},
|
|
@@ -426,7 +457,7 @@ public:
|
|
|
426
457
|
private:
|
|
427
458
|
std::unique_ptr<${actualType}> _function;
|
|
428
459
|
} SWIFT_NONCOPYABLE;
|
|
429
|
-
${name} create_${name}(void*
|
|
460
|
+
${name} create_${name}(void* NON_NULL swiftClosureWrapper) noexcept;
|
|
430
461
|
inline ${wrapperName} wrap_${name}(${name} value) noexcept {
|
|
431
462
|
return ${wrapperName}(std::move(value));
|
|
432
463
|
}
|
|
@@ -447,7 +478,7 @@ inline ${wrapperName} wrap_${name}(${name} value) noexcept {
|
|
|
447
478
|
},
|
|
448
479
|
cxxImplementation: {
|
|
449
480
|
code: `
|
|
450
|
-
${name} create_${name}(void*
|
|
481
|
+
${name} create_${name}(void* NON_NULL swiftClosureWrapper) noexcept {
|
|
451
482
|
auto swiftClosure = ${swiftClassName}::fromUnsafe(swiftClosureWrapper);
|
|
452
483
|
return [swiftClosure = std::move(swiftClosure)](${paramsSignature.join(', ')}) mutable -> ${type.returnType.getCode('c++')} {
|
|
453
484
|
${indent(body, ' ')}
|
|
@@ -51,7 +51,7 @@ import ${javaNamespace}.*
|
|
|
51
51
|
/**
|
|
52
52
|
* Represents the React Native \`ViewManager\` for the "${spec.name}" Nitro HybridView.
|
|
53
53
|
*/
|
|
54
|
-
class ${manager}: SimpleViewManager<View>() {
|
|
54
|
+
open class ${manager}: SimpleViewManager<View>() {
|
|
55
55
|
private val views = hashMapOf<View, ${viewImplementation}>()
|
|
56
56
|
|
|
57
57
|
override fun getName(): String {
|
|
@@ -115,6 +115,10 @@ ${createFileMetadataString(`J${stateUpdaterName}.hpp`)}
|
|
|
115
115
|
|
|
116
116
|
#pragma once
|
|
117
117
|
|
|
118
|
+
#ifndef RN_SERIALIZABLE_STATE
|
|
119
|
+
#error ${spec.config.getAndroidCxxLibName()} was compiled without the 'RN_SERIALIZABLE_STATE' flag. This flag is required for Nitro Views - set it in your CMakeLists!
|
|
120
|
+
#endif
|
|
121
|
+
|
|
118
122
|
#include <fbjni/fbjni.h>
|
|
119
123
|
#include <react/fabric/StateWrapperImpl.h>
|
|
120
124
|
#include <react/fabric/CoreComponentsRegistry.h>
|