Skip to content

Commit 544d9fb

Browse files
sahrensfacebook-github-bot
authored andcommitted
Use surface observer for Animated
Summary: Right now we rely on the Paper UIManager to update animated node graphs - this hooks us into `RCTSurfacePresenter` in the same way so we are no longer reliant on Paper. Should also help with complex ordering corner cases with pre vs. post operations and restoring defaults when nodes are removed. More info: https://github.com/facebook/react-native/pull/11819/files Note that we don't have a way to differentiate animation nodes related to fabric views vs. paper views, so if paper and fabric are both rendering updates simultaneously it's possible they could get processed by the wrong callback. That should be very rare, rarely cause problems even if it does happen, and won't be a problem at all in a post-Paper world. Reviewed By: shergin Differential Revision: D14336760 fbshipit-source-id: 1c6a72fa67d5fedbaefb21cd4d7e5d75484f4fae
1 parent 3e40837 commit 544d9fb

File tree

7 files changed

+117
-24
lines changed

7 files changed

+117
-24
lines changed

Libraries/NativeAnimation/Nodes/RCTPropsAnimatedNode.m

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,14 @@
77

88
#import "RCTPropsAnimatedNode.h"
99

10-
#import <objc/runtime.h>
11-
1210
#import <React/RCTLog.h>
11+
#import <React/RCTSurfacePresenterStub.h>
1312
#import <React/RCTUIManager.h>
1413

1514
#import "RCTAnimationUtils.h"
1615
#import "RCTStyleAnimatedNode.h"
1716
#import "RCTValueAnimatedNode.h"
1817

19-
// TODO: Eventually we should just include RCTSurfacePresenter.h, but that pulls in all of fabric
20-
// which doesn't compile in open source yet, so we mirror the protocol and duplicate the category
21-
// here for now.
22-
23-
@protocol SyncViewUpdater <NSObject>
24-
25-
- (BOOL)synchronouslyUpdateViewOnUIThread:(NSNumber *)reactTag props:(NSDictionary *)props;
26-
27-
@end
28-
29-
@implementation RCTBridge (SurfacePresenterShadow)
30-
31-
- (id<SyncViewUpdater>)surfacePresenter
32-
{
33-
return objc_getAssociatedObject(self, @selector(surfacePresenter));
34-
}
35-
36-
@end
3718

3819

3920
@implementation RCTPropsAnimatedNode

Libraries/NativeAnimation/RCTNativeAnimatedModule.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88
#import <React/RCTBridgeModule.h>
99
#import <React/RCTEventDispatcher.h>
1010
#import <React/RCTEventEmitter.h>
11+
#import <React/RCTSurfacePresenterStub.h>
1112
#import <React/RCTUIManager.h>
1213
#import <React/RCTUIManagerObserverCoordinator.h>
1314
#import <React/RCTUIManagerUtils.h>
1415

1516
#import "RCTValueAnimatedNode.h"
1617

17-
@interface RCTNativeAnimatedModule : RCTEventEmitter <RCTBridgeModule, RCTValueAnimatedNodeObserver, RCTEventDispatcherObserver, RCTUIManagerObserver>
18+
@interface RCTNativeAnimatedModule : RCTEventEmitter <RCTBridgeModule, RCTValueAnimatedNodeObserver, RCTEventDispatcherObserver, RCTUIManagerObserver, RCTSurfacePresenterObserver>
1819

1920
@end

Libraries/NativeAnimation/RCTNativeAnimatedModule.m

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ - (void)invalidate
2828
[_nodesManager stopAnimationLoop];
2929
[self.bridge.eventDispatcher removeDispatchObserver:self];
3030
[self.bridge.uiManager.observerCoordinator removeObserver:self];
31+
[self.bridge.surfacePresenter removeObserver:self];
3132
}
3233

