@react-native/codegen 0.76.0-nightly-20240701-TEMP → 0.76.0-nightly-20240702-ad3df8466

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.
@@ -82,13 +82,16 @@ const _require = require('../../parsers/parsers-commons'),
82
82
  unwrapNullable = _require.unwrapNullable;
83
83
  const _require2 = require('../TypeUtils/Java'),
84
84
  wrapOptional = _require2.wrapOptional;
85
- const _require3 = require('./Utils'),
86
- createAliasResolver = _require3.createAliasResolver,
87
- getModules = _require3.getModules;
85
+ const _require3 = require('../Utils'),
86
+ toPascalCase = _require3.toPascalCase;
87
+ const _require4 = require('./Utils'),
88
+ createAliasResolver = _require4.createAliasResolver,
89
+ getModules = _require4.getModules;
88
90
  function FileTemplate(config) {
89
91
  const packageName = config.packageName,
90
92
  className = config.className,
91
93
  jsName = config.jsName,
94
+ eventEmitters = config.eventEmitters,
92
95
  methods = config.methods,
93
96
  imports = config.imports;
94
97
  return `
@@ -119,10 +122,23 @@ public abstract class ${className} extends ReactContextBaseJavaModule implements
119
122
  return NAME;
120
123
  }
121
124
 
122
- ${methods}
125
+ ${eventEmitters}${eventEmitters.length > 0 ? '\n\n' : ''}${methods}
123
126
  }
124
127
  `;
125
128
  }
129
+ function EventEmitterTemplate(eventEmitter, imports) {
130
+ return ` protected final void emit${toPascalCase(eventEmitter.name)}(${
131
+ eventEmitter.typeAnnotation.typeAnnotation.type !== 'VoidTypeAnnotation'
132
+ ? `${translateEventEmitterTypeToJavaType(eventEmitter, imports)} value`
133
+ : ''
134
+ }) {
135
+ mEventEmitterCallback.invoke("${eventEmitter.name}"${
136
+ eventEmitter.typeAnnotation.typeAnnotation.type !== 'VoidTypeAnnotation'
137
+ ? ', value'
138
+ : ''
139
+ });
140
+ }`;
141
+ }
126
142
  function MethodTemplate(config) {
127
143
  const abstract = config.abstract,
128
144
  methodBody = config.methodBody,
@@ -141,6 +157,30 @@ function MethodTemplate(config) {
141
157
  ', ',
142
158
  )})${methodClosing}`;
143
159
  }
160
+ function translateEventEmitterTypeToJavaType(eventEmitter, imports) {
161
+ switch (eventEmitter.typeAnnotation.typeAnnotation.type) {
162
+ case 'StringTypeAnnotation':
163
+ return 'String';
164
+ case 'NumberTypeAnnotation':
165
+ case 'FloatTypeAnnotation':
166
+ case 'DoubleTypeAnnotation':
167
+ case 'Int32TypeAnnotation':
168
+ return 'double';
169
+ case 'BooleanTypeAnnotation':
170
+ return 'boolean';
171
+ case 'ObjectTypeAnnotation':
172
+ case 'TypeAliasTypeAnnotation':
173
+ imports.add('com.facebook.react.bridge.ReadableMap');
174
+ return 'ReadableMap';
175
+ case 'ArrayTypeAnnotation':
176
+ imports.add('com.facebook.react.bridge.ReadableArray');
177
+ return 'ReadableArray';
178
+ default:
179
+ throw new Error(
180
+ `Unsupported eventType for ${eventEmitter.name}. Found: ${eventEmitter.typeAnnotation.typeAnnotation.type}`,
181
+ );
182
+ }
183
+ }
144
184
  function translateFunctionParamToJavaType(
145
185
  param,
146
186
  createErrorMessage,
@@ -552,6 +592,9 @@ module.exports = {
552
592
  packageName: normalizedPackageName,
553
593
  className,
554
594
  jsName: moduleName,
595
+ eventEmitters: spec.eventEmitters
596
+ .map(eventEmitter => EventEmitterTemplate(eventEmitter, imports))
597
+ .join('\n\n'),
555
598
  methods: methods.filter(Boolean).join('\n\n'),
556
599
  imports: Array.from(imports)
557
600
  .sort()
@@ -12,6 +12,7 @@
12
12
 
13
13
  import type {
14
14
  NamedShape,
15
+ NativeModuleEventEmitterShape,
15
16
  NativeModuleFunctionTypeAnnotation,
16
17
  NativeModuleParamTypeAnnotation,
17
18
  NativeModulePropertyShape,
@@ -23,6 +24,7 @@ import type {AliasResolver} from './Utils';
23
24
 
24
25
  const {unwrapNullable} = require('../../parsers/parsers-commons');
25
26
  const {wrapOptional} = require('../TypeUtils/Java');
27
+ const {toPascalCase} = require('../Utils');
26
28
  const {createAliasResolver, getModules} = require('./Utils');
27
29
 
28
30
  type FilesOutput = Map<string, string>;
@@ -32,11 +34,13 @@ function FileTemplate(
32
34
  packageName: string,
33
35
  className: string,
34
36
  jsName: string,
37
+ eventEmitters: string,
35
38
  methods: string,
36
39
  imports: string,
37
40
  }>,
38
41
  ): string {
39
- const {packageName, className, jsName, methods, imports} = config;
42
+ const {packageName, className, jsName, eventEmitters, methods, imports} =
43
+ config;
40
44
  return `
