Fabric: Simplifying the integration among RCTSurfacePresenter, RCTMountingManager, and RCTFabricSurface

Summary:
Changes:
* RCTMountingManager got two dedicated methods that designate some external view as a Surface viewport;
* The wiring between views now happens right in `start` and `stop` methods (because there is no reason to do it later); now it's symmetrical and straightforward;
* A couple of Surface legacy statuses were removed; they are not used and do not convey useful information anyway.
Changelog: [Internal] Fabric-specific internal change.

Reviewed By: sammy-SC

Differential Revision: D26095434

fbshipit-source-id: 37828e093a40a1ad22ad78f110c18a8f27781ba7
This commit is contained in:
Valentin Shergin 2021-02-01 11:38:08 -08:00 коммит произвёл Facebook GitHub Bot
Родитель a81b7d18fa
Коммит 1ee87e1f97
5 изменённых файлов: 50 добавлений и 40 удалений

Просмотреть файл

@ -23,17 +23,12 @@ typedef NS_OPTIONS(NSInteger, RCTSurfaceStage) {
RCTSurfaceStageSurfaceDidStop = 1 << 7, // Surface stopped
// Most of the previously existed stages make no sense in the new architecture;
// now Surface exposes only three simple stages:
//
// Surface object was constructed and still valid.
RCTSurfaceStageInitialized = RCTSurfaceStageSurfaceDidInitialize,
// Surface was started.
RCTSurfaceStageStarted = 1 << 8,
// All off-main-thread work is done; we are ready to mount the UI.
RCTSurfaceStagePrepared = RCTSurfaceStageBridgeDidLoad | RCTSurfaceStageModuleDidLoad | RCTSurfaceStageSurfaceDidRun |
RCTSurfaceStageSurfaceDidInitialRendering | RCTSurfaceStageSurfaceDidInitialLayout,
// All main-thread work is done, the UI was mounted.
RCTSurfaceStageMounted = RCTSurfaceStageSurfaceDidInitialMounting,
// now Surface exposes only two simple stages:
RCTSurfaceStagePreparing = RCTSurfaceStageSurfaceDidInitialize | RCTSurfaceStageBridgeDidLoad |
RCTSurfaceStageModuleDidLoad,
RCTSurfaceStageRunning = RCTSurfaceStagePreparing | RCTSurfaceStageSurfaceDidRun |
RCTSurfaceStageSurfaceDidInitialRendering | RCTSurfaceStageSurfaceDidInitialLayout |
RCTSurfaceStageSurfaceDidInitialMounting,
};
/**

Просмотреть файл

@ -26,6 +26,20 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, weak) id<RCTMountingManagerDelegate> delegate;
@property (nonatomic, strong) RCTComponentViewRegistry *componentViewRegistry;
/**
* Designates the view as a rendering viewport of a React Native surface.
* The provided view must not have any subviews, and the caller is not supposed to interact with the view hierarchy
* inside the provided view. The view hierarchy created by mounting infrastructure inside the provided view does not
* influence the intrinsic size of the view and cannot be measured using UIView/UIKit layout API.
* Must be called on the main thead.
*/
- (void)attachSurfaceToView:(UIView *)view surfaceId:(facebook::react::SurfaceId)surfaceId;
/**
* Stops designating the view as a rendering viewport of a React Native surface.
*/
- (void)detachSurfaceFromView:(UIView *)view surfaceId:(facebook::react::SurfaceId)surfaceId;
/**
* Schedule a mounting transaction to be performed on the main thread.
* Can be called from any thread.
@ -46,7 +60,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)synchronouslyUpdateViewOnUIThread:(ReactTag)reactTag
changedProps:(NSDictionary *)props
componentDescriptor:(const facebook::react::ComponentDescriptor &)componentDescriptor;
componentDescriptor:(facebook::react::ComponentDescriptor const &)componentDescriptor;
@end
NS_ASSUME_NONNULL_END

Просмотреть файл

@ -13,6 +13,7 @@
#import <React/RCTFollyConvert.h>
#import <React/RCTLog.h>
#import <React/RCTUtils.h>
#import <react/renderer/components/root/RootShadowNode.h>
#import <react/renderer/core/LayoutableShadowNode.h>
#import <react/renderer/core/RawProps.h>
#import <react/renderer/debug/SystraceSection.h>
@ -146,6 +147,29 @@ static void RCTPerformMountInstructions(
return self;
}
- (void)attachSurfaceToView:(UIView *)view surfaceId:(SurfaceId)surfaceId
{
RCTAssertMainQueue();
RCTAssert(view.subviews.count == 0, @"The view must not have any subviews.");
RCTComponentViewDescriptor rootViewDescriptor =
[_componentViewRegistry dequeueComponentViewWithComponentHandle:RootShadowNode::Handle() tag:surfaceId];
[view addSubview:rootViewDescriptor.view];
}
- (void)detachSurfaceFromView:(UIView *)view surfaceId:(SurfaceId)surfaceId
{
RCTAssertMainQueue();
RCTComponentViewDescriptor rootViewDescriptor = [_componentViewRegistry componentViewDescriptorWithTag:surfaceId];
[rootViewDescriptor.view removeFromSuperview];
[_componentViewRegistry enqueueComponentViewWithComponentHandle:RootShadowNode::Handle()
tag:surfaceId
componentViewDescriptor:rootViewDescriptor];
}
- (void)scheduleTransaction:(MountingCoordinator::Shared const &)mountingCoordinator
{
if (RCTIsMainQueue()) {

Просмотреть файл

@ -381,8 +381,7 @@ static BackgroundExecutor RCTGetBackgroundExecutor()
{
RCTMountingManager *mountingManager = _mountingManager;
RCTExecuteOnMainQueue(^{
[mountingManager.componentViewRegistry dequeueComponentViewWithComponentHandle:RootShadowNode::Handle()
tag:surface.rootTag];
[mountingManager attachSurfaceToView:surface.view surfaceId:surface.rootTag];
});
LayoutContext layoutContext = RCTGetLayoutContext(surface.viewportOffset);
@ -402,15 +401,8 @@ static BackgroundExecutor RCTGetBackgroundExecutor()
RCTMountingManager *mountingManager = _mountingManager;
RCTExecuteOnMainQueue(^{
surface.view.rootView = nil;
RCTComponentViewDescriptor rootViewDescriptor =
[mountingManager.componentViewRegistry componentViewDescriptorWithTag:surface.rootTag];
[mountingManager.componentViewRegistry enqueueComponentViewWithComponentHandle:RootShadowNode::Handle()
tag:surface.rootTag
componentViewDescriptor:rootViewDescriptor];
[mountingManager detachSurfaceFromView:surface.view surfaceId:surface.rootTag];
});
[surface _unsetStage:(RCTSurfaceStagePrepared | RCTSurfaceStageMounted)];
}
- (void)_startAllSurfacesWithScheduler:(RCTScheduler *)scheduler
@ -452,10 +444,6 @@ static BackgroundExecutor RCTGetBackgroundExecutor()
- (void)schedulerDidFinishTransaction:(MountingCoordinator::Shared const &)mountingCoordinator
{
RCTFabricSurface *surface = [_surfaceRegistry surfaceForRootTag:mountingCoordinator->getSurfaceId()];
[surface _setStage:RCTSurfaceStagePrepared];
[_mountingManager scheduleTransaction:mountingCoordinator];
}
@ -509,17 +497,6 @@ static BackgroundExecutor RCTGetBackgroundExecutor()
{
RCTAssertMainQueue();
RCTFabricSurface *surface = [_surfaceRegistry surfaceForRootTag:rootTag];
RCTSurfaceStage stage = surface.stage;
if (stage & RCTSurfaceStagePrepared) {
// We have to progress the stage only if the preparing phase is done.
if ([surface _setStage:RCTSurfaceStageMounted]) {
auto rootComponentViewDescriptor =
[_mountingManager.componentViewRegistry componentViewDescriptorWithTag:rootTag];
surface.view.rootView = (RCTSurfaceRootView *)rootComponentViewDescriptor.view;
}
}
std::shared_lock<better::shared_mutex> lock(_observerListMutex);
for (id<RCTSurfacePresenterObserver> observer in _observers) {
if ([observer respondsToSelector:@selector(didMountComponentsWithRootTag:)]) {

Просмотреть файл

@ -73,17 +73,17 @@ using namespace facebook::react;
- (BOOL)start
{
if (![self _setStage:RCTSurfaceStageStarted]) {
if (![self _setStage:RCTSurfaceStageRunning]) {
return NO;
}
[_surfacePresenter registerSurface:self];
[_surfacePresenter registerSurface:self];
return YES;
}
- (BOOL)stop
{
if (![self _unsetStage:RCTSurfaceStageStarted]) {
if (![self _unsetStage:RCTSurfaceStageRunning]) {
return NO;
}