3334
- (dispatch_queue_t)methodQueue
@@ -48,7 +49,8 @@ - (void)setBridge:(RCTBridge *)bridge
4849
_animIdIsManagedByFabric = [NSMutableDictionary new];
4950

5051
[bridge.eventDispatcher addDispatchObserver:self];
51-
[bridge.uiManager.observerCoordinator addObserver:self]; // TODO: add fabric equivalent?
52+
[bridge.uiManager.observerCoordinator addObserver:self];
53+
[bridge.surfacePresenter addObserver:self];
5254
}
5355

5456
#pragma mark -- API
@@ -225,9 +227,29 @@ - (void)flushOperationQueues
225227
});
226228
}
227229

230+
#pragma mark - RCTSurfacePresenterObserver
231+
232+
- (void)willMountComponentsWithRootTag:(NSInteger)rootTag
233+
{
234+
RCTAssertMainQueue();
235+
for (AnimatedOperation operation in _preOperations) {
236+
operation(self->_nodesManager);
237+
}
238+
_preOperations = [NSMutableArray new];
239+
}
240+
241+
- (void)didMountComponentsWithRootTag:(NSInteger)rootTag
242+
{
243+
RCTAssertMainQueue();
244+
for (AnimatedOperation operation in _operations) {
245+
operation(self->_nodesManager);
246+
}
247+
_operations = [NSMutableArray new];
248+
}
249+
228250
#pragma mark - RCTUIManagerObserver
229251