41
45
  /**
42
46
  * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
@@ -65,11 +69,28 @@ public abstract class ${className} extends ReactContextBaseJavaModule implements
65
69
  return NAME;
66
70
  }
67
71
 
68
- ${methods}
72
+ ${eventEmitters}${eventEmitters.length > 0 ? '\n\n' : ''}${methods}
69
73
  }
70
74
  `;
71
75
  }
72
76
 
77
+ function EventEmitterTemplate(
78
+ eventEmitter: NativeModuleEventEmitterShape,
79
+ imports: Set<string>,
80
+ ): string {
81
+ return ` protected final void emit${toPascalCase(eventEmitter.name)}(${
82
+ eventEmitter.typeAnnotation.typeAnnotation.type !== 'VoidTypeAnnotation'
83
+ ? `${translateEventEmitterTypeToJavaType(eventEmitter, imports)} value`
84
+ : ''
85
+ }) {
86
+ mEventEmitterCallback.invoke("${eventEmitter.name}"${
87
+ eventEmitter.typeAnnotation.typeAnnotation.type !== 'VoidTypeAnnotation'
88
+ ? ', value'
89
+ : ''
90
+ });
91
+ }`;
92
+ }
93
+
73
94
  function MethodTemplate(
74
95
  config: $ReadOnly<{
75
96
  abstract: boolean,
@@ -102,6 +123,34 @@ function MethodTemplate(
102
123
 
103
124
  type Param = NamedShape<Nullable<NativeModuleParamTypeAnnotation>>;
104
125
 
126
+ function translateEventEmitterTypeToJavaType(
127
+ eventEmitter: NativeModuleEventEmitterShape,
128
+ imports: Set<string>,
129
+ ): string {
130
+ switch (eventEmitter.typeAnnotation.typeAnnotation.type) {
131
+ case 'StringTypeAnnotation':
132
+ return 'String';
133
+ case 'NumberTypeAnnotation':
134
+ case 'FloatTypeAnnotation':
135
+ case 'DoubleTypeAnnotation':
136
+ case 'Int32TypeAnnotation':
137
+ return 'double';
138
+ case 'BooleanTypeAnnotation':
139
+ return 'boolean';
140
+ case 'ObjectTypeAnnotation':
141
+ case 'TypeAliasTypeAnnotation':
142
+ imports.add('com.facebook.react.bridge.ReadableMap');
143
+ return 'ReadableMap';
144
+ case 'ArrayTypeAnnotation':
145
+ imports.add('com.facebook.react.bridge.ReadableArray');
146
+ return 'ReadableArray';
147
+ default:
148
+ throw new Error(
149
+ `Unsupported eventType for ${eventEmitter.name}. Found: ${eventEmitter.typeAnnotation.typeAnnotation.type}`,
150
+ );
151
+ }
152
+ }
153
+
105
154
  function translateFunctionParamToJavaType(
106
155
  param: Param,
107
156
  createErrorMessage: (typeName: string) => string,
@@ -533,6 +582,9 @@ module.exports = {
533
582
  packageName: normalizedPackageName,
534
583
  className,
535
584
  jsName: moduleName,
585
+ eventEmitters: spec.eventEmitters
586
+ .map(eventEmitter => EventEmitterTemplate(eventEmitter, imports))
587
+ .join('\n\n'),
536
588
  methods: methods.filter(Boolean).join('\n\n'),
537
589
  imports: Array.from(imports)
538
590
  .sort()
@@ -94,7 +94,11 @@ const HostFunctionTemplate = ({
94
94
  return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, ${jsReturnType}, "${propertyName}", "${jniSignature}", args, count, cachedMethodId);
95
95
  }`;
96
96
  };
97
- const ModuleClassConstructorTemplate = ({hasteModuleName, methods}) => {
97
+ const ModuleClassConstructorTemplate = ({
98
+ hasteModuleName,
99
+ eventEmitters,
100
+ methods,
101
+ }) => {
98
102
  return `
99
103
  ${hasteModuleName}SpecJSI::${hasteModuleName}SpecJSI(const JavaTurboModule::InitParams &params)
100
104
  : JavaTurboModule(params) {
@@ -102,7 +106,21 @@ ${methods
102
106
  .map(({propertyName, argCount}) => {
103
107
  return ` methodMap_["${propertyName}"] = MethodMetadata {${argCount}, __hostFunction_${hasteModuleName}SpecJSI_${propertyName}};`;
104
108
  })
105
- .join('\n')}
109
+ .join('\n')}${
110
+ eventEmitters.length > 0
111
+ ? eventEmitters
112
+ .map(eventEmitter => {
113
+ return `
114
+ eventEmitterMap_["${eventEmitter.name}"] = std::make_shared<AsyncEventEmitter<folly::dynamic>>();`;
115
+ })
116
+ .join('')
117
+ : ''
118
+ }${
119
+ eventEmitters.length > 0
120
+ ? `
121
+ setEventEmitterCallback(params.instance);`
122
+ : ''
123
+ }
106
124
  }`.trim();
107
125
  };
108
126
  const ModuleLookupTemplate = ({moduleName, hasteModuleName}) => {
@@ -433,7 +451,9 @@ module.exports = {
433
451
  .map(hasteModuleName => {
434
452
  const _nativeModules$hasteM = nativeModules[hasteModuleName],
435
453
  aliasMap = _nativeModules$hasteM.aliasMap,
436
- methods = _nativeModules$hasteM.spec.methods;
454
+ _nativeModules$hasteM2 = _nativeModules$hasteM.spec,
455
+ eventEmitters = _nativeModules$hasteM2.eventEmitters,
456
+ methods = _nativeModules$hasteM2.methods;
437
457
  const resolveAlias = createAliasResolver(aliasMap);
438
458
  const translatedMethods = methods
439
459
  .map(property =>
@@ -449,6 +469,7 @@ module.exports = {
449
469
  '\n\n' +
450
470
  ModuleClassConstructorTemplate({
451
471
  hasteModuleName,
472
+ eventEmitters,
452
473
  methods: methods
453
474
  .map(({name: propertyName, typeAnnotation}) => {
454
475
  const _unwrapNullable11 = unwrapNullable(typeAnnotation),
@@ -12,6 +12,7 @@
12
12
 
13
13
  import type {
14
14
  NamedShape,
15
+ NativeModuleEventEmitterShape,
15
16
  NativeModuleFunctionTypeAnnotation,
16
17
  NativeModuleParamTypeAnnotation,
17
18
  NativeModulePropertyShape,
@@ -54,9 +55,11 @@ const HostFunctionTemplate = ({
54
55
 
55
56
  const ModuleClassConstructorTemplate = ({
56
57
  hasteModuleName,
58
+ eventEmitters,
57
59
  methods,
58
60
  }: $ReadOnly<{
59
61
  hasteModuleName: string,
62
+ eventEmitters: $ReadOnlyArray<NativeModuleEventEmitterShape>,
60
63
  methods: $ReadOnlyArray<{
61
64
  propertyName: string,
62
65
  argCount: number,
@@ -69,7 +72,21 @@ ${methods
69
72
  .map(({propertyName, argCount}) => {
70
73
  return ` methodMap_["${propertyName}"] = MethodMetadata {${argCount}, __hostFunction_${hasteModuleName}SpecJSI_${propertyName}};`;
71
74
  })
72
- .join('\n')}
75
+ .join('\n')}${
76
+ eventEmitters.length > 0
77
+ ? eventEmitters
78
+ .map(eventEmitter => {
79
+ return `
80
+ eventEmitterMap_["${eventEmitter.name}"] = std::make_shared<AsyncEventEmitter<folly::dynamic>>();`;
81
+ })
82
+ .join('')
83
+ : ''
84
+ }${
85
+ eventEmitters.length > 0
86
+ ? `
87
+ setEventEmitterCallback(params.instance);`
88
+ : ''
89
+ }
73
90
  }`.trim();
74
91
  };
75
92
 
@@ -438,7 +455,7 @@ module.exports = {
438
455
  .map(hasteModuleName => {
439
456
  const {
440
457
  aliasMap,
441
- spec: {methods},
458
+ spec: {eventEmitters, methods},
442
459
  } = nativeModules[hasteModuleName];
443
460
  const resolveAlias = createAliasResolver(aliasMap);
444
461
 
@@ -457,6 +474,7 @@ module.exports = {
457
474
  '\n\n' +
458
475
  ModuleClassConstructorTemplate({
459
476
  hasteModuleName,
477
+ eventEmitters,
460
478
  methods: methods
461
479
  .map(({name: propertyName, typeAnnotation}) => {
462
480
  const [{returnTypeAnnotation, params}] =
@@ -15,15 +15,18 @@ const _require = require('../Utils'),
15
15
  getModules = _require.getModules;
16
16
  const _require2 = require('./header/serializeStruct'),
17
17
  serializeStruct = _require2.serializeStruct;
18
- const _require3 = require('./serializeMethod'),
19
- serializeMethod = _require3.serializeMethod;
20
- const _require4 = require('./source/serializeModule'),
21
- serializeModuleSource = _require4.serializeModuleSource;
22
- const _require5 = require('./StructCollector'),
23
- StructCollector = _require5.StructCollector;
18
+ const _require3 = require('./serializeEventEmitter'),
19
+ EventEmitterHeaderTemplate = _require3.EventEmitterHeaderTemplate;
20
+ const _require4 = require('./serializeMethod'),
21
+ serializeMethod = _require4.serializeMethod;
22
+ const _require5 = require('./source/serializeModule'),
23
+ serializeModuleSource = _require5.serializeModuleSource;
24
+ const _require6 = require('./StructCollector'),
25
+ StructCollector = _require6.StructCollector;
24
26
  const ModuleDeclarationTemplate = ({
25
27
  hasteModuleName,
26
28
  structDeclarations,
29
+ eventEmitters,
27
30
  protocolMethods,
28
31
  }) => `${structDeclarations}
29
32
  @protocol ${hasteModuleName}Spec <RCTBridgeModule, RCTTurboModule>
@@ -32,7 +35,13 @@ ${protocolMethods}
32
35
 
33
36
  @end
34
37
 
35
- @interface ${hasteModuleName}SpecBase : NSObject
38
+ @interface ${hasteModuleName}SpecBase : NSObject {
39
+ @protected
40
+ facebook::react::EventEmitterCallback _eventEmitterCallback;
41
+ }
42
+ - (void)setEventEmitterCallback:(EventEmitterCallbackWrapper *)eventEmitterCallbackWrapper;
43
+
44
+ ${eventEmitters}
36
45
  @end
37
46
 
38
47
  namespace facebook::react {
@@ -164,6 +173,9 @@ module.exports = {
164
173
  ModuleDeclarationTemplate({
165
174
  hasteModuleName: hasteModuleName,
166
175
  structDeclarations: structStrs.join('\n'),
176
+ eventEmitters: spec.eventEmitters
177
+ .map(eventEmitter => EventEmitterHeaderTemplate(eventEmitter))
178
+ .join('\n'),
167
179
  protocolMethods: methodSerializations
168
180
  .map(({protocolMethod}) => protocolMethod)
169
181
  .join('\n'),
@@ -175,6 +187,7 @@ module.exports = {
175
187
  hasteModuleName,
176
188
  generatedStructs,
177
189
  hasteModuleName,
190
+ spec.eventEmitters,
178
191
  methodSerializations.filter(
179
192
  ({selector}) => selector !== '@selector(constantsToExport)',
180
193
  ),
@@ -15,6 +15,7 @@ import type {MethodSerializationOutput} from './serializeMethod';
15
15
 
16
16
  const {createAliasResolver, getModules} = require('../Utils');
17
17
  const {serializeStruct} = require('./header/serializeStruct');
18
+ const {EventEmitterHeaderTemplate} = require('./serializeEventEmitter');
18
19
  const {serializeMethod} = require('./serializeMethod');
19
20
  const {serializeModuleSource} = require('./source/serializeModule');
20
21
  const {StructCollector} = require('./StructCollector');
@@ -24,10 +25,12 @@ type FilesOutput = Map<string, string>;
24
25
  const ModuleDeclarationTemplate = ({
25
26
  hasteModuleName,
26
27
  structDeclarations,
28
+ eventEmitters,
27
29
  protocolMethods,
28
30
  }: $ReadOnly<{
29
31
  hasteModuleName: string,
30
32
  structDeclarations: string,
33
+ eventEmitters: string,
31
34
  protocolMethods: string,
32
35
  }>) => `${structDeclarations}
33
36
  @protocol ${hasteModuleName}Spec <RCTBridgeModule, RCTTurboModule>
@@ -36,7 +39,13 @@ ${protocolMethods}
36
39
 
37
40
  @end
38
41
 
39
- @interface ${hasteModuleName}SpecBase : NSObject
42
+ @interface ${hasteModuleName}SpecBase : NSObject {
43
+ @protected
44
+ facebook::react::EventEmitterCallback _eventEmitterCallback;
45
+ }
46
+ - (void)setEventEmitterCallback:(EventEmitterCallbackWrapper *)eventEmitterCallbackWrapper;
47
+
48
+ ${eventEmitters}
40
49
  @end
41
50
 
42
51
  namespace facebook::react {
@@ -191,6 +200,9 @@ module.exports = {
191
200
  ModuleDeclarationTemplate({
192
201
  hasteModuleName: hasteModuleName,
193
202
  structDeclarations: structStrs.join('\n'),
203
+ eventEmitters: spec.eventEmitters
204
+ .map(eventEmitter => EventEmitterHeaderTemplate(eventEmitter))
205
+ .join('\n'),
194
206
  protocolMethods: methodSerializations
195
207
  .map(({protocolMethod}) => protocolMethod)
196
208
  .join('\n'),
@@ -204,6 +216,7 @@ module.exports = {
204
216
  hasteModuleName,
205
217
  generatedStructs,
206
218
  hasteModuleName,
219
+ spec.eventEmitters,
207
220
  methodSerializations.filter(
208
221
  ({selector}) => selector !== '@selector(constantsToExport)',
209
222
  ),
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ *
8
+ * @format
9
+ */
10
+
11
+ const _require = require('../../Utils'),
12
+ toPascalCase = _require.toPascalCase;
13
+ function getEventEmitterTypeObjCType(eventEmitter) {
14
+ switch (eventEmitter.typeAnnotation.typeAnnotation.type) {
15
+ case 'StringTypeAnnotation':
16
+ return 'NSString *_Nonnull';
17
+ case 'NumberTypeAnnotation':
18
+ return 'NSNumber *_Nonnull';
19
+ case 'BooleanTypeAnnotation':
20
+ return 'BOOL';
21
+ case 'ObjectTypeAnnotation':
22
+ case 'TypeAliasTypeAnnotation':
23
+ return 'NSDictionary *';
24
+ case 'ArrayTypeAnnotation':
25
+ return 'NSArray<id<NSObject>> *';
26
+ default:
27
+ throw new Error(
28
+ `Unsupported eventType for ${eventEmitter.name}. Found: ${eventEmitter.typeAnnotation.typeAnnotation.type}`,
29
+ );
30
+ }
31
+ }
32
+ function EventEmitterHeaderTemplate(eventEmitter) {
33
+ return `- (void)emit${toPascalCase(eventEmitter.name)}${
34
+ eventEmitter.typeAnnotation.typeAnnotation.type !== 'VoidTypeAnnotation'
35
+ ? `:(${getEventEmitterTypeObjCType(eventEmitter)})value`
36
+ : ''
37
+ };`;
38
+ }
39
+ function EventEmitterImplementationTemplate(eventEmitter) {
40
+ return `- (void)emit${toPascalCase(eventEmitter.name)}${
41
+ eventEmitter.typeAnnotation.typeAnnotation.type !== 'VoidTypeAnnotation'
42
+ ? `:(${getEventEmitterTypeObjCType(eventEmitter)})value`
43
+ : ''
44
+ }
45
+ {
46
+ _eventEmitterCallback("${eventEmitter.name}", ${
47
+ eventEmitter.typeAnnotation.typeAnnotation.type !== 'VoidTypeAnnotation'
48
+ ? eventEmitter.typeAnnotation.typeAnnotation.type !==
49
+ 'BooleanTypeAnnotation'
50
+ ? 'value'
51
+ : '[NSNumber numberWithBool:value]'
52
+ : 'nil'
53
+ });
54
+ }`;
55
+ }
56
+ module.exports = {
57
+ EventEmitterHeaderTemplate,
58
+ EventEmitterImplementationTemplate,
59
+ };
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow strict
8
+ * @format
9
+ */
10
+
11
+ import type {NativeModuleEventEmitterShape} from '../../../CodegenSchema';
12
+
13
+ const {toPascalCase} = require('../../Utils');
14
+
15
+ function getEventEmitterTypeObjCType(
16
+ eventEmitter: NativeModuleEventEmitterShape,
17
+ ): string {
18
+ switch (eventEmitter.typeAnnotation.typeAnnotation.type) {
19
+ case 'StringTypeAnnotation':
20
+ return 'NSString *_Nonnull';
21
+ case 'NumberTypeAnnotation':
22
+ return 'NSNumber *_Nonnull';
23
+ case 'BooleanTypeAnnotation':
24
+ return 'BOOL';
25
+ case 'ObjectTypeAnnotation':
26
+ case 'TypeAliasTypeAnnotation':
27
+ return 'NSDictionary *';
28
+ case 'ArrayTypeAnnotation':
29
+ return 'NSArray<id<NSObject>> *';
30
+ default:
31
+ throw new Error(
32
+ `Unsupported eventType for ${eventEmitter.name}. Found: ${eventEmitter.typeAnnotation.typeAnnotation.type}`,
33
+ );
34
+ }
35
+ }
36
+
37
+ function EventEmitterHeaderTemplate(
38
+ eventEmitter: NativeModuleEventEmitterShape,
39
+ ): string {
40
+ return `- (void)emit${toPascalCase(eventEmitter.name)}${
41
+ eventEmitter.typeAnnotation.typeAnnotation.type !== 'VoidTypeAnnotation'
42
+ ? `:(${getEventEmitterTypeObjCType(eventEmitter)})value`
43
+ : ''
44
+ };`;
45
+ }
46
+
47
+ function EventEmitterImplementationTemplate(
48
+ eventEmitter: NativeModuleEventEmitterShape,
49
+ ): string {
50
+ return `- (void)emit${toPascalCase(eventEmitter.name)}${
51
+ eventEmitter.typeAnnotation.typeAnnotation.type !== 'VoidTypeAnnotation'
52
+ ? `:(${getEventEmitterTypeObjCType(eventEmitter)})value`
53
+ : ''
54
+ }
55
+ {
56
+ _eventEmitterCallback("${eventEmitter.name}", ${
57
+ eventEmitter.typeAnnotation.typeAnnotation.type !== 'VoidTypeAnnotation'
58
+ ? eventEmitter.typeAnnotation.typeAnnotation.type !==
59
+ 'BooleanTypeAnnotation'
60
+ ? 'value'
61
+ : '[NSNumber numberWithBool:value]'
62
+ : 'nil'
63
+ });
64
+ }`;
65
+ }
66
+
67
+ module.exports = {
68
+ EventEmitterHeaderTemplate,
69
+ EventEmitterImplementationTemplate,
70
+ };
@@ -10,13 +10,25 @@
10
10
 
