mirror of
https://github.com/status-im/react-native.git
synced 2025-02-22 14:18:23 +00:00
Fabric: ShadowTree::synchronize
and reliable constraintLayout
Summary: New `ShadowTree::synchronize` method allows to perform operations on ShadowTree without a risk of an unsuccessful commit. To make it happen, the `commitMutex_` is now recursive and `synchronize` acquires it before calling the callback. Using that we finally can implement reliable `constraintLayout`. Reviewed By: mdvacca Differential Revision: D10174281 fbshipit-source-id: 9864ebb5343d40e2da205272a834710f0ab730db
This commit is contained in:
parent
b9850844a5
commit
b8947c459f
@ -49,7 +49,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
layoutContext:(facebook::react::LayoutContext)layoutContext
|
||||
surfaceId:(facebook::react::SurfaceId)surfaceId;
|
||||
|
||||
- (BOOL)constraintSurfaceLayoutWithLayoutConstraints:(facebook::react::LayoutConstraints)layoutConstraints
|
||||
- (void)constraintSurfaceLayoutWithLayoutConstraints:(facebook::react::LayoutConstraints)layoutConstraints
|
||||
layoutContext:(facebook::react::LayoutContext)layoutContext
|
||||
surfaceId:(facebook::react::SurfaceId)surfaceId;
|
||||
|
||||
|
@ -80,11 +80,11 @@ private:
|
||||
return RCTCGSizeFromSize(_scheduler->measureSurface(surfaceId, layoutConstraints, layoutContext));
|
||||
}
|
||||
|
||||
- (BOOL)constraintSurfaceLayoutWithLayoutConstraints:(LayoutConstraints)layoutConstraints
|
||||
- (void)constraintSurfaceLayoutWithLayoutConstraints:(LayoutConstraints)layoutConstraints
|
||||
layoutContext:(LayoutContext)layoutContext
|
||||
surfaceId:(SurfaceId)surfaceId
|
||||
{
|
||||
return _scheduler->constraintSurfaceLayout(surfaceId, layoutConstraints, layoutContext);
|
||||
_scheduler->constraintSurfaceLayout(surfaceId, layoutConstraints, layoutContext);
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -57,9 +57,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* Sets `minimumSize` and `maximumSize` layout constraints for the Surface.
|
||||
* Returns `YES` if the operation finished successfully.
|
||||
*/
|
||||
- (BOOL)setMinimumSize:(CGSize)minimumSize
|
||||
- (void)setMinimumSize:(CGSize)minimumSize
|
||||
maximumSize:(CGSize)maximumSize
|
||||
surface:(RCTFabricSurface *)surface;
|
||||
|
||||
|
@ -119,7 +119,7 @@ using namespace facebook::react;
|
||||
surfaceId:surface.rootTag];
|
||||
}
|
||||
|
||||
- (BOOL)setMinimumSize:(CGSize)minimumSize
|
||||
- (void)setMinimumSize:(CGSize)minimumSize
|
||||
maximumSize:(CGSize)maximumSize
|
||||
surface:(RCTFabricSurface *)surface
|
||||
{
|
||||
@ -129,9 +129,9 @@ using namespace facebook::react;
|
||||
layoutConstraints.minimumSize = RCTSizeFromCGSize(minimumSize);
|
||||
layoutConstraints.maximumSize = RCTSizeFromCGSize(maximumSize);
|
||||
|
||||
return [self._scheduler constraintSurfaceLayoutWithLayoutConstraints:layoutConstraints
|
||||
layoutContext:layoutContext
|
||||
surfaceId:surface.rootTag];
|
||||
[self._scheduler constraintSurfaceLayoutWithLayoutConstraints:layoutConstraints
|
||||
layoutContext:layoutContext
|
||||
surfaceId:surface.rootTag];
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
@ -94,7 +94,7 @@ Size Scheduler::measureSurface(
|
||||
return shadowTree->measure(layoutConstraints, layoutContext);
|
||||
}
|
||||
|
||||
bool Scheduler::constraintSurfaceLayout(
|
||||
void Scheduler::constraintSurfaceLayout(
|
||||
SurfaceId surfaceId,
|
||||
const LayoutConstraints &layoutConstraints,
|
||||
const LayoutContext &layoutContext
|
||||
@ -102,7 +102,9 @@ bool Scheduler::constraintSurfaceLayout(
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
const auto &shadowTree = shadowTreeRegistry_.at(surfaceId);
|
||||
assert(shadowTree);
|
||||
return shadowTree->constraintLayout(layoutConstraints, layoutContext);
|
||||
shadowTree->synchronize([&]() {
|
||||
shadowTree->constraintLayout(layoutConstraints, layoutContext);
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - Delegate
|
||||
|
@ -53,10 +53,9 @@ public:
|
||||
* The user interface will be relaid out as a result. The operation will be
|
||||
* performed synchronously (including mounting) if the method is called
|
||||
* on the main thread.
|
||||
* Returns `true` if the operation finished successfully.
|
||||
* Can be called from any thread.
|
||||
*/
|
||||
bool constraintSurfaceLayout(
|
||||
void constraintSurfaceLayout(
|
||||
SurfaceId surfaceId,
|
||||
const LayoutConstraints &layoutConstraints,
|
||||
const LayoutContext &layoutContext
|
||||
|
@ -39,10 +39,15 @@ Tag ShadowTree::getRootTag() const {
|
||||
}
|
||||
|
||||
SharedRootShadowNode ShadowTree::getRootShadowNode() const {
|
||||
std::lock_guard<std::mutex> lock(commitMutex_);
|
||||
std::lock_guard<std::recursive_mutex> lock(commitMutex_);
|
||||
return rootShadowNode_;
|
||||
}
|
||||
|
||||
void ShadowTree::synchronize(std::function<void(void)> function) const {
|
||||
std::lock_guard<std::recursive_mutex> lock(commitMutex_);
|
||||
function();
|
||||
}
|
||||
|
||||
#pragma mark - Layout
|
||||
|
||||
Size ShadowTree::measure(const LayoutConstraints &layoutConstraints, const LayoutContext &layoutContext) const {
|
||||
@ -109,7 +114,7 @@ bool ShadowTree::commit(
|
||||
const SharedRootShadowNode &newRootShadowNode,
|
||||
const ShadowViewMutationList &mutations
|
||||
) const {
|
||||
std::lock_guard<std::mutex> lock(commitMutex_);
|
||||
std::lock_guard<std::recursive_mutex> lock(commitMutex_);
|
||||
|
||||
if (oldRootShadowNode != rootShadowNode_) {
|
||||
return false;
|
||||
|
@ -38,6 +38,16 @@ public:
|
||||
*/
|
||||
Tag getRootTag() const;
|
||||
|
||||
/*
|
||||
* Synchronously runs `function` when `commitMutex_` is acquired.
|
||||
* It is useful in cases when transactional consistency and/or successful
|
||||
* commit are required. E.g. you might want to run `measure` and
|
||||
* `constraintLayout` as part of a single congious transaction.
|
||||
* Use this only if it is necessary. All public methods of the class are
|
||||
* already thread-safe.
|
||||
*/
|
||||
void synchronize(std::function<void(void)> function) const;
|
||||
|
||||
#pragma mark - Layout
|
||||
|
||||
/*
|
||||
@ -93,7 +103,7 @@ private:
|
||||
const Tag rootTag_;
|
||||
mutable SharedRootShadowNode rootShadowNode_; // Protected by `commitMutex_`.
|
||||
ShadowTreeDelegate const *delegate_;
|
||||
mutable std::mutex commitMutex_;
|
||||
mutable std::recursive_mutex commitMutex_;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
Loading…
x
Reference in New Issue
Block a user