1// Copyright 2015-present 650 Industries. All rights reserved.
2
3#import "EXDevLauncherRCTBridge.h"
4#import "EXDevLauncherController.h"
5#import "RCTCxxBridge+Private.h"
6
7#import <React/RCTPerformanceLogger.h>
8#import <React/RCTDevSettings.h>
9#import <React/RCTDevMenu.h>
10
11@import EXDevMenuInterface;
12
13@implementation EXDevLauncherRCTCxxBridge
14
15- (instancetype)initWithParentBridge:(RCTBridge *)bridge
16{
17  if ((self = [super initWithParentBridge:bridge])) {
18    RCTBridge *appBridge = [EXDevLauncherController sharedInstance].appBridge;
19    // reset the singleton `RCTBridge.currentBridge` to app bridge instance
20    RCTBridge.currentBridge = appBridge != nil ? appBridge.batchedBridge : nil;
21  }
22  return self;
23}
24
25/**
26 * Theoretically, we could overwrite the `RCTDevSettings` module by exporting our version through the bridge.
27 * However, this won't work with the js remote debugging. For some reason, the RN needs to initialized remote tools very early. So it always uses the default module to do it.
28 * When we export our module, it won't be used in the initialized phase. So the launcher will start with remote debug support.
29 */
30- (RCTDevSettings *)devSettings
31{
32  //  uncomment below to enable fast refresh for development builds of DevLauncher
33//   return super.devSettings;
34 return nil;
35}
36
37- (RCTDevMenu *)devMenu
38{
39  return nil;
40}
41
42- (NSArray<Class> *)filterModuleList:(NSArray<Class> *)modules
43{
44  NSArray<NSString *> *allowedModules = @[@"RCT", @"DevMenu"];
45  NSArray<Class> *filteredModuleList = [modules filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id  _Nullable clazz, NSDictionary<NSString *,id> * _Nullable bindings) {
46    if ([clazz conformsToProtocol:@protocol(DevMenuExtensionProtocol)]) {
47      return true;
48    }
49
50    if ([clazz conformsToProtocol:@protocol(EXDevExtensionProtocol)]) {
51      return true;
52    }
53
54    NSString* clazzName = NSStringFromClass(clazz);
55    for (NSString *allowedModule in allowedModules) {
56      if ([clazzName hasPrefix:allowedModule]) {
57        return true;
58      }
59    }
60    return false;
61  }]];
62
63  return filteredModuleList;
64}
65
66- (NSArray<RCTModuleData *> *)_initializeModules:(NSArray<Class> *)modules
67                               withDispatchGroup:(dispatch_group_t)dispatchGroup
68                                lazilyDiscovered:(BOOL)lazilyDiscovered
69{
70  return [super _initializeModules:[self filterModuleList:modules] withDispatchGroup:dispatchGroup lazilyDiscovered:lazilyDiscovered];
71}
72
73@end
74
75@implementation EXDevLauncherRCTBridge
76
77- (Class)bridgeClass
78{
79  return [EXDevLauncherRCTCxxBridge class];
80}
81
82#pragma clang diagnostic push
83#pragma clang diagnostic ignored "-Wdeprecated-implementations"
84// This method is still used so we need to override it even if it's deprecated
85- (void)reloadWithReason:(NSString *)reason {}
86#pragma clang diagnostic pop
87
88@end
89