1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | #import "RCTSurfacePresenterBridgeAdapter.h"
|
9 |
|
10 | #import <cxxreact/MessageQueueThread.h>
|
11 | #import <jsi/jsi.h>
|
12 |
|
13 | #import <React/RCTAssert.h>
|
14 | #import <React/RCTBridge+Private.h>
|
15 | #import <React/RCTImageLoader.h>
|
16 | #import <React/RCTImageLoaderWithAttributionProtocol.h>
|
17 | #import <React/RCTSurfacePresenter.h>
|
18 | #import <React/RCTSurfacePresenterStub.h>
|
19 |
|
20 | #import <react/utils/ContextContainer.h>
|
21 | #import <react/utils/ManagedObjectWrapper.h>
|
22 | #import <react/utils/RuntimeExecutor.h>
|
23 |
|
24 | using namespace facebook::react;
|
25 |
|
26 | @interface RCTBridge ()
|
27 | - (std::shared_ptr<facebook::react::MessageQueueThread>)jsMessageThread;
|
28 | - (void)invokeAsync:(std::function<void()> &&)func;
|
29 | @end
|
30 |
|
31 | static ContextContainer::Shared RCTContextContainerFromBridge(RCTBridge *bridge)
|
32 | {
|
33 | auto contextContainer = std::make_shared<ContextContainer const>();
|
34 |
|
35 | RCTImageLoader *imageLoader = RCTTurboModuleEnabled()
|
36 | ? [bridge moduleForName:@"RCTImageLoader" lazilyLoadIfNecessary:YES]
|
37 | : [bridge moduleForClass:[RCTImageLoader class]];
|
38 |
|
39 | contextContainer->insert("Bridge", wrapManagedObjectWeakly(bridge));
|
40 | contextContainer->insert("RCTImageLoader", wrapManagedObject((id<RCTImageLoaderWithAttributionProtocol>)imageLoader));
|
41 | return contextContainer;
|
42 | }
|
43 |
|
44 | static RuntimeExecutor RCTRuntimeExecutorFromBridge(RCTBridge *bridge)
|
45 | {
|
46 | auto bridgeWeakWrapper = wrapManagedObjectWeakly([bridge batchedBridge] ?: bridge);
|
47 |
|
48 | RuntimeExecutor runtimeExecutor = [bridgeWeakWrapper](
|
49 | std::function<void(facebook::jsi::Runtime & runtime)> &&callback) {
|
50 | [unwrapManagedObjectWeakly(bridgeWeakWrapper) invokeAsync:[bridgeWeakWrapper, callback = std::move(callback)]() {
|
51 | RCTCxxBridge *batchedBridge = (RCTCxxBridge *)unwrapManagedObjectWeakly(bridgeWeakWrapper);
|
52 |
|
53 | if (!batchedBridge) {
|
54 | return;
|
55 | }
|
56 |
|
57 | auto runtime = (facebook::jsi::Runtime *)(batchedBridge.runtime);
|
58 |
|
59 | if (!runtime) {
|
60 | return;
|
61 | }
|
62 |
|
63 | callback(*runtime);
|
64 | }];
|
65 | };
|
66 |
|
67 | return runtimeExecutor;
|
68 | }
|
69 |
|
70 | @implementation RCTSurfacePresenterBridgeAdapter {
|
71 | RCTSurfacePresenter *_Nullable _surfacePresenter;
|
72 | __weak RCTBridge *_bridge;
|
73 | __weak RCTBridge *_batchedBridge;
|
74 | }
|
75 |
|
76 | - (instancetype)initWithBridge:(RCTBridge *)bridge contextContainer:(ContextContainer::Shared)contextContainer
|
77 | {
|
78 | if (self = [super init]) {
|
79 | contextContainer->update(*RCTContextContainerFromBridge(bridge));
|
80 | _surfacePresenter = [[RCTSurfacePresenter alloc] initWithContextContainer:contextContainer
|
81 | runtimeExecutor:RCTRuntimeExecutorFromBridge(bridge)];
|
82 |
|
83 | _bridge = bridge;
|
84 | _batchedBridge = [_bridge batchedBridge] ?: _bridge;
|
85 |
|
86 | [self _updateSurfacePresenter];
|
87 | [self _addBridgeObservers:_bridge];
|
88 | }
|
89 |
|
90 | return self;
|
91 | }
|
92 |
|
93 | - (void)dealloc
|
94 | {
|
95 | [_surfacePresenter suspend];
|
96 | }
|
97 |
|
98 | - (RCTBridge *)bridge
|
99 | {
|
100 | return _bridge;
|
101 | }
|
102 |
|
103 | - (void)setBridge:(RCTBridge *)bridge
|
104 | {
|
105 | if (bridge == _bridge) {
|
106 | return;
|
107 | }
|
108 |
|
109 | [self _removeBridgeObservers:_bridge];
|
110 |
|
111 | [_surfacePresenter suspend];
|
112 |
|
113 | _bridge = bridge;
|
114 | _batchedBridge = [_bridge batchedBridge] ?: _bridge;
|
115 |
|
116 | [self _updateSurfacePresenter];
|
117 |
|
118 | [self _addBridgeObservers:_bridge];
|
119 |
|
120 | [_surfacePresenter resume];
|
121 | }
|
122 |
|
123 | - (void)_updateSurfacePresenter
|
124 | {
|
125 | _surfacePresenter.runtimeExecutor = RCTRuntimeExecutorFromBridge(_bridge);
|
126 | _surfacePresenter.contextContainer->update(*RCTContextContainerFromBridge(_bridge));
|
127 |
|
128 | [_bridge setSurfacePresenter:_surfacePresenter];
|
129 | [_batchedBridge setSurfacePresenter:_surfacePresenter];
|
130 | }
|
131 |
|
132 | - (void)_addBridgeObservers:(RCTBridge *)bridge
|
133 | {
|
134 | if (!bridge) {
|
135 | return;
|
136 | }
|
137 |
|
138 | [[NSNotificationCenter defaultCenter] addObserver:self
|
139 | selector:@selector(handleBridgeWillReloadNotification:)
|
140 | name:RCTBridgeWillReloadNotification
|
141 | object:bridge];
|
142 | [[NSNotificationCenter defaultCenter] addObserver:self
|
143 | selector:@selector(handleJavaScriptDidLoadNotification:)
|
144 | name:RCTJavaScriptDidLoadNotification
|
145 | object:bridge];
|
146 | [[NSNotificationCenter defaultCenter] addObserver:self
|
147 | selector:@selector(handleBridgeWillBeInvalidatedNotification:)
|
148 | name:RCTBridgeWillBeInvalidatedNotification
|
149 | object:bridge];
|
150 | }
|
151 |
|
152 | - (void)_removeBridgeObservers:(RCTBridge *)bridge
|
153 | {
|
154 | if (!bridge) {
|
155 | return;
|
156 | }
|
157 |
|
158 | [[NSNotificationCenter defaultCenter] removeObserver:self name:RCTBridgeWillReloadNotification object:bridge];
|
159 | [[NSNotificationCenter defaultCenter] removeObserver:self name:RCTJavaScriptDidLoadNotification object:bridge];
|
160 | [[NSNotificationCenter defaultCenter] removeObserver:self name:RCTBridgeWillBeInvalidatedNotification object:bridge];
|
161 | }
|
162 |
|
163 | #pragma mark - Bridge events
|
164 |
|
165 | - (void)handleBridgeWillReloadNotification:(NSNotification *)notification
|
166 | {
|
167 | [_surfacePresenter suspend];
|
168 | }
|
169 |
|
170 | - (void)handleBridgeWillBeInvalidatedNotification:(NSNotification *)notification
|
171 | {
|
172 | [_surfacePresenter suspend];
|
173 | }
|
174 |
|
175 | - (void)handleJavaScriptDidLoadNotification:(NSNotification *)notification
|
176 | {
|
177 | RCTBridge *bridge = notification.userInfo[@"bridge"];
|
178 | if (bridge == _batchedBridge) {
|
179 |
|
180 | return;
|
181 | }
|
182 |
|
183 | _batchedBridge = bridge;
|
184 | _batchedBridge.surfacePresenter = _surfacePresenter;
|
185 |
|
186 | [self _updateSurfacePresenter];
|
187 |
|
188 | [_surfacePresenter resume];
|
189 | }
|
190 |
|
191 | @end
|