11
11
  'use strict';
12
12
 
13
+ const _require = require('./../serializeEventEmitter'),
14
+ EventEmitterImplementationTemplate =
15
+ _require.EventEmitterImplementationTemplate;
13
16
  const ModuleTemplate = ({
14
17
  hasteModuleName,
15
18
  structs,
16
19
  moduleName,
20
+ eventEmitters,
17
21
  methodSerializationOutputs,
18
22
  }) => `
19
23
  @implementation ${hasteModuleName}SpecBase
24
+ ${eventEmitters
25
+ .map(eventEmitter => EventEmitterImplementationTemplate(eventEmitter))
26
+ .join('\n')}
27
+
28
+ - (void)setEventEmitterCallback:(EventEmitterCallbackWrapper *)eventEmitterCallbackWrapper
29
+ {
30
+ _eventEmitterCallback = std::move(eventEmitterCallbackWrapper->_eventEmitterCallback);
31
+ }
20
32
  @end
21
33
 
22
34
  ${structs
@@ -50,7 +62,23 @@ namespace facebook::react {
50
62
  argCount,
51
63
  }),
52
64
  )
53
- .join('\n' + ' '.repeat(8))}
65
+ .join('\n' + ' '.repeat(8))}${
66
+ eventEmitters.length > 0
67
+ ? eventEmitters
68
+ .map(eventEmitter => {
69
+ return `
70
+ eventEmitterMap_["${eventEmitter.name}"] = std::make_shared<AsyncEventEmitter<id>>();`;
71
+ })
72
+ .join('')
73
+ : ''
74
+ }${
75
+ eventEmitters.length > 0
76
+ ? `
77
+ setEventEmitterCallback([&](const std::string &name, id value) {
78
+ static_cast<AsyncEventEmitter<id> &>(*eventEmitterMap_[name]).emit(value);
79
+ });`
80
+ : ''
81
+ }
54
82
  }
55
83
  } // namespace facebook::react`;
