nitrogen 0.32.2 → 0.33.1
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/ios/createHybridObjectInitializer.js +25 -4
- package/lib/syntax/swift/SwiftHybridObject.js +2 -2
- package/lib/syntax/swift/SwiftHybridObjectBridge.js +5 -0
- package/lib/syntax/swift/SwiftHybridObjectRegistration.d.ts +3 -1
- package/lib/syntax/swift/SwiftHybridObjectRegistration.js +21 -14
- package/lib/views/kotlin/KotlinHybridViewManager.js +26 -12
- package/lib/views/swift/SwiftHybridViewManager.js +11 -6
- package/package.json +2 -2
- package/src/autolinking/ios/createHybridObjectInitializer.ts +25 -4
- package/src/syntax/swift/SwiftHybridObject.ts +2 -2
- package/src/syntax/swift/SwiftHybridObjectBridge.ts +6 -0
- package/src/syntax/swift/SwiftHybridObjectRegistration.ts +25 -17
- package/src/views/kotlin/KotlinHybridViewManager.ts +26 -12
- package/src/views/swift/SwiftHybridViewManager.ts +15 -6
- package/lib/syntax/types/Int32Type.d.ts +0 -10
- package/lib/syntax/types/Int32Type.js +0 -36
|
@@ -10,7 +10,7 @@ export function createHybridObjectIntializer() {
|
|
|
10
10
|
const umbrellaHeaderName = getUmbrellaHeaderName();
|
|
11
11
|
const bridgeNamespace = NitroConfig.current.getSwiftBridgeNamespace('swift');
|
|
12
12
|
const autolinkedHybridObjects = NitroConfig.current.getAutolinkedHybridObjects();
|
|
13
|
-
const
|
|
13
|
+
const swiftRegistrations = [];
|
|
14
14
|
const cppRegistrations = [];
|
|
15
15
|
const cppImports = [];
|
|
16
16
|
let containsSwiftObjects = false;
|
|
@@ -28,13 +28,13 @@ export function createHybridObjectIntializer() {
|
|
|
28
28
|
if (config?.swift != null) {
|
|
29
29
|
// Autolink a Swift HybridObject!
|
|
30
30
|
containsSwiftObjects = true;
|
|
31
|
-
const { cppCode, requiredImports,
|
|
31
|
+
const { cppCode, requiredImports, swiftRegistrationClass } = createSwiftHybridObjectRegistration({
|
|
32
32
|
hybridObjectName: hybridObjectName,
|
|
33
33
|
swiftClassName: config.swift,
|
|
34
34
|
});
|
|
35
35
|
cppImports.push(...requiredImports);
|
|
36
36
|
cppRegistrations.push(cppCode);
|
|
37
|
-
|
|
37
|
+
swiftRegistrations.push(swiftRegistrationClass);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
if (cppRegistrations.length === 0) {
|
|
@@ -72,10 +72,31 @@ ${imports}
|
|
|
72
72
|
const swiftCode = `
|
|
73
73
|
${createFileMetadataString(`${autolinkingClassName}.swift`)}
|
|
74
74
|
|
|
75
|
+
import NitroModules
|
|
76
|
+
|
|
77
|
+
// TODO: Use empty enums once Swift supports exporting them as namespaces
|
|
78
|
+
// See: https://github.com/swiftlang/swift/pull/83616
|
|
75
79
|
public final class ${autolinkingClassName} {
|
|
76
80
|
public typealias bridge = ${bridgeNamespace}
|
|
77
81
|
|
|
78
|
-
|
|
82
|
+
private protocol AutolinkedClass {
|
|
83
|
+
associatedtype T
|
|
84
|
+
/**
|
|
85
|
+
* Creates an instance of the Swift class that implements the HybridObject's spec,
|
|
86
|
+
* and wraps it in a Swift class that can directly interop with C++.
|
|
87
|
+
*
|
|
88
|
+
* This is generated by Nitrogen and will initialize the class specified
|
|
89
|
+
* in the \`"autolinking"\` property of \`nitro.json\`.
|
|
90
|
+
*/
|
|
91
|
+
static func create() -> T
|
|
92
|
+
/**
|
|
93
|
+
* Returns whether this concrete implementation is also
|
|
94
|
+
* conforming to the \`RecyclableView\` protocol, or not.
|
|
95
|
+
*/
|
|
96
|
+
static var isRecyclableHybridView: Bool { get }
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
${indent(swiftRegistrations.join('\n\n'), ' ')}
|
|
79
100
|
}
|
|
80
101
|
`.trim();
|
|
81
102
|
return [
|
|
@@ -40,14 +40,14 @@ export function createSwiftHybridObject(spec) {
|
|
|
40
40
|
baseMembers.push(`
|
|
41
41
|
public ${hasBaseClass ? 'override func' : 'func'} getCxxWrapper() -> ${name.HybridTSpecCxx} {
|
|
42
42
|
#if DEBUG
|
|
43
|
-
guard self is ${name.HybridTSpec} else {
|
|
43
|
+
guard self is any ${name.HybridTSpec} else {
|
|
44
44
|
fatalError("\`self\` is not a \`${name.HybridTSpec}\`! Did you accidentally inherit from \`${name.HybridTSpec}_base\` instead of \`${name.HybridTSpec}\`?")
|
|
45
45
|
}
|
|
46
46
|
#endif
|
|
47
47
|
if let cxxWrapper = self.cxxWrapper {
|
|
48
48
|
return cxxWrapper
|
|
49
49
|
} else {
|
|
50
|
-
let cxxWrapper = ${name.HybridTSpecCxx}(self as! ${name.HybridTSpec})
|
|
50
|
+
let cxxWrapper = ${name.HybridTSpecCxx}(self as! any ${name.HybridTSpec})
|
|
51
51
|
self.cxxWrapper = cxxWrapper
|
|
52
52
|
return cxxWrapper
|
|
53
53
|
}
|
|
@@ -41,6 +41,11 @@ public final func beforeUpdate() {
|
|
|
41
41
|
public final func afterUpdate() {
|
|
42
42
|
__implementation.afterUpdate()
|
|
43
43
|
}
|
|
44
|
+
`.trim(), `
|
|
45
|
+
public final func maybePrepareForRecycle() {
|
|
46
|
+
guard let recyclable = __implementation as? RecyclableView else { return }
|
|
47
|
+
recyclable.prepareForRecycle()
|
|
48
|
+
}
|
|
44
49
|
`.trim());
|
|
45
50
|
}
|
|
46
51
|
const hybridObject = new HybridObjectType(spec);
|
|
@@ -11,9 +11,11 @@ interface Props {
|
|
|
11
11
|
}
|
|
12
12
|
interface SwiftHybridObjectRegistration {
|
|
13
13
|
cppCode: string;
|
|
14
|
-
|
|
14
|
+
swiftRegistrationClass: string;
|
|
15
15
|
requiredImports: SourceImport[];
|
|
16
16
|
}
|
|
17
|
+
export declare function getAutolinkingClassName(hybridObjectName: string): string;
|
|
18
|
+
export declare function getAutolinkingNamespace(): string;
|
|
17
19
|
export declare function getHybridObjectConstructorCall(hybridObjectName: string): string;
|
|
18
20
|
export declare function createSwiftHybridObjectRegistration({ hybridObjectName, swiftClassName, }: Props): SwiftHybridObjectRegistration;
|
|
19
21
|
export {};
|
|
@@ -3,27 +3,34 @@ import { indent } from '../../utils.js';
|
|
|
3
3
|
import { getHybridObjectName } from '../getHybridObjectName.js';
|
|
4
4
|
import { HybridObjectType } from '../types/HybridObjectType.js';
|
|
5
5
|
import { SwiftCxxBridgedType } from './SwiftCxxBridgedType.js';
|
|
6
|
-
export function
|
|
6
|
+
export function getAutolinkingClassName(hybridObjectName) {
|
|
7
|
+
return `Autolinked${hybridObjectName}`;
|
|
8
|
+
}
|
|
9
|
+
export function getAutolinkingNamespace() {
|
|
7
10
|
const swiftNamespace = NitroConfig.current.getIosModuleName();
|
|
8
11
|
const autolinkingClassName = `${swiftNamespace}Autolinking`;
|
|
9
|
-
return `${swiftNamespace}::${autolinkingClassName}
|
|
12
|
+
return `${swiftNamespace}::${autolinkingClassName}`;
|
|
13
|
+
}
|
|
14
|
+
export function getHybridObjectConstructorCall(hybridObjectName) {
|
|
15
|
+
const namespace = getAutolinkingNamespace();
|
|
16
|
+
const autolinkingClassName = getAutolinkingClassName(hybridObjectName);
|
|
17
|
+
return `${namespace}::${autolinkingClassName}::create();`;
|
|
10
18
|
}
|
|
11
19
|
export function createSwiftHybridObjectRegistration({ hybridObjectName, swiftClassName, }) {
|
|
12
|
-
const {
|
|
20
|
+
const { HybridTSpecSwift } = getHybridObjectName(hybridObjectName);
|
|
13
21
|
const type = new HybridObjectType(hybridObjectName, 'swift', [], NitroConfig.current);
|
|
14
22
|
const bridge = new SwiftCxxBridgedType(type);
|
|
23
|
+
const autolinkingClassName = getAutolinkingClassName(hybridObjectName);
|
|
15
24
|
return {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
let hybridObject = ${swiftClassName}()
|
|
26
|
-
return ${indent(bridge.parseFromSwiftToCpp('hybridObject', 'swift'), ' ')}
|
|
25
|
+
swiftRegistrationClass: `
|
|
26
|
+
public final class ${autolinkingClassName}: AutolinkedClass {
|
|
27
|
+
public static func create() -> ${bridge.getTypeCode('swift')} {
|
|
28
|
+
let hybridObject = ${swiftClassName}()
|
|
29
|
+
return ${indent(bridge.parseFromSwiftToCpp('hybridObject', 'swift'), ' ')}
|
|
30
|
+
}
|
|
31
|
+
public static var isRecyclableHybridView: Bool {
|
|
32
|
+
return ${swiftClassName}.self is any RecyclableView.Type
|
|
33
|
+
}
|
|
27
34
|
}
|
|
28
35
|
`.trim(),
|
|
29
36
|
requiredImports: [
|
|
@@ -26,13 +26,20 @@ import com.facebook.react.uimanager.ReactStylesDiffMap
|
|
|
26
26
|
import com.facebook.react.uimanager.SimpleViewManager
|
|
27
27
|
import com.facebook.react.uimanager.StateWrapper
|
|
28
28
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
29
|
+
import com.margelo.nitro.R.id.associated_hybrid_view_tag
|
|
30
|
+
import com.margelo.nitro.views.RecyclableView
|
|
29
31
|
import ${javaNamespace}.*
|
|
30
32
|
|
|
31
33
|
/**
|
|
32
34
|
* Represents the React Native \`ViewManager\` for the "${spec.name}" Nitro HybridView.
|
|
33
35
|
*/
|
|
34
36
|
open class ${manager}: SimpleViewManager<View>() {
|
|
35
|
-
|
|
37
|
+
init {
|
|
38
|
+
if (RecyclableView::class.java.isAssignableFrom(${viewImplementation}::class.java)) {
|
|
39
|
+
// Enable view recycling
|
|
40
|
+
super.setupViewRecycling()
|
|
41
|
+
}
|
|
42
|
+
}
|
|
36
43
|
|
|
37
44
|
override fun getName(): String {
|
|
38
45
|
return "${spec.name}"
|
|
@@ -41,17 +48,13 @@ open class ${manager}: SimpleViewManager<View>() {
|
|
|
41
48
|
override fun createViewInstance(reactContext: ThemedReactContext): View {
|
|
42
49
|
val hybridView = ${viewImplementation}(reactContext)
|
|
43
50
|
val view = hybridView.view
|
|
44
|
-
|
|
51
|
+
view.setTag(associated_hybrid_view_tag, hybridView)
|
|
45
52
|
return view
|
|
46
53
|
}
|
|
47
54
|
|
|
48
|
-
override fun onDropViewInstance(view: View) {
|
|
49
|
-
super.onDropViewInstance(view)
|
|
50
|
-
views.remove(view)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
55
|
override fun updateState(view: View, props: ReactStylesDiffMap, stateWrapper: StateWrapper): Any? {
|
|
54
|
-
val hybridView =
|
|
56
|
+
val hybridView = view.getTag(associated_hybrid_view_tag) as? ${viewImplementation}
|
|
57
|
+
?: throw Error("Couldn't find view $view in local views table!")
|
|
55
58
|
|
|
56
59
|
// 1. Update each prop individually
|
|
57
60
|
hybridView.beforeUpdate()
|
|
@@ -62,10 +65,21 @@ open class ${manager}: SimpleViewManager<View>() {
|
|
|
62
65
|
return super.updateState(view, props, stateWrapper)
|
|
63
66
|
}
|
|
64
67
|
|
|
65
|
-
protected override fun
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
68
|
+
protected override fun prepareToRecycleView(reactContext: ThemedReactContext, view: View): View? {
|
|
69
|
+
super.prepareToRecycleView(reactContext, view)
|
|
70
|
+
val hybridView = view.getTag(associated_hybrid_view_tag) as? ${viewImplementation}
|
|
71
|
+
?: return null
|
|
72
|
+
|
|
73
|
+
@Suppress("USELESS_IS_CHECK")
|
|
74
|
+
if (hybridView is RecyclableView) {
|
|
75
|
+
// Recycle in it's implementation
|
|
76
|
+
hybridView.prepareForRecycle()
|
|
77
|
+
|
|
78
|
+
// Maybe update the view if it changed
|
|
79
|
+
return hybridView.view
|
|
80
|
+
} else {
|
|
81
|
+
return null
|
|
82
|
+
}
|
|
69
83
|
}
|
|
70
84
|
}
|
|
71
85
|
`.trim();
|
|
@@ -2,7 +2,7 @@ import { createViewComponentShadowNodeFiles, getViewComponentNames, } from '../C
|
|
|
2
2
|
import { createFileMetadataString, escapeCppName, } from '../../syntax/helpers.js';
|
|
3
3
|
import { getUmbrellaHeaderName } from '../../autolinking/ios/createSwiftUmbrellaHeader.js';
|
|
4
4
|
import { getHybridObjectName } from '../../syntax/getHybridObjectName.js';
|
|
5
|
-
import { getHybridObjectConstructorCall } from '../../syntax/swift/SwiftHybridObjectRegistration.js';
|
|
5
|
+
import { getAutolinkingClassName, getAutolinkingNamespace, getHybridObjectConstructorCall, } from '../../syntax/swift/SwiftHybridObjectRegistration.js';
|
|
6
6
|
import { indent } from '../../utils.js';
|
|
7
7
|
import { SwiftCxxBridgedType } from '../../syntax/swift/SwiftCxxBridgedType.js';
|
|
8
8
|
export function createSwiftHybridViewManager(spec) {
|
|
@@ -68,11 +68,6 @@ using namespace ${namespace}::views;
|
|
|
68
68
|
return react::concreteComponentDescriptorProvider<${descriptorClassName}>();
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
+ (BOOL)shouldBeRecycled {
|
|
72
|
-
// TODO: Recycling should be controllable by the user. WIP, but disabled for now.
|
|
73
|
-
return NO;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
71
|
- (instancetype) init {
|
|
77
72
|
if (self = [super init]) {
|
|
78
73
|
std::shared_ptr<${HybridTSpec}> hybridView = ${getHybridObjectConstructorCall(spec.name)}
|
|
@@ -122,6 +117,16 @@ using namespace ${namespace}::views;
|
|
|
122
117
|
[super updateProps:props oldProps:oldProps];
|
|
123
118
|
}
|
|
124
119
|
|
|
120
|
+
+ (BOOL)shouldBeRecycled {
|
|
121
|
+
return ${getAutolinkingNamespace()}::${getAutolinkingClassName(spec.name)}::isRecyclableHybridView();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
- (void)prepareForRecycle {
|
|
125
|
+
[super prepareForRecycle];
|
|
126
|
+
${swiftNamespace}::${HybridTSpecCxx}& swiftPart = _hybridView->getSwiftPart();
|
|
127
|
+
swiftPart.maybePrepareForRecycle();
|
|
128
|
+
}
|
|
129
|
+
|
|
125
130
|
@end
|
|
126
131
|
`;
|
|
127
132
|
return [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nitrogen",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.33.1",
|
|
4
4
|
"description": "The code-generator for react-native-nitro-modules.",
|
|
5
5
|
"main": "lib/index",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"chalk": "^5.3.0",
|
|
38
|
-
"react-native-nitro-modules": "^0.
|
|
38
|
+
"react-native-nitro-modules": "^0.33.1",
|
|
39
39
|
"ts-morph": "^27.0.0",
|
|
40
40
|
"yargs": "^18.0.0",
|
|
41
41
|
"zod": "^4.0.5"
|
|
@@ -18,7 +18,7 @@ export function createHybridObjectIntializer(): [ObjcFile, SwiftFile] | [] {
|
|
|
18
18
|
const autolinkedHybridObjects =
|
|
19
19
|
NitroConfig.current.getAutolinkedHybridObjects()
|
|
20
20
|
|
|
21
|
-
const
|
|
21
|
+
const swiftRegistrations: string[] = []
|
|
22
22
|
const cppRegistrations: string[] = []
|
|
23
23
|
const cppImports: SourceImport[] = []
|
|
24
24
|
let containsSwiftObjects = false
|
|
@@ -37,14 +37,14 @@ export function createHybridObjectIntializer(): [ObjcFile, SwiftFile] | [] {
|
|
|
37
37
|
if (config?.swift != null) {
|
|
38
38
|
// Autolink a Swift HybridObject!
|
|
39
39
|
containsSwiftObjects = true
|
|
40
|
-
const { cppCode, requiredImports,
|
|
40
|
+
const { cppCode, requiredImports, swiftRegistrationClass } =
|
|
41
41
|
createSwiftHybridObjectRegistration({
|
|
42
42
|
hybridObjectName: hybridObjectName,
|
|
43
43
|
swiftClassName: config.swift,
|
|
44
44
|
})
|
|
45
45
|
cppImports.push(...requiredImports)
|
|
46
46
|
cppRegistrations.push(cppCode)
|
|
47
|
-
|
|
47
|
+
swiftRegistrations.push(swiftRegistrationClass)
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
@@ -86,10 +86,31 @@ ${imports}
|
|
|
86
86
|
const swiftCode = `
|
|
87
87
|
${createFileMetadataString(`${autolinkingClassName}.swift`)}
|
|
88
88
|
|
|
89
|
+
import NitroModules
|
|
90
|
+
|
|
91
|
+
// TODO: Use empty enums once Swift supports exporting them as namespaces
|
|
92
|
+
// See: https://github.com/swiftlang/swift/pull/83616
|
|
89
93
|
public final class ${autolinkingClassName} {
|
|
90
94
|
public typealias bridge = ${bridgeNamespace}
|
|
91
95
|
|
|
92
|
-
|
|
96
|
+
private protocol AutolinkedClass {
|
|
97
|
+
associatedtype T
|
|
98
|
+
/**
|
|
99
|
+
* Creates an instance of the Swift class that implements the HybridObject's spec,
|
|
100
|
+
* and wraps it in a Swift class that can directly interop with C++.
|
|
101
|
+
*
|
|
102
|
+
* This is generated by Nitrogen and will initialize the class specified
|
|
103
|
+
* in the \`"autolinking"\` property of \`nitro.json\`.
|
|
104
|
+
*/
|
|
105
|
+
static func create() -> T
|
|
106
|
+
/**
|
|
107
|
+
* Returns whether this concrete implementation is also
|
|
108
|
+
* conforming to the \`RecyclableView\` protocol, or not.
|
|
109
|
+
*/
|
|
110
|
+
static var isRecyclableHybridView: Bool { get }
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
${indent(swiftRegistrations.join('\n\n'), ' ')}
|
|
93
114
|
}
|
|
94
115
|
`.trim()
|
|
95
116
|
|
|
@@ -49,14 +49,14 @@ export function createSwiftHybridObject(spec: HybridObjectSpec): SourceFile[] {
|
|
|
49
49
|
`
|
|
50
50
|
public ${hasBaseClass ? 'override func' : 'func'} getCxxWrapper() -> ${name.HybridTSpecCxx} {
|
|
51
51
|
#if DEBUG
|
|
52
|
-
guard self is ${name.HybridTSpec} else {
|
|
52
|
+
guard self is any ${name.HybridTSpec} else {
|
|
53
53
|
fatalError("\`self\` is not a \`${name.HybridTSpec}\`! Did you accidentally inherit from \`${name.HybridTSpec}_base\` instead of \`${name.HybridTSpec}\`?")
|
|
54
54
|
}
|
|
55
55
|
#endif
|
|
56
56
|
if let cxxWrapper = self.cxxWrapper {
|
|
57
57
|
return cxxWrapper
|
|
58
58
|
} else {
|
|
59
|
-
let cxxWrapper = ${name.HybridTSpecCxx}(self as! ${name.HybridTSpec})
|
|
59
|
+
let cxxWrapper = ${name.HybridTSpecCxx}(self as! any ${name.HybridTSpec})
|
|
60
60
|
self.cxxWrapper = cxxWrapper
|
|
61
61
|
return cxxWrapper
|
|
62
62
|
}
|
|
@@ -63,6 +63,12 @@ public final func beforeUpdate() {
|
|
|
63
63
|
public final func afterUpdate() {
|
|
64
64
|
__implementation.afterUpdate()
|
|
65
65
|
}
|
|
66
|
+
`.trim(),
|
|
67
|
+
`
|
|
68
|
+
public final func maybePrepareForRecycle() {
|
|
69
|
+
guard let recyclable = __implementation as? RecyclableView else { return }
|
|
70
|
+
recyclable.prepareForRecycle()
|
|
71
|
+
}
|
|
66
72
|
`.trim()
|
|
67
73
|
)
|
|
68
74
|
}
|
|
@@ -18,24 +18,33 @@ interface Props {
|
|
|
18
18
|
|
|
19
19
|
interface SwiftHybridObjectRegistration {
|
|
20
20
|
cppCode: string
|
|
21
|
-
|
|
21
|
+
swiftRegistrationClass: string
|
|
22
22
|
requiredImports: SourceImport[]
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
export function getAutolinkingClassName(hybridObjectName: string): string {
|
|
26
|
+
return `Autolinked${hybridObjectName}`
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function getAutolinkingNamespace() {
|
|
30
|
+
const swiftNamespace = NitroConfig.current.getIosModuleName()
|
|
31
|
+
const autolinkingClassName = `${swiftNamespace}Autolinking`
|
|
32
|
+
return `${swiftNamespace}::${autolinkingClassName}`
|
|
33
|
+
}
|
|
34
|
+
|
|
25
35
|
export function getHybridObjectConstructorCall(
|
|
26
36
|
hybridObjectName: string
|
|
27
37
|
): string {
|
|
28
|
-
const
|
|
29
|
-
const autolinkingClassName =
|
|
30
|
-
return `${
|
|
38
|
+
const namespace = getAutolinkingNamespace()
|
|
39
|
+
const autolinkingClassName = getAutolinkingClassName(hybridObjectName)
|
|
40
|
+
return `${namespace}::${autolinkingClassName}::create();`
|
|
31
41
|
}
|
|
32
42
|
|
|
33
43
|
export function createSwiftHybridObjectRegistration({
|
|
34
44
|
hybridObjectName,
|
|
35
45
|
swiftClassName,
|
|
36
46
|
}: Props): SwiftHybridObjectRegistration {
|
|
37
|
-
const {
|
|
38
|
-
getHybridObjectName(hybridObjectName)
|
|
47
|
+
const { HybridTSpecSwift } = getHybridObjectName(hybridObjectName)
|
|
39
48
|
|
|
40
49
|
const type = new HybridObjectType(
|
|
41
50
|
hybridObjectName,
|
|
@@ -44,19 +53,18 @@ export function createSwiftHybridObjectRegistration({
|
|
|
44
53
|
NitroConfig.current
|
|
45
54
|
)
|
|
46
55
|
const bridge = new SwiftCxxBridgedType(type)
|
|
56
|
+
const autolinkingClassName = getAutolinkingClassName(hybridObjectName)
|
|
47
57
|
|
|
48
58
|
return {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
let hybridObject = ${swiftClassName}()
|
|
59
|
-
return ${indent(bridge.parseFromSwiftToCpp('hybridObject', 'swift'), ' ')}
|
|
59
|
+
swiftRegistrationClass: `
|
|
60
|
+
public final class ${autolinkingClassName}: AutolinkedClass {
|
|
61
|
+
public static func create() -> ${bridge.getTypeCode('swift')} {
|
|
62
|
+
let hybridObject = ${swiftClassName}()
|
|
63
|
+
return ${indent(bridge.parseFromSwiftToCpp('hybridObject', 'swift'), ' ')}
|
|
64
|
+
}
|
|
65
|
+
public static var isRecyclableHybridView: Bool {
|
|
66
|
+
return ${swiftClassName}.self is any RecyclableView.Type
|
|
67
|
+
}
|
|
60
68
|
}
|
|
61
69
|
`.trim(),
|
|
62
70
|
requiredImports: [
|
|
@@ -46,13 +46,20 @@ import com.facebook.react.uimanager.ReactStylesDiffMap
|
|
|
46
46
|
import com.facebook.react.uimanager.SimpleViewManager
|
|
47
47
|
import com.facebook.react.uimanager.StateWrapper
|
|
48
48
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
49
|
+
import com.margelo.nitro.R.id.associated_hybrid_view_tag
|
|
50
|
+
import com.margelo.nitro.views.RecyclableView
|
|
49
51
|
import ${javaNamespace}.*
|
|
50
52
|
|
|
51
53
|
/**
|
|
52
54
|
* Represents the React Native \`ViewManager\` for the "${spec.name}" Nitro HybridView.
|
|
53
55
|
*/
|
|
54
56
|
open class ${manager}: SimpleViewManager<View>() {
|
|
55
|
-
|
|
57
|
+
init {
|
|
58
|
+
if (RecyclableView::class.java.isAssignableFrom(${viewImplementation}::class.java)) {
|
|
59
|
+
// Enable view recycling
|
|
60
|
+
super.setupViewRecycling()
|
|
61
|
+
}
|
|
62
|
+
}
|
|
56
63
|
|
|
57
64
|
override fun getName(): String {
|
|
58
65
|
return "${spec.name}"
|
|
@@ -61,17 +68,13 @@ open class ${manager}: SimpleViewManager<View>() {
|
|
|
61
68
|
override fun createViewInstance(reactContext: ThemedReactContext): View {
|
|
62
69
|
val hybridView = ${viewImplementation}(reactContext)
|
|
63
70
|
val view = hybridView.view
|
|
64
|
-
|
|
71
|
+
view.setTag(associated_hybrid_view_tag, hybridView)
|
|
65
72
|
return view
|
|
66
73
|
}
|
|
67
74
|
|
|
68
|
-
override fun onDropViewInstance(view: View) {
|
|
69
|
-
super.onDropViewInstance(view)
|
|
70
|
-
views.remove(view)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
75
|
override fun updateState(view: View, props: ReactStylesDiffMap, stateWrapper: StateWrapper): Any? {
|
|
74
|
-
val hybridView =
|
|
76
|
+
val hybridView = view.getTag(associated_hybrid_view_tag) as? ${viewImplementation}
|
|
77
|
+
?: throw Error("Couldn't find view $view in local views table!")
|
|
75
78
|
|
|
76
79
|
// 1. Update each prop individually
|
|
77
80
|
hybridView.beforeUpdate()
|
|
@@ -82,10 +85,21 @@ open class ${manager}: SimpleViewManager<View>() {
|
|
|
82
85
|
return super.updateState(view, props, stateWrapper)
|
|
83
86
|
}
|
|
84
87
|
|
|
85
|
-
protected override fun
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
88
|
+
protected override fun prepareToRecycleView(reactContext: ThemedReactContext, view: View): View? {
|
|
89
|
+
super.prepareToRecycleView(reactContext, view)
|
|
90
|
+
val hybridView = view.getTag(associated_hybrid_view_tag) as? ${viewImplementation}
|
|
91
|
+
?: return null
|
|
92
|
+
|
|
93
|
+
@Suppress("USELESS_IS_CHECK")
|
|
94
|
+
if (hybridView is RecyclableView) {
|
|
95
|
+
// Recycle in it's implementation
|
|
96
|
+
hybridView.prepareForRecycle()
|
|
97
|
+
|
|
98
|
+
// Maybe update the view if it changed
|
|
99
|
+
return hybridView.view
|
|
100
|
+
} else {
|
|
101
|
+
return null
|
|
102
|
+
}
|
|
89
103
|
}
|
|
90
104
|
}
|
|
91
105
|
`.trim()
|
|
@@ -10,7 +10,11 @@ import {
|
|
|
10
10
|
} from '../../syntax/helpers.js'
|
|
11
11
|
import { getUmbrellaHeaderName } from '../../autolinking/ios/createSwiftUmbrellaHeader.js'
|
|
12
12
|
import { getHybridObjectName } from '../../syntax/getHybridObjectName.js'
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
getAutolinkingClassName,
|
|
15
|
+
getAutolinkingNamespace,
|
|
16
|
+
getHybridObjectConstructorCall,
|
|
17
|
+
} from '../../syntax/swift/SwiftHybridObjectRegistration.js'
|
|
14
18
|
import { indent } from '../../utils.js'
|
|
15
19
|
import { SwiftCxxBridgedType } from '../../syntax/swift/SwiftCxxBridgedType.js'
|
|
16
20
|
|
|
@@ -89,11 +93,6 @@ using namespace ${namespace}::views;
|
|
|
89
93
|
return react::concreteComponentDescriptorProvider<${descriptorClassName}>();
|
|
90
94
|
}
|
|
91
95
|
|
|
92
|
-
+ (BOOL)shouldBeRecycled {
|
|
93
|
-
// TODO: Recycling should be controllable by the user. WIP, but disabled for now.
|
|
94
|
-
return NO;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
96
|
- (instancetype) init {
|
|
98
97
|
if (self = [super init]) {
|
|
99
98
|
std::shared_ptr<${HybridTSpec}> hybridView = ${getHybridObjectConstructorCall(spec.name)}
|
|
@@ -143,6 +142,16 @@ using namespace ${namespace}::views;
|
|
|
143
142
|
[super updateProps:props oldProps:oldProps];
|
|
144
143
|
}
|
|
145
144
|
|
|
145
|
+
+ (BOOL)shouldBeRecycled {
|
|
146
|
+
return ${getAutolinkingNamespace()}::${getAutolinkingClassName(spec.name)}::isRecyclableHybridView();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
- (void)prepareForRecycle {
|
|
150
|
+
[super prepareForRecycle];
|
|
151
|
+
${swiftNamespace}::${HybridTSpecCxx}& swiftPart = _hybridView->getSwiftPart();
|
|
152
|
+
swiftPart.maybePrepareForRecycle();
|
|
153
|
+
}
|
|
154
|
+
|
|
146
155
|
@end
|
|
147
156
|
`
|
|
148
157
|
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { Language } from '../../getPlatformSpecs.js';
|
|
2
|
-
import type { SourceFile, SourceImport } from '../SourceFile.js';
|
|
3
|
-
import type { Type, TypeKind } from './Type.js';
|
|
4
|
-
export declare class Int32Type implements Type {
|
|
5
|
-
get canBePassedByReference(): boolean;
|
|
6
|
-
get kind(): TypeKind;
|
|
7
|
-
getCode(language: Language): string;
|
|
8
|
-
getExtraFiles(): SourceFile[];
|
|
9
|
-
getRequiredImports(language: Language): SourceImport[];
|
|
10
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
export class Int32Type {
|
|
2
|
-
get canBePassedByReference() {
|
|
3
|
-
// It's a primitive
|
|
4
|
-
return false;
|
|
5
|
-
}
|
|
6
|
-
get kind() {
|
|
7
|
-
return 'int32';
|
|
8
|
-
}
|
|
9
|
-
getCode(language) {
|
|
10
|
-
switch (language) {
|
|
11
|
-
case 'c++':
|
|
12
|
-
return 'int32_t';
|
|
13
|
-
case 'swift':
|
|
14
|
-
return 'Int32';
|
|
15
|
-
case 'kotlin':
|
|
16
|
-
return 'Int';
|
|
17
|
-
default:
|
|
18
|
-
throw new Error(`Language ${language} is not yet supported for Int32Type!`);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
getExtraFiles() {
|
|
22
|
-
return [];
|
|
23
|
-
}
|
|
24
|
-
getRequiredImports(language) {
|
|
25
|
-
if (language === 'c++') {
|
|
26
|
-
return [
|
|
27
|
-
{
|
|
28
|
-
language: language,
|
|
29
|
-
name: 'cstdint',
|
|
30
|
-
space: 'system',
|
|
31
|
-
},
|
|
32
|
-
];
|
|
33
|
-
}
|
|
34
|
-
return [];
|
|
35
|
-
}
|
|
36
|
-
}
|