1// Copyright 2023-present 650 Industries. All rights reserved.
2
3#import <React/RCTUIManager.h>
4#import <React/RCTEventDispatcher.h>
5#import <React/JSCExecutorFactory.h>
6#import <React/RCTJSIExecutorRuntimeInstaller.h>
7#import <React/CoreModulesPlugins.h>
8#import <ReactCommon/RCTTurboModule.h>
9#import <reacthermes/HermesExecutorFactory.h>
10
11#import <RNReanimated/REAModule.h>
12#import <RNReanimated/REAEventDispatcher.h>
13#import <RNReanimated/REAUIManager.h>
14#import <RNReanimated/NativeProxy.h>
15#import <RNReanimated/ReanimatedVersion.h>
16
17#import <ExpoModulesCore/EXDefines.h>
18
19#import "EXDevSettings.h"
20#import "EXDisabledDevMenu.h"
21#import "EXDisabledRedBox.h"
22#import "EXVersionUtils.h"
23
24@interface RCTEventDispatcher (REAnimated)
25- (void)setBridge:(RCTBridge*)bridge;
26@end
27
28@implementation EXVersionUtils
29
30+ (nonnull void *)versionedJsExecutorFactoryForBridge:(nonnull RCTBridge *)bridge
31                                               engine:(nonnull NSString *)jsEngine
32{
33  [bridge moduleForClass:[RCTUIManager class]];
34  REAUIManager *reaUiManager = [REAUIManager new];
35  [reaUiManager setBridge:bridge];
36  RCTUIManager *uiManager = reaUiManager;
37  [bridge updateModuleWithInstance:uiManager];
38
39  [bridge moduleForClass:[RCTEventDispatcher class]];
40  RCTEventDispatcher *eventDispatcher = [REAEventDispatcher new];
41  RCTCallableJSModules *callableJSModules = [RCTCallableJSModules new];
42  [bridge setValue:callableJSModules forKey:@"_callableJSModules"];
43  [callableJSModules setBridge:bridge];
44  [eventDispatcher setValue:callableJSModules forKey:@"_callableJSModules"];
45  [eventDispatcher setValue:bridge forKey:@"_bridge"];
46  [eventDispatcher initialize];
47  [bridge updateModuleWithInstance:eventDispatcher];
48
49  EX_WEAKIFY(self);
50  const auto executor = [EXWeak_self, bridge](facebook::jsi::Runtime &runtime) {
51    if (!bridge) {
52      return;
53    }
54    EX_ENSURE_STRONGIFY(self);
55    auto reanimatedModule = reanimated::createReanimatedModule(bridge, bridge.jsCallInvoker);
56    auto workletRuntimeValue = runtime
57      .global()
58      .getProperty(runtime, "ArrayBuffer")
59      .asObject(runtime)
60      .asFunction(runtime)
61      .callAsConstructor(runtime, {static_cast<double>(sizeof(void*))});
62    uintptr_t* workletRuntimeData = reinterpret_cast<uintptr_t*>(
63                                                                 workletRuntimeValue.getObject(runtime).getArrayBuffer(runtime).data(runtime));
64    workletRuntimeData[0] = reinterpret_cast<uintptr_t>(reanimatedModule->runtime.get());
65    runtime.global().setProperty(
66                                 runtime,
67                                 "_WORKLET_RUNTIME",
68                                 workletRuntimeValue);
69    runtime.global().setProperty(
70                                 runtime,
71                                 "_REANIMATED_VERSION_CPP",
72                                 reanimated::getReanimatedVersionString(runtime));
73
74    runtime.global().setProperty(
75                                 runtime,
76                                 jsi::PropNameID::forAscii(runtime, "__reanimatedModuleProxy"),
77                                 jsi::Object::createFromHostObject(runtime, reanimatedModule));
78  };
79  if ([jsEngine isEqualToString:@"hermes"]) {
80    return new facebook::react::HermesExecutorFactory(RCTJSIExecutorRuntimeInstaller(executor));
81  }
82  return new facebook::react::JSCExecutorFactory(RCTJSIExecutorRuntimeInstaller(executor));
83}
84
85@end
86