56
84
  const RCTCxxConvertCategoryTemplate = ({
@@ -87,12 +115,14 @@ function serializeModuleSource(
87
115
  hasteModuleName,
88
116
  structs,
89
117
  moduleName,
118
+ eventEmitters,
90
119
  methodSerializationOutputs,
91
120
  ) {
92
121
  return ModuleTemplate({
93
122
  hasteModuleName,
94
123
  structs: structs.filter(({context}) => context !== 'CONSTANTS'),
95
124
  moduleName,
125
+ eventEmitters,
96
126
  methodSerializationOutputs,
97
127
  });
98
128
  }
@@ -10,24 +10,39 @@
10
10
 
11
11
  'use strict';
12
12
 
13
+ import type {NativeModuleEventEmitterShape} from '../../../../CodegenSchema';
13
14
  import type {
14
15
  MethodSerializationOutput,
15
16
  StructParameterRecord,
16
17
  } from '../serializeMethod';
17
18
  import type {Struct} from '../StructCollector';
18
19
 
20
+ const {
21
+ EventEmitterImplementationTemplate,
22
+ } = require('./../serializeEventEmitter');
23
+
19
24
  const ModuleTemplate = ({
20
25
  hasteModuleName,
21
26
  structs,
22
27
  moduleName,
28
+ eventEmitters,
23
29
  methodSerializationOutputs,
24
30
  }: $ReadOnly<{
25
31
  hasteModuleName: string,
26
32
  structs: $ReadOnlyArray<Struct>,
27
33
  moduleName: string,
34
+ eventEmitters: $ReadOnlyArray<NativeModuleEventEmitterShape>,
28
35
  methodSerializationOutputs: $ReadOnlyArray<MethodSerializationOutput>,
29
36
  }>) => `
30
37
  @implementation ${hasteModuleName}SpecBase
38
+ ${eventEmitters
39
+ .map(eventEmitter => EventEmitterImplementationTemplate(eventEmitter))
40
+ .join('\n')}
41
+
42
+ - (void)setEventEmitterCallback:(EventEmitterCallbackWrapper *)eventEmitterCallbackWrapper
43
+ {
44
+ _eventEmitterCallback = std::move(eventEmitterCallbackWrapper->_eventEmitterCallback);
45
+ }
31
46
  @end
32
47
 
33
48
  ${structs
@@ -58,7 +73,23 @@ namespace facebook::react {
58
73
  argCount,
59
74
  }),
60
75
  )
61
- .join('\n' + ' '.repeat(8))}
76
+ .join('\n' + ' '.repeat(8))}${
77
+ eventEmitters.length > 0
78
+ ? eventEmitters
79
+ .map(eventEmitter => {
80
+ return `
81
+ eventEmitterMap_["${eventEmitter.name}"] = std::make_shared<AsyncEventEmitter<id>>();`;
82
+ })
83
+ .join('')
84
+ : ''
85
+ }${
86
+ eventEmitters.length > 0
87
+ ? `
88
+ setEventEmitterCallback([&](const std::string &name, id value) {
89
+ static_cast<AsyncEventEmitter<id> &>(*eventEmitterMap_[name]).emit(value);
90
+ });`
91
+ : ''
92
+ }
62
93
  }
63
94
  } // namespace facebook::react`;
64
95
 
@@ -112,12 +143,14 @@ function serializeModuleSource(
112
143
  hasteModuleName: string,
113
144
  structs: $ReadOnlyArray<Struct>,
114
145
  moduleName: string,
146
+ eventEmitters: $ReadOnlyArray<NativeModuleEventEmitterShape>,
115
147
  methodSerializationOutputs: $ReadOnlyArray<MethodSerializationOutput>,
116
148
  ): string {
117
149
  return ModuleTemplate({
118
150
  hasteModuleName,
119
151
  structs: structs.filter(({context}) => context !== 'CONSTANTS'),
120
152
  moduleName,
153
+ eventEmitters,
121
154
  methodSerializationOutputs,
122
155
  });
123
156
  }
@@ -24,6 +24,128 @@ const EMPTY_NATIVE_MODULES = {
24
24
  },
25
25
  },
26
26
  };
