1// Copyright 2018-present 650 Industries. All rights reserved.
2
3#import <ExpoModulesCore/EXNativeModulesProxy.h>
4#import <ExpoModulesCore/EXViewManagerAdapter.h>
5#import <ExpoModulesCore/EXModuleRegistryAdapter.h>
6#import <ExpoModulesCore/EXModuleRegistryProvider.h>
7#import <ExpoModulesCore/EXViewManagerAdapterClassesRegistry.h>
8#import <ExpoModulesCore/EXModuleRegistryHolderReactModule.h>
9#import <ExpoModulesCore/EXReactNativeEventEmitter.h>
10
11@interface EXModuleRegistryAdapter ()
12
13@property (nonatomic, strong) EXModuleRegistryProvider *moduleRegistryProvider;
14@property (nonatomic, strong) EXViewManagerAdapterClassesRegistry *viewManagersClassesRegistry;
15
16@end
17
18@implementation EXModuleRegistryAdapter
19
20- (instancetype)initWithModuleRegistryProvider:(EXModuleRegistryProvider *)moduleRegistryProvider
21{
22  if (self = [super init]) {
23    _moduleRegistryProvider = moduleRegistryProvider;
24    _viewManagersClassesRegistry = [[EXViewManagerAdapterClassesRegistry alloc] init];
25  }
26  return self;
27}
28
29- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
30{
31  return [self extraModulesForModuleRegistry:[_moduleRegistryProvider moduleRegistry]];
32}
33
34- (NSArray<id<RCTBridgeModule>> *)extraModulesForModuleRegistry:(EXModuleRegistry *)moduleRegistry
35{
36  NSMutableArray<id<RCTBridgeModule>> *extraModules = [NSMutableArray array];
37
38  EXNativeModulesProxy *nativeModulesProxy = [[EXNativeModulesProxy alloc] initWithModuleRegistry:moduleRegistry];
39  [extraModules addObject:nativeModulesProxy];
40
41  // Event emitter is not automatically registered — we add it to the module registry here.
42  // It will be added to the bridge later in this method, as it conforms to `RCTBridgeModule`.
43  EXReactNativeEventEmitter *eventEmitter = [EXReactNativeEventEmitter new];
44  [moduleRegistry registerInternalModule:eventEmitter];
45
46  for (EXViewManager *viewManager in [moduleRegistry getAllViewManagers]) {
47    Class viewManagerAdapterClass = [EXViewManagerAdapterClassesRegistry createViewManagerAdapterClassForViewManager:viewManager];
48    [extraModules addObject:[[viewManagerAdapterClass alloc] init]];
49  }
50
51  // Silence React Native warning `Base module "%s" does not exist`
52  // occurring when view manager class is subclassing another class
53  // that is not RCTViewManager (in our case all the view manager adapters
54  // subclass EXViewManagerAdapter, so RN expects to find EXViewManagerAdapter
55  // exported.
56  [extraModules addObject:[[EXViewManagerAdapter alloc] init]];
57
58  // It is possible that among internal modules there are some RCTBridgeModules --
59  // let's add them to extraModules here.
60  for (id<EXInternalModule> module in [moduleRegistry getAllInternalModules]) {
61    if ([module conformsToProtocol:@protocol(RCTBridgeModule)]) {
62      id<RCTBridgeModule> reactBridgeModule = (id<RCTBridgeModule>)module;
63      [extraModules addObject:reactBridgeModule];
64    }
65  }
66
67  // Adding the way to access the module registry from RCTBridgeModules.
68  [extraModules addObject:[[EXModuleRegistryHolderReactModule alloc] initWithModuleRegistry:moduleRegistry]];
69
70  // One could add some modules to the Module Registry after creating it.
71  // Here is our last call for finalizing initialization.
72  [moduleRegistry initialize];
73  return extraModules;
74}
75
76@end
77