Fabric: Using SurfaceHandler on iOS

Summary:
This diff migrates iOS renderer to using SurfaceHandler directly instead of calling Scheduler methods.

Major changes:
* RCTFabricSurface only stores a SurfaceHandler and platform-specific parts (such as a UIView instance and TouchHandler); all other pieces of state are stored in SurfaceHandler object.
* All the state changes initiated from RCTFabricSurface are performed via calling corresponding methods on SurfaceHandler (bypassing RCTSurfacePresenter, RCTScheduler, Scheduler, and UIManager).
* Every RCTSurfaceHandler is responsible for observing `UIContentSizeCategoryDidChangeNotification` and communicating the change down to SurfaceHandler. (Besides code simplifications it's more correct because on iOS the DPI actually depends on a particular UIScreen/UIWindow associated with UIView and *not* global for the whole app.)

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: sammy-SC

Differential Revision: D24290778

fbshipit-source-id: 62b600c3f1b2e66a7513481404af941ef8b78bec
This commit is contained in:
Valentin Shergin
2021-02-09 08:10:43 -08:00
committed by Facebook GitHub Bot
parent 5c202cafd6
commit 33d6091cac
6 changed files with 154 additions and 343 deletions
+4 -16
View File
@@ -14,6 +14,7 @@
#import <react/renderer/core/LayoutContext.h>
#import <react/renderer/mounting/MountingCoordinator.h>
#import <react/renderer/scheduler/SchedulerToolbox.h>
#import <react/renderer/scheduler/SurfaceHandler.h>
#import <react/utils/ContextContainer.h>
NS_ASSUME_NONNULL_BEGIN
@@ -47,26 +48,13 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithToolbox:(facebook::react::SchedulerToolbox)toolbox;
- (void)startSurfaceWithSurfaceId:(facebook::react::SurfaceId)surfaceId
moduleName:(NSString *)moduleName
initialProps:(NSDictionary *)initialProps
layoutConstraints:(facebook::react::LayoutConstraints)layoutConstraints
layoutContext:(facebook::react::LayoutContext)layoutContext;
- (void)stopSurfaceWithSurfaceId:(facebook::react::SurfaceId)surfaceId;
- (CGSize)measureSurfaceWithLayoutConstraints:(facebook::react::LayoutConstraints)layoutConstraints
layoutContext:(facebook::react::LayoutContext)layoutContext
surfaceId:(facebook::react::SurfaceId)surfaceId;
- (void)constraintSurfaceLayoutWithLayoutConstraints:(facebook::react::LayoutConstraints)layoutConstraints
layoutContext:(facebook::react::LayoutContext)layoutContext
surfaceId:(facebook::react::SurfaceId)surfaceId;
- (void)registerSurface:(facebook::react::SurfaceHandler const &)surfaceHandler;
- (void)unregisterSurface:(facebook::react::SurfaceHandler const &)surfaceHandler;
- (facebook::react::ComponentDescriptor const *)findComponentDescriptorByHandle_DO_NOT_USE_THIS_IS_BROKEN:
(facebook::react::ComponentHandle)handle;
- (facebook::react::MountingCoordinator::Shared)mountingCoordinatorWithSurfaceId:(facebook::react::SurfaceId)surfaceId;
- (void)setupAnimationDriver:(facebook::react::SurfaceHandler const &)surfaceHandler;
- (void)onAnimationStarted;
+6 -35
View File
@@ -139,43 +139,14 @@ class LayoutAnimationDelegateProxy : public LayoutAnimationStatusDelegate, publi
_animationDriver = nullptr;
}
- (void)startSurfaceWithSurfaceId:(SurfaceId)surfaceId
moduleName:(NSString *)moduleName
initialProps:(NSDictionary *)initialProps
layoutConstraints:(LayoutConstraints)layoutConstraints
layoutContext:(LayoutContext)layoutContext
- (void)registerSurface:(facebook::react::SurfaceHandler const &)surfaceHandler
{
SystraceSection s("-[RCTScheduler startSurfaceWithSurfaceId:...]");
auto props = convertIdToFollyDynamic(initialProps);
_scheduler->startSurface(surfaceId, RCTStringFromNSString(moduleName), props, layoutConstraints, layoutContext);
_scheduler->findMountingCoordinator(surfaceId)->setMountingOverrideDelegate(_animationDriver);
_scheduler->renderTemplateToSurface(
surfaceId, props.getDefault("navigationConfig").getDefault("initialUITemplate", "").getString());
_scheduler->registerSurface(surfaceHandler);
}
- (void)stopSurfaceWithSurfaceId:(SurfaceId)surfaceId
- (void)unregisterSurface:(facebook::react::SurfaceHandler const &)surfaceHandler
{
SystraceSection s("-[RCTScheduler stopSurfaceWithSurfaceId:]");
_scheduler->stopSurface(surfaceId);
}
- (CGSize)measureSurfaceWithLayoutConstraints:(LayoutConstraints)layoutConstraints
layoutContext:(LayoutContext)layoutContext
surfaceId:(SurfaceId)surfaceId
{
SystraceSection s("-[RCTScheduler measureSurfaceWithLayoutConstraints:]");
return RCTCGSizeFromSize(_scheduler->measureSurface(surfaceId, layoutConstraints, layoutContext));
}
- (void)constraintSurfaceLayoutWithLayoutConstraints:(LayoutConstraints)layoutConstraints
layoutContext:(LayoutContext)layoutContext
surfaceId:(SurfaceId)surfaceId
{
SystraceSection s("-[RCTScheduler constraintSurfaceLayoutWithLayoutConstraints:]");
_scheduler->constraintSurfaceLayout(surfaceId, layoutConstraints, layoutContext);
_scheduler->unregisterSurface(surfaceHandler);
}
- (ComponentDescriptor const *)findComponentDescriptorByHandle_DO_NOT_USE_THIS_IS_BROKEN:(ComponentHandle)handle
@@ -183,9 +154,9 @@ class LayoutAnimationDelegateProxy : public LayoutAnimationStatusDelegate, publi
return _scheduler->findComponentDescriptorByHandle_DO_NOT_USE_THIS_IS_BROKEN(handle);
}
- (MountingCoordinator::Shared)mountingCoordinatorWithSurfaceId:(SurfaceId)surfaceId
- (void)setupAnimationDriver:(facebook::react::SurfaceHandler const &)surfaceHandler
{
return _scheduler->findMountingCoordinator(surfaceId);
surfaceHandler.getMountingCoordinator()->setMountingOverrideDelegate(_animationDriver);
}
- (void)onAnimationStarted
+8 -16
View File
@@ -11,6 +11,7 @@
#import <React/RCTSurfacePresenterStub.h>
#import <React/RCTSurfaceStage.h>
#import <ReactCommon/RuntimeExecutor.h>
#import <react/renderer/scheduler/SurfaceHandler.h>
#import <react/utils/ContextContainer.h>
NS_ASSUME_NONNULL_BEGIN
@@ -45,34 +46,25 @@ NS_ASSUME_NONNULL_BEGIN
@interface RCTSurfacePresenter (Surface) <RCTSurfacePresenterStub>
/**
/*
* Surface uses these methods to register itself in the Presenter.
*/
- (void)registerSurface:(RCTFabricSurface *)surface;
- (void)unregisterSurface:(RCTFabricSurface *)surface;
- (void)setProps:(NSDictionary *)props surface:(RCTFabricSurface *)surface;
@property (readonly) RCTMountingManager *mountingManager;
- (nullable RCTFabricSurface *)surfaceForRootTag:(ReactTag)rootTag;
/**
* Measures the Surface with given constraints.
*/
- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize
maximumSize:(CGSize)maximumSize
surface:(RCTFabricSurface *)surface;
/**
* Sets `minimumSize` and `maximumSize` layout constraints for the Surface.
*/
- (void)setMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize surface:(RCTFabricSurface *)surface;
- (BOOL)synchronouslyUpdateViewOnUIThread:(NSNumber *)reactTag props:(NSDictionary *)props;
- (BOOL)synchronouslyWaitSurface:(RCTFabricSurface *)surface timeout:(NSTimeInterval)timeout;
- (void)setupAnimationDriverWithSurfaceHandler:(facebook::react::SurfaceHandler const &)surfaceHandler;
/*
* Deprecated.
* Use `RCTMountingTransactionObserverCoordinator` instead.
*/
- (void)addObserver:(id<RCTSurfacePresenterObserver>)observer;
- (void)removeObserver:(id<RCTSurfacePresenterObserver>)observer;
/*
+14 -127
View File
@@ -40,25 +40,6 @@
using namespace facebook::react;
static inline LayoutConstraints RCTGetLayoutConstraintsForSize(CGSize minimumSize, CGSize maximumSize)
{
return {
.minimumSize = RCTSizeFromCGSize(minimumSize),
.maximumSize = RCTSizeFromCGSize(maximumSize),
.layoutDirection = RCTLayoutDirection([[RCTI18nUtil sharedInstance] isRTL]),
};
}
static inline LayoutContext RCTGetLayoutContext(CGPoint viewportOffset)
{
return {
.pointScaleFactor = RCTScreenScale(),
.swapLeftAndRightInRTL =
[[RCTI18nUtil sharedInstance] isRTL] && [[RCTI18nUtil sharedInstance] doLeftAndRightSwapInRTL],
.fontSizeMultiplier = RCTFontSizeMultiplier(),
.viewportOffset = RCTPointFromCGPoint(viewportOffset)};
}
static dispatch_queue_t RCTGetBackgroundQueue()
{
static dispatch_queue_t queue;
@@ -119,16 +100,16 @@ static BackgroundExecutor RCTGetBackgroundExecutor()
_observers = [NSMutableArray array];
_scheduler = [self _createScheduler];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(_handleContentSizeCategoryDidChangeNotification:)
name:UIContentSizeCategoryDidChangeNotification
object:nil];
}
return self;
}
- (RCTMountingManager *)mountingManager
{
return _mountingManager;
}
- (RCTScheduler *_Nullable)_scheduler
{
std::lock_guard<std::mutex> lock(_schedulerAccessMutex);
@@ -163,10 +144,10 @@ static BackgroundExecutor RCTGetBackgroundExecutor()
- (void)registerSurface:(RCTFabricSurface *)surface
{
RCTScheduler *scheduler = [self _scheduler];
[_surfaceRegistry registerSurface:surface];
RCTScheduler *scheduler = [self _scheduler];
if (scheduler) {
[self _startSurface:surface scheduler:scheduler];
[scheduler registerSurface:surface.surfaceHandler];
}
}
@@ -174,54 +155,16 @@ static BackgroundExecutor RCTGetBackgroundExecutor()
{
RCTScheduler *scheduler = [self _scheduler];
if (scheduler) {
[self _stopSurface:surface scheduler:scheduler];
[scheduler unregisterSurface:surface.surfaceHandler];
}
[_surfaceRegistry unregisterSurface:surface];
}
- (void)setProps:(NSDictionary *)props surface:(RCTFabricSurface *)surface
{
RCTScheduler *scheduler = [self _scheduler];
if (scheduler) {
[self _stopSurface:surface scheduler:scheduler];
[self _startSurface:surface scheduler:scheduler];
}
}
- (RCTFabricSurface *)surfaceForRootTag:(ReactTag)rootTag
{
return [_surfaceRegistry surfaceForRootTag:rootTag];
}
- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize
maximumSize:(CGSize)maximumSize
surface:(RCTFabricSurface *)surface
{
RCTScheduler *scheduler = [self _scheduler];
if (!scheduler) {
return minimumSize;
}
LayoutContext layoutContext = RCTGetLayoutContext(surface.viewportOffset);
LayoutConstraints layoutConstraints = RCTGetLayoutConstraintsForSize(minimumSize, maximumSize);
return [scheduler measureSurfaceWithLayoutConstraints:layoutConstraints
layoutContext:layoutContext
surfaceId:surface.rootTag];
}
- (void)setMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize surface:(RCTFabricSurface *)surface
{
RCTScheduler *scheduler = [self _scheduler];
if (!scheduler) {
return;
}
LayoutContext layoutContext = RCTGetLayoutContext(surface.viewportOffset);
LayoutConstraints layoutConstraints = RCTGetLayoutConstraintsForSize(minimumSize, maximumSize);
[scheduler constraintSurfaceLayoutWithLayoutConstraints:layoutConstraints
layoutContext:layoutContext
surfaceId:surface.rootTag];
}
- (UIView *)findComponentViewWithTag_DO_NOT_USE_DEPRECATED:(NSInteger)tag
{
UIView<RCTComponentViewProtocol> *componentView =
@@ -253,22 +196,9 @@ static BackgroundExecutor RCTGetBackgroundExecutor()
return YES;
}
- (BOOL)synchronouslyWaitSurface:(RCTFabricSurface *)surface timeout:(NSTimeInterval)timeout
- (void)setupAnimationDriverWithSurfaceHandler:(facebook::react::SurfaceHandler const &)surfaceHandler
{
RCTScheduler *scheduler = [self _scheduler];
if (!scheduler) {
return NO;
}
auto mountingCoordinator = [scheduler mountingCoordinatorWithSurfaceId:surface.rootTag];
if (!mountingCoordinator->waitForTransaction(std::chrono::duration<NSTimeInterval>(timeout))) {
return NO;
}
[_mountingManager scheduleTransaction:mountingCoordinator];
return YES;
[[self _scheduler] setupAnimationDriver:surfaceHandler];
}
- (BOOL)suspend
@@ -377,39 +307,12 @@ static BackgroundExecutor RCTGetBackgroundExecutor()
return scheduler;
}
- (void)_startSurface:(RCTFabricSurface *)surface scheduler:(RCTScheduler *)scheduler
{
RCTMountingManager *mountingManager = _mountingManager;
RCTExecuteOnMainQueue(^{
[mountingManager attachSurfaceToView:surface.view surfaceId:surface.rootTag];
});
LayoutContext layoutContext = RCTGetLayoutContext(surface.viewportOffset);
LayoutConstraints layoutConstraints = RCTGetLayoutConstraintsForSize(surface.minimumSize, surface.maximumSize);
[scheduler startSurfaceWithSurfaceId:surface.rootTag
moduleName:surface.moduleName
initialProps:surface.properties
layoutConstraints:layoutConstraints
layoutContext:layoutContext];
}
- (void)_stopSurface:(RCTFabricSurface *)surface scheduler:(RCTScheduler *)scheduler
{
[scheduler stopSurfaceWithSurfaceId:surface.rootTag];
RCTMountingManager *mountingManager = _mountingManager;
RCTExecuteOnMainQueue(^{
[mountingManager detachSurfaceFromView:surface.view surfaceId:surface.rootTag];
});
}
- (void)_startAllSurfacesWithScheduler:(RCTScheduler *)scheduler
{
[_surfaceRegistry enumerateWithBlock:^(NSEnumerator<RCTFabricSurface *> *enumerator) {
for (RCTFabricSurface *surface in enumerator) {
[self _startSurface:surface scheduler:scheduler];
[scheduler registerSurface:surface.surfaceHandler];
[surface start];
}
}];
}
@@ -418,24 +321,8 @@ static BackgroundExecutor RCTGetBackgroundExecutor()
{
[_surfaceRegistry enumerateWithBlock:^(NSEnumerator<RCTFabricSurface *> *enumerator) {
for (RCTFabricSurface *surface in enumerator) {
[self _stopSurface:surface scheduler:scheduler];
}
}];
}
- (void)_handleContentSizeCategoryDidChangeNotification:(NSNotification *)notification
{
RCTScheduler *scheduler = [self _scheduler];
[_surfaceRegistry enumerateWithBlock:^(NSEnumerator<RCTFabricSurface *> *enumerator) {
for (RCTFabricSurface *surface in enumerator) {
LayoutContext layoutContext = RCTGetLayoutContext(surface.viewportOffset);
LayoutConstraints layoutConstraints = RCTGetLayoutConstraintsForSize(surface.minimumSize, surface.maximumSize);
[scheduler constraintSurfaceLayoutWithLayoutConstraints:layoutConstraints
layoutContext:layoutContext
surfaceId:surface.rootTag];
[surface stop];
[scheduler unregisterSurface:surface.surfaceHandler];
}
}];
}
+2 -6
View File
@@ -8,6 +8,7 @@
#import <React/RCTSurfaceProtocol.h>
#import <React/RCTSurfaceStage.h>
#import <react/renderer/mounting/MountingCoordinator.h>
#import <react/renderer/scheduler/SurfaceHandler.h>
NS_ASSUME_NONNULL_BEGIN
@@ -128,12 +129,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface RCTFabricSurface (Internal)
/**
* Sets and clears given stage flags (bitmask).
* Returns `YES` if the actual state was changed.
*/
- (BOOL)_setStage:(RCTSurfaceStage)stage;
- (BOOL)_unsetStage:(RCTSurfaceStage)stage;
- (facebook::react::SurfaceHandler const &)surfaceHandler;
@end
+120 -143
View File
@@ -10,6 +10,10 @@
#import <mutex>
#import <React/RCTAssert.h>
#import <React/RCTConversions.h>
#import <React/RCTFollyConvert.h>
#import <React/RCTI18nUtil.h>
#import <React/RCTMountingManager.h>
#import <React/RCTSurfaceDelegate.h>
#import <React/RCTSurfaceRootView.h>
#import <React/RCTSurfaceTouchHandler.h>
@@ -23,26 +27,19 @@
using namespace facebook::react;
@implementation RCTFabricSurface {
// Immutable
__weak RCTSurfacePresenter *_surfacePresenter;
NSString *_moduleName;
// Protected by the `_mutex`
std::mutex _mutex;
RCTSurfaceStage _stage;
NSDictionary *_properties;
CGSize _minimumSize;
CGSize _maximumSize;
CGPoint _viewportOffset;
CGSize _intrinsicSize;
// `SurfaceHandler` is a thread-safe object, so we don't need additional synchronization.
// Objective-C++ classes cannot have instance variables without default constructors,
// hence we wrap a value into `optional` to workaround it.
better::optional<SurfaceHandler> _surfaceHandler;
// The Main thread only
// Can be accessed from the main thread only.
RCTSurfaceView *_Nullable _view;
RCTSurfaceTouchHandler *_Nullable _touchHandler;
}
@synthesize delegate = _delegate;
@synthesize rootTag = _rootTag;
- (instancetype)initWithSurfacePresenter:(RCTSurfacePresenter *)surfacePresenter
moduleName:(NSString *)moduleName
@@ -50,15 +47,19 @@ using namespace facebook::react;
{
if (self = [super init]) {
_surfacePresenter = surfacePresenter;
_moduleName = moduleName;
_properties = [initialProperties copy];
_rootTag = [RCTAllocateRootViewTag() integerValue];
_minimumSize = CGSizeZero;
_surfaceHandler =
SurfaceHandler{RCTStringFromNSString(moduleName), (SurfaceId)[RCTAllocateRootViewTag() integerValue]};
_surfaceHandler->setProps(convertIdToFollyDynamic(initialProperties));
_maximumSize = CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX);
[_surfacePresenter registerSurface:self];
_stage = RCTSurfaceStageSurfaceDidInitialize;
[self _updateLayoutContext];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleContentSizeCategoryDidChangeNotification:)
name:UIContentSizeCategoryDidChangeNotification
object:nil];
}
return self;
@@ -67,40 +68,48 @@ using namespace facebook::react;
- (void)resetWithSurfacePresenter:(RCTSurfacePresenter *)surfacePresenter
{
_surfacePresenter = surfacePresenter;
_stage = RCTSurfaceStageSurfaceDidInitialize;
_view = nil;
}
- (void)dealloc
{
[_surfacePresenter unregisterSurface:self];
}
#pragma mark - Life-cycle management
- (BOOL)start
{
if (![self _setStage:RCTSurfaceStageRunning]) {
return NO;
}
_surfaceHandler->start();
[self _propagateStageChange];
[_surfacePresenter registerSurface:self];
RCTExecuteOnMainQueue(^{
[self->_surfacePresenter.mountingManager attachSurfaceToView:self.view
surfaceId:self->_surfaceHandler->getSurfaceId()];
});
[_surfacePresenter setupAnimationDriverWithSurfaceHandler:*_surfaceHandler];
return YES;
}
- (BOOL)stop
{
if (![self _unsetStage:RCTSurfaceStageRunning]) {
return NO;
}
_surfaceHandler->stop();
[self _propagateStageChange];
RCTExecuteOnMainQueue(^{
[self->_surfacePresenter.mountingManager detachSurfaceFromView:self.view
surfaceId:self->_surfaceHandler->getSurfaceId()];
});
[_surfacePresenter unregisterSurface:self];
return YES;
}
- (void)dealloc
{
[self stop];
}
#pragma mark - Immutable Properties (no need to enforce synchronization)
- (NSString *)moduleName
{
return _moduleName;
return RCTNSStringFromString(_surfaceHandler->getModuleName());
}
#pragma mark - Main-Threaded Routines
@@ -122,49 +131,13 @@ using namespace facebook::react;
- (RCTSurfaceStage)stage
{
std::lock_guard<std::mutex> lock(_mutex);
return _stage;
return _surfaceHandler->getStatus() == SurfaceHandler::Status::Running ? RCTSurfaceStageRunning
: RCTSurfaceStagePreparing;
}
- (BOOL)_setStage:(RCTSurfaceStage)stage
- (void)_propagateStageChange
{
return [self _setStage:stage setOrUnset:YES];
}
- (BOOL)_unsetStage:(RCTSurfaceStage)stage
{
return [self _setStage:stage setOrUnset:NO];
}
- (BOOL)_setStage:(RCTSurfaceStage)stage setOrUnset:(BOOL)setOrUnset
{
RCTSurfaceStage updatedStage;
{
std::lock_guard<std::mutex> lock(_mutex);
if (setOrUnset) {
updatedStage = (RCTSurfaceStage)(_stage | stage);
} else {
updatedStage = (RCTSurfaceStage)(_stage & ~stage);
}
if (updatedStage == _stage) {
return NO;
}
_stage = updatedStage;
}
[self _propagateStageChange:updatedStage];
return YES;
}
- (void)_propagateStageChange:(RCTSurfaceStage)stage
{
// Updating the `view`
RCTExecuteOnMainQueue(^{
self->_view.stage = stage;
});
RCTSurfaceStage stage = self.stage;
// Notifying the `delegate`
id<RCTSurfaceDelegate> delegate = self.delegate;
@@ -173,114 +146,113 @@ using namespace facebook::react;
}
}
- (void)_updateLayoutContext
{
auto layoutConstraints = _surfaceHandler->getLayoutConstraints();
auto layoutContext = _surfaceHandler->getLayoutContext();
layoutContext.pointScaleFactor = RCTScreenScale();
layoutContext.swapLeftAndRightInRTL =
[[RCTI18nUtil sharedInstance] isRTL] && [[RCTI18nUtil sharedInstance] doLeftAndRightSwapInRTL];
layoutContext.fontSizeMultiplier = RCTFontSizeMultiplier();
_surfaceHandler->constraintLayout(layoutConstraints, layoutContext);
}
#pragma mark - Properties Management
- (NSDictionary *)properties
{
std::lock_guard<std::mutex> lock(_mutex);
return _properties;
return convertFollyDynamicToId(_surfaceHandler->getProps());
}
- (void)setProperties:(NSDictionary *)properties
{
{
std::lock_guard<std::mutex> lock(_mutex);
if ([properties isEqualToDictionary:_properties]) {
return;
}
_properties = [properties copy];
}
[_surfacePresenter setProps:properties surface:self];
_surfaceHandler->setProps(convertIdToFollyDynamic(properties));
}
#pragma mark - Layout
- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize
{
return [_surfacePresenter sizeThatFitsMinimumSize:minimumSize maximumSize:maximumSize surface:self];
}
#pragma mark - Size Constraints
- (void)setSize:(CGSize)size
{
[self setMinimumSize:size maximumSize:size viewportOffset:_viewportOffset];
}
- (void)setMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize viewportOffset:(CGPoint)viewportOffset
{
{
std::lock_guard<std::mutex> lock(_mutex);
if (CGSizeEqualToSize(minimumSize, _minimumSize) && CGSizeEqualToSize(maximumSize, _maximumSize) &&
CGPointEqualToPoint(viewportOffset, _viewportOffset)) {
return;
}
auto layoutConstraints = _surfaceHandler->getLayoutConstraints();
auto layoutContext = _surfaceHandler->getLayoutContext();
_maximumSize = maximumSize;
_minimumSize = minimumSize;
_viewportOffset = viewportOffset;
layoutConstraints.minimumSize = RCTSizeFromCGSize(minimumSize);
layoutConstraints.maximumSize = RCTSizeFromCGSize(maximumSize);
if (!isnan(viewportOffset.x) && !isnan(viewportOffset.y)) {
layoutContext.viewportOffset = RCTPointFromCGPoint(viewportOffset);
}
[_surfacePresenter setMinimumSize:minimumSize maximumSize:maximumSize surface:self];
_surfaceHandler->constraintLayout(layoutConstraints, layoutContext);
}
- (void)setMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize
{
[self setMinimumSize:minimumSize maximumSize:maximumSize viewportOffset:_viewportOffset];
[self setMinimumSize:minimumSize maximumSize:maximumSize viewportOffset:CGPointMake(NAN, NAN)];
}
- (void)setSize:(CGSize)size
{
[self setMinimumSize:size maximumSize:size];
}
- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize
{
auto layoutConstraints = _surfaceHandler->getLayoutConstraints();
auto layoutContext = _surfaceHandler->getLayoutContext();
layoutConstraints.minimumSize = RCTSizeFromCGSize(minimumSize);
layoutConstraints.maximumSize = RCTSizeFromCGSize(maximumSize);
return RCTCGSizeFromSize(_surfaceHandler->measure(layoutConstraints, layoutContext));
}
- (CGSize)minimumSize
{
std::lock_guard<std::mutex> lock(_mutex);
return _minimumSize;
return RCTCGSizeFromSize(_surfaceHandler->getLayoutConstraints().minimumSize);
}
- (CGSize)maximumSize
{
std::lock_guard<std::mutex> lock(_mutex);
return _maximumSize;
return RCTCGSizeFromSize(_surfaceHandler->getLayoutConstraints().maximumSize);
}
- (CGPoint)viewportOffset
{
std::lock_guard<std::mutex> lock(_mutex);
return _viewportOffset;
}
#pragma mark - intrinsicSize
- (void)setIntrinsicSize:(CGSize)intrinsicSize
{
{
std::lock_guard<std::mutex> lock(_mutex);
if (CGSizeEqualToSize(intrinsicSize, _intrinsicSize)) {
return;
}
_intrinsicSize = intrinsicSize;
}
// Notifying `delegate`
id<RCTSurfaceDelegate> delegate = self.delegate;
if ([delegate respondsToSelector:@selector(surface:didChangeIntrinsicSize:)]) {
[delegate surface:(RCTSurface *)(id)self didChangeIntrinsicSize:intrinsicSize];
}
}
- (CGSize)intrinsicSize
{
std::lock_guard<std::mutex> lock(_mutex);
return _intrinsicSize;
return RCTCGPointFromPoint(_surfaceHandler->getLayoutContext().viewportOffset);
}
#pragma mark - Synchronous Waiting
- (BOOL)synchronouslyWaitFor:(NSTimeInterval)timeout
{
return [_surfacePresenter synchronouslyWaitSurface:self timeout:timeout];
auto mountingCoordinator = _surfaceHandler->getMountingCoordinator();
if (!mountingCoordinator) {
return NO;
}
if (!mountingCoordinator->waitForTransaction(std::chrono::duration<NSTimeInterval>(timeout))) {
return NO;
}
[_surfacePresenter.mountingManager scheduleTransaction:mountingCoordinator];
return YES;
}
- (void)handleContentSizeCategoryDidChangeNotification:(NSNotification *)notification
{
[self _updateLayoutContext];
}
#pragma mark - Private
- (SurfaceHandler const &)surfaceHandler;
{
return *_surfaceHandler;
}
#pragma mark - Deprecated
@@ -296,7 +268,12 @@ using namespace facebook::react;
- (NSNumber *)rootViewTag
{
return @(_rootTag);
return @(_surfaceHandler->getSurfaceId());
}
- (NSInteger)rootTag
{
return (NSInteger)(_surfaceHandler->getSurfaceId());
}
@end