27
+ const EVENT_EMITTER_MODULES = {
28
+ modules: {
29
+ NativeSampleTurboModule: {
30
+ type: 'NativeModule',
31
+ aliasMap: {
32
+ ObjectStruct: {
33
+ type: 'ObjectTypeAnnotation',
34
+ properties: [
35
+ {
36
+ name: 'a',
37
+ optional: false,
38
+ typeAnnotation: {
39
+ type: 'NumberTypeAnnotation',
40
+ },
41
+ },
42
+ {
43
+ name: 'b',
44
+ optional: false,
45
+ typeAnnotation: {
46
+ type: 'StringTypeAnnotation',
47
+ },
48
+ },
49
+ {
50
+ name: 'c',
51
+ optional: true,
52
+ typeAnnotation: {
53
+ type: 'NullableTypeAnnotation',
54
+ typeAnnotation: {
55
+ type: 'StringTypeAnnotation',
56
+ },
57
+ },
58
+ },
59
+ ],
60
+ },
61
+ },
62
+ enumMap: {},
63
+ spec: {
64
+ eventEmitters: [
65
+ {
66
+ name: 'onEvent1',
67
+ optional: false,
68
+ typeAnnotation: {
69
+ type: 'EventEmitterTypeAnnotation',
70
+ typeAnnotation: {
71
+ type: 'VoidTypeAnnotation',
72
+ },
73
+ },
74
+ },
75
+ {
76
+ name: 'onEvent2',
77
+ optional: false,
78
+ typeAnnotation: {
79
+ type: 'EventEmitterTypeAnnotation',
80
+ typeAnnotation: {
81
+ type: 'StringTypeAnnotation',
82
+ },
83
+ },
84
+ },
85
+ {
86
+ name: 'onEvent3',
87
+ optional: false,
88
+ typeAnnotation: {
89
+ type: 'EventEmitterTypeAnnotation',
90
+ typeAnnotation: {
91
+ type: 'NumberTypeAnnotation',
92
+ },
93
+ },
94
+ },
95
+ {
96
+ name: 'onEvent4',
97
+ optional: false,
98
+ typeAnnotation: {
99
+ type: 'EventEmitterTypeAnnotation',
100
+ typeAnnotation: {
101
+ type: 'BooleanTypeAnnotation',
102
+ },
103
+ },
104
+ },
105
+ {
106
+ name: 'onEvent5',
107
+ optional: false,
108
+ typeAnnotation: {
109
+ type: 'EventEmitterTypeAnnotation',
110
+ typeAnnotation: {
111
+ type: 'TypeAliasTypeAnnotation',
112
+ name: 'ObjectStruct',
113
+ },
114
+ },
115
+ },
116
+ {
117
+ name: 'onEvent6',
118
+ optional: false,
119
+ typeAnnotation: {
120
+ type: 'EventEmitterTypeAnnotation',
121
+ typeAnnotation: {
122
+ type: 'ArrayTypeAnnotation',
123
+ elementType: {
124
+ type: 'TypeAliasTypeAnnotation',
125
+ name: 'ObjectStruct',
126
+ },
127
+ },
128
+ },
129
+ },
130
+ ],
131
+ methods: [
132
+ {
133
+ name: 'voidFunc',
134
+ optional: false,
135
+ typeAnnotation: {
136
+ type: 'FunctionTypeAnnotation',
137
+ returnTypeAnnotation: {
138
+ type: 'VoidTypeAnnotation',
139
+ },
140
+ params: [],
141
+ },
142
+ },
143
+ ],
144
+ },
145
+ moduleName: 'SampleTurboModule',
146
+ },
147
+ },
148
+ };
27
149
  const SIMPLE_NATIVE_MODULES = {
28
150
  modules: {
29
151
  NativeSampleTurboModule: {
@@ -2423,6 +2545,7 @@ module.exports = {
2423
2545
  complex_objects: COMPLEX_OBJECTS,
2424
2546
  two_modules_different_files: TWO_MODULES_DIFFERENT_FILES,
2425
2547
  empty_native_modules: EMPTY_NATIVE_MODULES,
2548
+ event_emitter_module: EVENT_EMITTER_MODULES,
2426
2549
  simple_native_modules: SIMPLE_NATIVE_MODULES,
2427
2550
  native_modules_with_type_aliases: NATIVE_MODULES_WITH_TYPE_ALIASES,
2428
2551
  real_module_example: REAL_MODULE_EXAMPLE,
@@ -27,6 +27,129 @@ const EMPTY_NATIVE_MODULES: SchemaType = {
27
27
  },
28
28
  };
29
29
 
30
+ const EVENT_EMITTER_MODULES: SchemaType = {
31
+ modules: {
32
+ NativeSampleTurboModule: {
33
+ type: 'NativeModule',
34
+ aliasMap: {
35
+ ObjectStruct: {
36
+ type: 'ObjectTypeAnnotation',
37
+ properties: [
38
+ {
39
+ name: 'a',
40
+ optional: false,
41
+ typeAnnotation: {
42
+ type: 'NumberTypeAnnotation',
43
+ },
44
+ },
45
+ {
46
+ name: 'b',
47
+ optional: false,
48
+ typeAnnotation: {
49
+ type: 'StringTypeAnnotation',
50
+ },
51
+ },
52
+ {
53
+ name: 'c',
54
+ optional: true,
55
+ typeAnnotation: {
56
+ type: 'NullableTypeAnnotation',
57
+ typeAnnotation: {
58
+ type: 'StringTypeAnnotation',
59
+ },
60
+ },
61
+ },
62
+ ],
63
+ },
64
+ },
65
+ enumMap: {},
66
+ spec: {
67
+ eventEmitters: [
68
+ {
69
+ name: 'onEvent1',
70
+ optional: false,
71
+ typeAnnotation: {
72
+ type: 'EventEmitterTypeAnnotation',
73
+ typeAnnotation: {
74
+ type: 'VoidTypeAnnotation',
75
+ },
76
+ },
77
+ },
78
+ {
79
+ name: 'onEvent2',
80
+ optional: false,
81
+ typeAnnotation: {
82
+ type: 'EventEmitterTypeAnnotation',
83
+ typeAnnotation: {
84
+ type: 'StringTypeAnnotation',
85
+ },
86
+ },
87
+ },
88
+ {
89
+ name: 'onEvent3',
90
+ optional: false,
91
+ typeAnnotation: {
92
+ type: 'EventEmitterTypeAnnotation',
93
+ typeAnnotation: {
94
+ type: 'NumberTypeAnnotation',
95
+ },
96
+ },
97
+ },
98
+ {
99
+ name: 'onEvent4',
100
+ optional: false,
101
+ typeAnnotation: {
102
+ type: 'EventEmitterTypeAnnotation',
103
+ typeAnnotation: {
104
+ type: 'BooleanTypeAnnotation',
105
+ },
106
+ },
107
+ },
108
+ {
109
+ name: 'onEvent5',
110
+ optional: false,
111
+ typeAnnotation: {
112
+ type: 'EventEmitterTypeAnnotation',
113
+ typeAnnotation: {
114
+ type: 'TypeAliasTypeAnnotation',
115
+ name: 'ObjectStruct',
116
+ },
117
+ },
118
+ },
119
+ {
120
+ name: 'onEvent6',
121
+ optional: false,
122
+ typeAnnotation: {
123
+ type: 'EventEmitterTypeAnnotation',
124
+ typeAnnotation: {
125
+ type: 'ArrayTypeAnnotation',
126
+ elementType: {
127
+ type: 'TypeAliasTypeAnnotation',
128
+ name: 'ObjectStruct',
129
+ },
130
+ },
131
+ },
132
+ },
133
+ ],
134
+ methods: [
135
+ {
136
+ name: 'voidFunc',
137
+ optional: false,
138
+ typeAnnotation: {
139
+ type: 'FunctionTypeAnnotation',
140
+ returnTypeAnnotation: {
141
+ type: 'VoidTypeAnnotation',
142
+ },
143
+ params: [],
144
+ },
145
+ },
146
+ ],
147
+ },
148
+ moduleName: 'SampleTurboModule',
149
+ },
150
+ },
151
+ };
152
+
30
153
  const SIMPLE_NATIVE_MODULES: SchemaType = {
31
154
  modules: {
32
155
  NativeSampleTurboModule: {
@@ -2435,6 +2558,7 @@ module.exports = {
2435
2558
  complex_objects: COMPLEX_OBJECTS,
2436
2559
  two_modules_different_files: TWO_MODULES_DIFFERENT_FILES,
2437
2560
  empty_native_modules: EMPTY_NATIVE_MODULES,
2561
+ event_emitter_module: EVENT_EMITTER_MODULES,
2438
2562
  simple_native_modules: SIMPLE_NATIVE_MODULES,
2439
2563
  native_modules_with_type_aliases: NATIVE_MODULES_WITH_TYPE_ALIASES,
2440
2564
  real_module_example: REAL_MODULE_EXAMPLE,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-native/codegen",
3
- "version": "0.76.0-nightly-20240701-TEMP",
3
+ "version": "0.76.0-nightly-20240702-ad3df8466",
4
4
  "description": "Code generation tools for React Native",
5
5
  "license": "MIT",
6
6
  "repository": {