mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-01-12 22:50:10 +08:00
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
This commit is contained in:
committed by
Facebook Github Bot
parent
3e40837a85
commit
544d9fb10b
@@ -7,33 +7,14 @@
|
||||
|
||||
#import "RCTPropsAnimatedNode.h"
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#import <React/RCTLog.h>
|
||||
#import <React/RCTSurfacePresenterStub.h>
|
||||
#import <React/RCTUIManager.h>
|
||||
|
||||
#import "RCTAnimationUtils.h"
|
||||
#import "RCTStyleAnimatedNode.h"
|
||||
#import "RCTValueAnimatedNode.h"
|
||||
|
||||
// TODO: Eventually we should just include RCTSurfacePresenter.h, but that pulls in all of fabric
|
||||
// which doesn't compile in open source yet, so we mirror the protocol and duplicate the category
|
||||
// here for now.
|
||||
|
||||
@protocol SyncViewUpdater <NSObject>
|
||||
|
||||
- (BOOL)synchronouslyUpdateViewOnUIThread:(NSNumber *)reactTag props:(NSDictionary *)props;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTBridge (SurfacePresenterShadow)
|
||||
|
||||
- (id<SyncViewUpdater>)surfacePresenter
|
||||
{
|
||||
return objc_getAssociatedObject(self, @selector(surfacePresenter));
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation RCTPropsAnimatedNode
|
||||
|
||||
@@ -8,12 +8,13 @@
|
||||
#import <React/RCTBridgeModule.h>
|
||||
#import <React/RCTEventDispatcher.h>
|
||||
#import <React/RCTEventEmitter.h>
|
||||
#import <React/RCTSurfacePresenterStub.h>
|
||||
#import <React/RCTUIManager.h>
|
||||
#import <React/RCTUIManagerObserverCoordinator.h>
|
||||
#import <React/RCTUIManagerUtils.h>
|
||||
|
||||
#import "RCTValueAnimatedNode.h"
|
||||
|
||||
@interface RCTNativeAnimatedModule : RCTEventEmitter <RCTBridgeModule, RCTValueAnimatedNodeObserver, RCTEventDispatcherObserver, RCTUIManagerObserver>
|
||||
@interface RCTNativeAnimatedModule : RCTEventEmitter <RCTBridgeModule, RCTValueAnimatedNodeObserver, RCTEventDispatcherObserver, RCTUIManagerObserver, RCTSurfacePresenterObserver>
|
||||
|
||||
@end
|
||||
|
||||
@@ -28,6 +28,7 @@ RCT_EXPORT_MODULE();
|
||||
[_nodesManager stopAnimationLoop];
|
||||
[self.bridge.eventDispatcher removeDispatchObserver:self];
|
||||
[self.bridge.uiManager.observerCoordinator removeObserver:self];
|
||||
[self.bridge.surfacePresenter removeObserver:self];
|
||||
}
|
||||
|
||||
- (dispatch_queue_t)methodQueue
|
||||
@@ -48,7 +49,8 @@ RCT_EXPORT_MODULE();
|
||||
_animIdIsManagedByFabric = [NSMutableDictionary new];
|
||||
|
||||
[bridge.eventDispatcher addDispatchObserver:self];
|
||||
[bridge.uiManager.observerCoordinator addObserver:self]; // TODO: add fabric equivalent?
|
||||
[bridge.uiManager.observerCoordinator addObserver:self];
|
||||
[bridge.surfacePresenter addObserver:self];
|
||||
}
|
||||
|
||||
#pragma mark -- API
|
||||
@@ -225,9 +227,29 @@ RCT_EXPORT_METHOD(removeAnimatedEventFromView:(nonnull NSNumber *)viewTag
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - RCTSurfacePresenterObserver
|
||||
|
||||
- (void)willMountComponentsWithRootTag:(NSInteger)rootTag
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
for (AnimatedOperation operation in _preOperations) {
|
||||
operation(self->_nodesManager);
|
||||
}
|
||||
_preOperations = [NSMutableArray new];
|
||||
}
|
||||
|
||||
- (void)didMountComponentsWithRootTag:(NSInteger)rootTag
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
for (AnimatedOperation operation in _operations) {
|
||||
operation(self->_nodesManager);
|
||||
}
|
||||
_operations = [NSMutableArray new];
|
||||
}
|
||||
|
||||
#pragma mark - RCTUIManagerObserver
|
||||
|
||||
- (void)uiManagerWillPerformMounting:(RCTUIManager *)uiManager // TODO: need fabric equivalent
|
||||
- (void)uiManagerWillPerformMounting:(RCTUIManager *)uiManager
|
||||
{
|
||||
if (_preOperations.count == 0 && _operations.count == 0) {
|
||||
return;
|
||||
|
||||
@@ -19,6 +19,16 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@class RCTFabricSurface;
|
||||
@class RCTMountingManager;
|
||||
|
||||
@protocol RCTSurfacePresenterObserver <NSObject>
|
||||
|
||||
@optional
|
||||
|
||||
- (void)willMountComponentsWithRootTag:(ReactTag)rootTag;
|
||||
|
||||
- (void)didMountComponentsWithRootTag:(ReactTag)rootTag;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
* Coordinates presenting of React Native Surfaces and represents application
|
||||
* facing interface of running React Native core.
|
||||
@@ -68,6 +78,10 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
- (BOOL)synchronouslyUpdateViewOnUIThread:(NSNumber *)reactTag props:(NSDictionary *)props;
|
||||
|
||||
- (void)addObserver:(id<RCTSurfacePresenterObserver>)observer;
|
||||
|
||||
- (void)removeObserver:(id<RCTSurfacePresenterObserver>)observer;
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTSurfacePresenter (Deprecated)
|
||||
|
||||
@@ -53,6 +53,8 @@ using namespace facebook::react;
|
||||
RCTBridge *_bridge; // Unsafe. We are moving away from Bridge.
|
||||
RCTBridge *_batchedBridge;
|
||||
std::shared_ptr<const ReactNativeConfig> _reactNativeConfig;
|
||||
std::mutex _observerListMutex;
|
||||
NSMutableArray<id<RCTSurfacePresenterObserver>> *_observers;
|
||||
}
|
||||
|
||||
- (instancetype)initWithBridge:(RCTBridge *)bridge config:(std::shared_ptr<const ReactNativeConfig>)config
|
||||
@@ -309,13 +311,29 @@ using namespace facebook::react;
|
||||
[_mountingManager optimisticallyCreateComponentViewWithComponentHandle:componentHandle];
|
||||
}
|
||||
|
||||
- (void)addObserver:(id<RCTSurfacePresenterObserver>)observer
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_observerListMutex);
|
||||
[self->_observers addObject:observer];
|
||||
}
|
||||
|
||||
- (void)removeObserver:(id<RCTSurfacePresenterObserver>)observer
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_observerListMutex);
|
||||
[self->_observers removeObject:observer];
|
||||
}
|
||||
|
||||
#pragma mark - RCTMountingManagerDelegate
|
||||
|
||||
- (void)mountingManager:(RCTMountingManager *)mountingManager willMountComponentsWithRootTag:(ReactTag)rootTag
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
|
||||
// Does nothing.
|
||||
for (id<RCTSurfacePresenterObserver> observer in _observers) {
|
||||
if ([observer respondsToSelector:@selector(willMountComponentsWithRootTag:)]) {
|
||||
[observer willMountComponentsWithRootTag:rootTag];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mountingManager:(RCTMountingManager *)mountingManager didMountComponentsWithRootTag:(ReactTag)rootTag
|
||||
@@ -331,6 +349,11 @@ using namespace facebook::react;
|
||||
surface.view.rootView = (RCTSurfaceRootView *)rootComponentView;
|
||||
}
|
||||
}
|
||||
for (id<RCTSurfacePresenterObserver> observer in _observers) {
|
||||
if ([observer respondsToSelector:@selector(didMountComponentsWithRootTag:)]) {
|
||||
[observer didMountComponentsWithRootTag:rootTag];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Bridge events
|
||||
|
||||
46
React/Modules/RCTSurfacePresenterStub.h
Normal file
46
React/Modules/RCTSurfacePresenterStub.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#import <React/RCTBridge.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
// TODO: Eventually this should go away and files should just include RCTSurfacePresenter.h, but
|
||||
// that pulls in all of fabric which doesn't compile in open source yet, so we mirror the protocol
|
||||
// and duplicate the category here for now.
|
||||
|
||||
|
||||
@protocol RCTSurfacePresenterObserver <NSObject>
|
||||
|
||||
@optional
|
||||
|
||||
- (void)willMountComponentsWithRootTag:(NSInteger)rootTag;
|
||||
- (void)didMountComponentsWithRootTag:(NSInteger)rootTag;
|
||||
|
||||
@end
|
||||
|
||||
@protocol RCTSurfacePresenterStub <NSObject>
|
||||
|
||||
- (BOOL)synchronouslyUpdateViewOnUIThread:(NSNumber *)reactTag props:(NSDictionary *)props;
|
||||
- (void)addObserver:(id<RCTSurfacePresenterObserver>)observer;
|
||||
- (void)removeObserver:(id<RCTSurfacePresenterObserver>)observer;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTBridge (RCTSurfacePresenterStub)
|
||||
|
||||
- (id<RCTSurfacePresenterStub>)surfacePresenter
|
||||
{
|
||||
return objc_getAssociatedObject(self, @selector(surfacePresenter));
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -834,6 +834,8 @@
|
||||
58114A161AAE854800E7D092 /* RCTPicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 58114A131AAE854800E7D092 /* RCTPicker.m */; };
|
||||
58114A171AAE854800E7D092 /* RCTPickerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 58114A151AAE854800E7D092 /* RCTPickerManager.m */; };
|
||||
58114A501AAE93D500E7D092 /* RCTAsyncLocalStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 58114A4E1AAE93D500E7D092 /* RCTAsyncLocalStorage.m */; };
|
||||
589515E02231AD9C0036BDE0 /* RCTSurfacePresenterStub.h in Headers */ = {isa = PBXBuildFile; fileRef = 589515DF2231AD9C0036BDE0 /* RCTSurfacePresenterStub.h */; };
|
||||
589515E12231ADE00036BDE0 /* RCTSurfacePresenterStub.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 589515DF2231AD9C0036BDE0 /* RCTSurfacePresenterStub.h */; };
|
||||
590D7BFD1EBD458B00D8A370 /* RCTShadowView+Layout.h in Headers */ = {isa = PBXBuildFile; fileRef = 590D7BFB1EBD458B00D8A370 /* RCTShadowView+Layout.h */; };
|
||||
590D7BFE1EBD458B00D8A370 /* RCTShadowView+Layout.h in Headers */ = {isa = PBXBuildFile; fileRef = 590D7BFB1EBD458B00D8A370 /* RCTShadowView+Layout.h */; };
|
||||
590D7BFF1EBD458B00D8A370 /* RCTShadowView+Layout.m in Sources */ = {isa = PBXBuildFile; fileRef = 590D7BFC1EBD458B00D8A370 /* RCTShadowView+Layout.m */; };
|
||||
@@ -1557,6 +1559,7 @@
|
||||
dstPath = include/React;
|
||||
dstSubfolderSpec = 16;
|
||||
files = (
|
||||
589515E12231ADE00036BDE0 /* RCTSurfacePresenterStub.h in Copy Headers */,
|
||||
39C50FF92046EACF00CEE534 /* RCTVersion.h in Copy Headers */,
|
||||
591F78DE202ADB8F004A668C /* RCTLayout.h in Copy Headers */,
|
||||
59EDBCBD1FDF4E43003573DE /* RCTScrollableProtocol.h in Copy Headers */,
|
||||
@@ -2096,6 +2099,7 @@
|
||||
58114A151AAE854800E7D092 /* RCTPickerManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTPickerManager.m; sourceTree = "<group>"; };
|
||||
58114A4E1AAE93D500E7D092 /* RCTAsyncLocalStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTAsyncLocalStorage.m; sourceTree = "<group>"; };
|
||||
58114A4F1AAE93D500E7D092 /* RCTAsyncLocalStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAsyncLocalStorage.h; sourceTree = "<group>"; };
|
||||
589515DF2231AD9C0036BDE0 /* RCTSurfacePresenterStub.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSurfacePresenterStub.h; sourceTree = "<group>"; };
|
||||
58C571BF1AA56C1900CDF9C8 /* RCTDatePickerManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTDatePickerManager.m; sourceTree = "<group>"; };
|
||||
58C571C01AA56C1900CDF9C8 /* RCTDatePickerManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = RCTDatePickerManager.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
590D7BFB1EBD458B00D8A370 /* RCTShadowView+Layout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTShadowView+Layout.h"; sourceTree = "<group>"; };
|
||||
@@ -2499,6 +2503,7 @@
|
||||
13B07FE01A69315300A75B9A /* Modules */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
589515DF2231AD9C0036BDE0 /* RCTSurfacePresenterStub.h */,
|
||||
E9B20B791B500126007A2DA7 /* RCTAccessibilityManager.h */,
|
||||
E9B20B7A1B500126007A2DA7 /* RCTAccessibilityManager.m */,
|
||||
13B07FE71A69327A00A75B9A /* RCTAlertManager.h */,
|
||||
@@ -3496,6 +3501,7 @@
|
||||
3D0E378A1F1CC40000DCAC9F /* RCTWebSocketModule.h in Headers */,
|
||||
3D80DA621DF820620028D040 /* RCTAutoInsetsProtocol.h in Headers */,
|
||||
C60128AB1F3D1258009DF9FF /* RCTCxxConvert.h in Headers */,
|
||||
589515E02231AD9C0036BDE0 /* RCTSurfacePresenterStub.h in Headers */,
|
||||
59EDBCAD1FDF4E0C003573DE /* RCTScrollContentView.h in Headers */,
|
||||
59EDBCA71FDF4E0C003573DE /* RCTScrollableProtocol.h in Headers */,
|
||||
591F78DC202ADB22004A668C /* RCTLayout.h in Headers */,
|
||||
|
||||
Reference in New Issue
Block a user