230-
- (void)uiManagerWillPerformMounting:(RCTUIManager *)uiManager // TODO: need fabric equivalent
252+
- (void)uiManagerWillPerformMounting:(RCTUIManager *)uiManager
231253
{
232254
if (_preOperations.count == 0 && _operations.count == 0) {
233255
return;

React/Fabric/RCTSurfacePresenter.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@ NS_ASSUME_NONNULL_BEGIN
1919
@class RCTFabricSurface;
2020
@class RCTMountingManager;
2121

22+
@protocol RCTSurfacePresenterObserver <NSObject>
23+
24+
@optional
25+
26+
- (void)willMountComponentsWithRootTag:(ReactTag)rootTag;
27+
28+
- (void)didMountComponentsWithRootTag:(ReactTag)rootTag;
29+
30+
@end
31+
2232
/**
2333
* Coordinates presenting of React Native Surfaces and represents application
2434
* facing interface of running React Native core.
@@ -68,6 +78,10 @@ NS_ASSUME_NONNULL_BEGIN
6878

6979
- (BOOL)synchronouslyUpdateViewOnUIThread:(NSNumber *)reactTag props:(NSDictionary *)props;
7080

81+
- (void)addObserver:(id<RCTSurfacePresenterObserver>)observer;
82+
83+
- (void)removeObserver:(id<RCTSurfacePresenterObserver>)observer;
84+
7185
@end
7286

7387
@interface RCTSurfacePresenter (Deprecated)

React/Fabric/RCTSurfacePresenter.mm

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ @implementation RCTSurfacePresenter {
5353
RCTBridge *_bridge; // Unsafe. We are moving away from Bridge.
5454
RCTBridge *_batchedBridge;
5555
std::shared_ptr<const ReactNativeConfig> _reactNativeConfig;
56+
std::mutex _observerListMutex;
57+
NSMutableArray<id<RCTSurfacePresenterObserver>> *_observers;
5658
}
5759

5860
- (instancetype)initWithBridge:(RCTBridge *)bridge config:(std::shared_ptr<const ReactNativeConfig>)config
@@ -309,13 +311,29 @@ - (void)schedulerOptimisticallyCreateComponentViewWithComponentHandle:(Component
309311
[_mountingManager optimisticallyCreateComponentViewWithComponentHandle:componentHandle];
310312
}
311313

314+
- (void)addObserver:(id<RCTSurfacePresenterObserver>)observer
315+
{
316+
std::lock_guard<std::mutex> lock(_observerListMutex);
317+
[self->_observers addObject:observer];
318+
}
319+
320+
- (void)removeObserver:(id<RCTSurfacePresenterObserver>)observer
321+
{
322+
std::lock_guard<std::mutex> lock(_observerListMutex);
323+
[self->_observers removeObject:observer];
324+
}
325+
312326
#pragma mark - RCTMountingManagerDelegate
313327

314328
- (void)mountingManager:(RCTMountingManager *)mountingManager willMountComponentsWithRootTag:(ReactTag)rootTag
315329
{
316330
RCTAssertMainQueue();
317331

318-
// Does nothing.
332+
for (id<RCTSurfacePresenterObserver> observer in _observers) {
333+
if ([observer respondsToSelector:@selector(willMountComponentsWithRootTag:)]) {
334+
[observer willMountComponentsWithRootTag:rootTag];
335+
}
336+
}
319337
}
320338

321339
- (void)mountingManager:(RCTMountingManager *)mountingManager didMountComponentsWithRootTag:(ReactTag)rootTag
@@ -331,6 +349,11 @@ - (void)mountingManager:(RCTMountingManager *)mountingManager didMountComponents
331349
surface.view.rootView = (RCTSurfaceRootView *)rootComponentView;
332350
}
333351
}
352+
for (id<RCTSurfacePresenterObserver> observer in _observers) {
353+
if ([observer respondsToSelector:@selector(didMountComponentsWithRootTag:)]) {
354+
[observer didMountComponentsWithRootTag:rootTag];
355+
}
356+
}
334357
}
335358

336359
#pragma mark - Bridge events
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its 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+
#import <objc/runtime.h>
9+
10+
#import <React/RCTBridge.h>
11+
12+
NS_ASSUME_NONNULL_BEGIN
13+
14+
// TODO: Eventually this should go away and files should just include RCTSurfacePresenter.h, but
15+
// that pulls in all of fabric which doesn't compile in open source yet, so we mirror the protocol
16+
// and duplicate the category here for now.
17+
18+
19+
@protocol RCTSurfacePresenterObserver <NSObject>
20+
21+
@optional
22+
23+
- (void)willMountComponentsWithRootTag:(NSInteger)rootTag;
24+
- (void)didMountComponentsWithRootTag:(NSInteger)rootTag;
25+
26+
@end
27+
28+
@protocol RCTSurfacePresenterStub <NSObject>
29+
30+
- (BOOL)synchronouslyUpdateViewOnUIThread:(NSNumber *)reactTag props:(NSDictionary *)props;
31+
- (void)addObserver:(id<RCTSurfacePresenterObserver>)observer;
32+
- (void)removeObserver:(id<RCTSurfacePresenterObserver>)observer;
33+
34+
@end
35+
36+
@implementation RCTBridge (RCTSurfacePresenterStub)
37+
38+
- (id<RCTSurfacePresenterStub>)surfacePresenter
39+
{
40+
return objc_getAssociatedObject(self, @selector(surfacePresenter));
41+
}
42+
43+
@end
44+
45+
46+
NS_ASSUME_NONNULL_END

React/React.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,8 @@
834834
58114A161AAE854800E7D092 /* RCTPicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 58114A131AAE854800E7D092 /* RCTPicker.m */; };
835835
58114A171AAE854800E7D092 /* RCTPickerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 58114A151AAE854800E7D092 /* RCTPickerManager.m */; };
836836
58114A501AAE93D500E7D092 /* RCTAsyncLocalStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 58114A4E1AAE93D500E7D092 /* RCTAsyncLocalStorage.m */; };
837+
589515E02231AD9C0036BDE0 /* RCTSurfacePresenterStub.h in Headers */ = {isa = PBXBuildFile; fileRef = 589515DF2231AD9C0036BDE0 /* RCTSurfacePresenterStub.h */; };
838+
589515E12231ADE00036BDE0 /* RCTSurfacePresenterStub.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 589515DF2231AD9C0036BDE0 /* RCTSurfacePresenterStub.h */; };
837839
590D7BFD1EBD458B00D8A370 /* RCTShadowView+Layout.h in Headers */ = {isa = PBXBuildFile; fileRef = 590D7BFB1EBD458B00D8A370 /* RCTShadowView+Layout.h */; };
838840
590D7BFE1EBD458B00D8A370 /* RCTShadowView+Layout.h in Headers */ = {isa = PBXBuildFile; fileRef = 590D7BFB1EBD458B00D8A370 /* RCTShadowView+Layout.h */; };
839841
590D7BFF1EBD458B00D8A370 /* RCTShadowView+Layout.m in Sources */ = {isa = PBXBuildFile; fileRef = 590D7BFC1EBD458B00D8A370 /* RCTShadowView+Layout.m */; };
@@ -1557,6 +1559,7 @@
15571559
dstPath = include/React;
15581560
dstSubfolderSpec = 16;
15591561
files = (
1562+
589515E12231ADE00036BDE0 /* RCTSurfacePresenterStub.h in Copy Headers */,
15601563
39C50FF92046EACF00CEE534 /* RCTVersion.h in Copy Headers */,
15611564
591F78DE202ADB8F004A668C /* RCTLayout.h in Copy Headers */,
15621565
59EDBCBD1FDF4E43003573DE /* RCTScrollableProtocol.h in Copy Headers */,
@@ -2096,6 +2099,7 @@
20962099
58114A151AAE854800E7D092 /* RCTPickerManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTPickerManager.m; sourceTree = "<group>"; };
20972100
58114A4E1AAE93D500E7D092 /* RCTAsyncLocalStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTAsyncLocalStorage.m; sourceTree = "<group>"; };
20982101
58114A4F1AAE93D500E7D092 /* RCTAsyncLocalStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAsyncLocalStorage.h; sourceTree = "<group>"; };
2102+
589515DF2231AD9C0036BDE0 /* RCTSurfacePresenterStub.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSurfacePresenterStub.h; sourceTree = "<group>"; };
20992103
58C571BF1AA56C1900CDF9C8 /* RCTDatePickerManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTDatePickerManager.m; sourceTree = "<group>"; };
21002104
58C571C01AA56C1900CDF9C8 /* RCTDatePickerManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = RCTDatePickerManager.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
21012105
590D7BFB1EBD458B00D8A370 /* RCTShadowView+Layout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTShadowView+Layout.h"; sourceTree = "<group>"; };
@@ -2499,6 +2503,7 @@
24992503
13B07FE01A69315300A75B9A /* Modules */ = {
25002504
isa = PBXGroup;
25012505
children = (
2506+
589515DF2231AD9C0036BDE0 /* RCTSurfacePresenterStub.h */,
25022507
E9B20B791B500126007A2DA7 /* RCTAccessibilityManager.h */,
25032508
E9B20B7A1B500126007A2DA7 /* RCTAccessibilityManager.m */,
25042509
13B07FE71A69327A00A75B9A /* RCTAlertManager.h */,
@@ -3496,6 +3501,7 @@
34963501
3D0E378A1F1CC40000DCAC9F /* RCTWebSocketModule.h in Headers */,
34973502
3D80DA621DF820620028D040 /* RCTAutoInsetsProtocol.h in Headers */,
34983503
C60128AB1F3D1258009DF9FF /* RCTCxxConvert.h in Headers */,
3504+
589515E02231AD9C0036BDE0 /* RCTSurfacePresenterStub.h in Headers */,
34993505
59EDBCAD1FDF4E0C003573DE /* RCTScrollContentView.h in Headers */,
35003506
59EDBCA71FDF4E0C003573DE /* RCTScrollableProtocol.h in Headers */,
35013507
591F78DC202ADB22004A668C /* RCTLayout.h in Headers */,

0 commit comments

Comments
 (0)