Remove reliance on shared_ptr for ASDisplayNodeLayouts (#1131)

* Remove reliance on shared_ptr for ASDisplayNodeLayouts

* Fix up

* Fix in yoga

* Back to let

* Returns inner pointer

* Trivial change to kick the CI
This commit is contained in:
Adlai Holler 2018-09-19 11:23:19 -07:00 committed by Huy Nguyen
parent cd608c9b18
commit ceed2d2008
10 changed files with 99 additions and 124 deletions

View File

@ -148,7 +148,6 @@
6947B0C01E36B4E30007C478 /* ASStackUnpositionedLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6947B0BD1E36B4E30007C478 /* ASStackUnpositionedLayout.mm */; };
6947B0C31E36B5040007C478 /* ASStackPositionedLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 6947B0C11E36B5040007C478 /* ASStackPositionedLayout.h */; settings = {ATTRIBUTES = (Private, ); }; };
6947B0C51E36B5040007C478 /* ASStackPositionedLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6947B0C21E36B5040007C478 /* ASStackPositionedLayout.mm */; };
6959433F1D70815300B0EE1F /* ASDisplayNodeLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6959433C1D70815300B0EE1F /* ASDisplayNodeLayout.mm */; };
695943401D70815300B0EE1F /* ASDisplayNodeLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 6959433D1D70815300B0EE1F /* ASDisplayNodeLayout.h */; settings = {ATTRIBUTES = (Private, ); }; };
695BE2551DC1245C008E6EA5 /* ASWrapperSpecSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 695BE2541DC1245C008E6EA5 /* ASWrapperSpecSnapshotTests.mm */; };
696F01EC1DD2AF450049FBD5 /* ASEventLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 696F01EA1DD2AF450049FBD5 /* ASEventLog.h */; settings = {ATTRIBUTES = (Public, ); }; };
@ -705,7 +704,6 @@
6947B0BD1E36B4E30007C478 /* ASStackUnpositionedLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASStackUnpositionedLayout.mm; sourceTree = "<group>"; };
6947B0C11E36B5040007C478 /* ASStackPositionedLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASStackPositionedLayout.h; sourceTree = "<group>"; };
6947B0C21E36B5040007C478 /* ASStackPositionedLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASStackPositionedLayout.mm; sourceTree = "<group>"; };
6959433C1D70815300B0EE1F /* ASDisplayNodeLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDisplayNodeLayout.mm; sourceTree = "<group>"; };
6959433D1D70815300B0EE1F /* ASDisplayNodeLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDisplayNodeLayout.h; sourceTree = "<group>"; };
695BE2541DC1245C008E6EA5 /* ASWrapperSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASWrapperSpecSnapshotTests.mm; sourceTree = "<group>"; };
696F01EA1DD2AF450049FBD5 /* ASEventLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEventLog.h; sourceTree = "<group>"; };
@ -1490,7 +1488,6 @@
690BC8C020F6D3490052A434 /* ASDisplayNodeCornerLayerDelegate.m */,
058D0A0C195D050800B7D73C /* ASDisplayNodeInternal.h */,
6959433D1D70815300B0EE1F /* ASDisplayNodeLayout.h */,
6959433C1D70815300B0EE1F /* ASDisplayNodeLayout.mm */,
CCA282C61E9EB64B0037E8B7 /* ASDisplayNodeTipState.h */,
CCA282C71E9EB64B0037E8B7 /* ASDisplayNodeTipState.m */,
68B8A4DB1CBD911D007E4543 /* ASImageNode+AnimatedImagePrivate.h */,
@ -2497,7 +2494,6 @@
DB78412E1C6BCE1600A9E2B4 /* _ASTransitionContext.m in Sources */,
B350620B1B010EFD0018CF92 /* ASTableView.mm in Sources */,
B350620E1B010EFD0018CF92 /* ASTextNode.mm in Sources */,
6959433F1D70815300B0EE1F /* ASDisplayNodeLayout.mm in Sources */,
68355B3E1CB57A60001D4E68 /* ASPINRemoteImageDownloader.m in Sources */,
CC034A141E649F1300626263 /* AsyncDisplayKit+IGListKitMethods.m in Sources */,
509E68661B3AEDD7009B9150 /* CoreGraphics+ASConvenience.m in Sources */,

View File

@ -49,6 +49,7 @@
- Small optimization to the layout spec & yoga layout systems by eliminating array copies. [Adlai Holler](https://github.com/Adlai-Holler)
- Optimize layout process by removing `ASRectMap`. [Adlai Holler](https://github.com/Adlai-Holler)
- Remove necessity to use view to access rangeController in ASTableNode, ASCollectionNode. [Michael Schneider](https://github.com/maicki)
- Remove display node's reliance on shared_ptr. [Adlai Holler](https://github.com/Adlai-Holler)
## 2.7
- Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877)

View File

@ -70,19 +70,19 @@
ASLayout *layout = nil;
NSUInteger version = _layoutVersion;
if (_calculatedDisplayNodeLayout->isValid(constrainedSize, parentSize, version)) {
ASDisplayNodeAssertNotNil(_calculatedDisplayNodeLayout->layout, @"-[ASDisplayNode layoutThatFits:parentSize:] _calculatedDisplayNodeLayout->layout should not be nil! %@", self);
layout = _calculatedDisplayNodeLayout->layout;
} else if (_pendingDisplayNodeLayout != nullptr && _pendingDisplayNodeLayout->isValid(constrainedSize, parentSize, version)) {
ASDisplayNodeAssertNotNil(_pendingDisplayNodeLayout->layout, @"-[ASDisplayNode layoutThatFits:parentSize:] _pendingDisplayNodeLayout->layout should not be nil! %@", self);
layout = _pendingDisplayNodeLayout->layout;
if (_calculatedDisplayNodeLayout.isValid(constrainedSize, parentSize, version)) {
ASDisplayNodeAssertNotNil(_calculatedDisplayNodeLayout.layout, @"-[ASDisplayNode layoutThatFits:parentSize:] _calculatedDisplayNodeLayout.layout should not be nil! %@", self);
layout = _calculatedDisplayNodeLayout.layout;
} else if (_pendingDisplayNodeLayout.isValid(constrainedSize, parentSize, version)) {
ASDisplayNodeAssertNotNil(_pendingDisplayNodeLayout.layout, @"-[ASDisplayNode layoutThatFits:parentSize:] _pendingDisplayNodeLayout.layout should not be nil! %@", self);
layout = _pendingDisplayNodeLayout.layout;
} else {
// Create a pending display node layout for the layout pass
layout = [self calculateLayoutThatFits:constrainedSize
restrictedToSize:self.style.size
relativeToParentSize:parentSize];
as_log_verbose(ASLayoutLog(), "Established pending layout for %@ in %s", self, sel_getName(_cmd));
_pendingDisplayNodeLayout = std::make_shared<ASDisplayNodeLayout>(layout, constrainedSize, parentSize, version);
_pendingDisplayNodeLayout = ASDisplayNodeLayout(layout, constrainedSize, parentSize,version);
ASDisplayNodeAssertNotNil(layout, @"-[ASDisplayNode layoutThatFits:parentSize:] newly calculated layout should not be nil! %@", self);
}
@ -156,16 +156,16 @@ ASLayoutElementStyleExtensibilityForwarding
- (ASLayout *)calculatedLayout
{
ASDN::MutexLocker l(__instanceLock__);
return _calculatedDisplayNodeLayout->layout;
return _calculatedDisplayNodeLayout.layout;
}
- (CGSize)calculatedSize
{
ASDN::MutexLocker l(__instanceLock__);
if (_pendingDisplayNodeLayout != nullptr && _pendingDisplayNodeLayout->isValid(_layoutVersion)) {
return _pendingDisplayNodeLayout->layout.size;
if (_pendingDisplayNodeLayout.isValid(_layoutVersion)) {
return _pendingDisplayNodeLayout.layout.size;
}
return _calculatedDisplayNodeLayout->layout.size;
return _calculatedDisplayNodeLayout.layout.size;
}
- (ASSizeRange)constrainedSizeForCalculatedLayout
@ -177,10 +177,10 @@ ASLayoutElementStyleExtensibilityForwarding
- (ASSizeRange)_locked_constrainedSizeForCalculatedLayout
{
ASAssertLocked(__instanceLock__);
if (_pendingDisplayNodeLayout != nullptr && _pendingDisplayNodeLayout->isValid(_layoutVersion)) {
return _pendingDisplayNodeLayout->constrainedSize;
if (_pendingDisplayNodeLayout.isValid(_layoutVersion)) {
return _pendingDisplayNodeLayout.constrainedSize;
}
return _calculatedDisplayNodeLayout->constrainedSize;
return _calculatedDisplayNodeLayout.constrainedSize;
}
@end
@ -246,10 +246,10 @@ ASLayoutElementStyleExtensibilityForwarding
// Figure out constrainedSize to use
ASSizeRange constrainedSize = ASSizeRangeMake(boundsSizeForLayout);
if (_pendingDisplayNodeLayout != nullptr) {
constrainedSize = _pendingDisplayNodeLayout->constrainedSize;
} else if (_calculatedDisplayNodeLayout->layout != nil) {
constrainedSize = _calculatedDisplayNodeLayout->constrainedSize;
if (_pendingDisplayNodeLayout.layout != nil) {
constrainedSize = _pendingDisplayNodeLayout.constrainedSize;
} else if (_calculatedDisplayNodeLayout.layout != nil) {
constrainedSize = _calculatedDisplayNodeLayout.constrainedSize;
}
__instanceLock__.unlock();
@ -305,20 +305,20 @@ ASLayoutElementStyleExtensibilityForwarding
// Prefer a newer and not yet applied _pendingDisplayNodeLayout over _calculatedDisplayNodeLayout
// If there is no such _pending, check if _calculated is valid to reuse (avoiding recalculation below).
BOOL pendingLayoutIsPreferred = NO;
if (_pendingDisplayNodeLayout != nullptr && _pendingDisplayNodeLayout->isValid(_layoutVersion)) {
NSUInteger calculatedVersion = _calculatedDisplayNodeLayout->version;
NSUInteger pendingVersion = _pendingDisplayNodeLayout->version;
if (_pendingDisplayNodeLayout.isValid(_layoutVersion)) {
NSUInteger calculatedVersion = _calculatedDisplayNodeLayout.version;
NSUInteger pendingVersion = _pendingDisplayNodeLayout.version;
if (pendingVersion > calculatedVersion) {
pendingLayoutIsPreferred = YES; // Newer _pending
} else if (pendingVersion == calculatedVersion
&& !ASSizeRangeEqualToSizeRange(_pendingDisplayNodeLayout->constrainedSize,
_calculatedDisplayNodeLayout->constrainedSize)) {
&& !ASSizeRangeEqualToSizeRange(_pendingDisplayNodeLayout.constrainedSize,
_calculatedDisplayNodeLayout.constrainedSize)) {
pendingLayoutIsPreferred = YES; // _pending with a different constrained size
}
}
BOOL calculatedLayoutIsReusable = (_calculatedDisplayNodeLayout->isValid(_layoutVersion)
&& (_calculatedDisplayNodeLayout->requestedLayoutFromAbove
|| CGSizeEqualToSize(_calculatedDisplayNodeLayout->layout.size, boundsSizeForLayout)));
BOOL calculatedLayoutIsReusable = (_calculatedDisplayNodeLayout.isValid(_layoutVersion)
&& (_calculatedDisplayNodeLayout.requestedLayoutFromAbove
|| CGSizeEqualToSize(_calculatedDisplayNodeLayout.layout.size, boundsSizeForLayout)));
if (!pendingLayoutIsPreferred && calculatedLayoutIsReusable) {
return;
}
@ -341,15 +341,15 @@ ASLayoutElementStyleExtensibilityForwarding
}
// Figure out previous and pending layouts for layout transition
std::shared_ptr<ASDisplayNodeLayout> nextLayout = _pendingDisplayNodeLayout;
#define layoutSizeDifferentFromBounds !CGSizeEqualToSize(nextLayout->layout.size, boundsSizeForLayout)
ASDisplayNodeLayout nextLayout = _pendingDisplayNodeLayout;
#define layoutSizeDifferentFromBounds !CGSizeEqualToSize(nextLayout.layout.size, boundsSizeForLayout)
// nextLayout was likely created by a call to layoutThatFits:, check if it is valid and can be applied.
// If our bounds size is different than it, or invalid, recalculate. Use #define to avoid nullptr->
BOOL pendingLayoutApplicable = NO;
if (nextLayout == nullptr) {
if (nextLayout.layout == nil) {
as_log_verbose(ASLayoutLog(), "No pending layout.");
} else if (nextLayout->isValid(_layoutVersion) == NO) {
} else if (!nextLayout.isValid(_layoutVersion)) {
as_log_verbose(ASLayoutLog(), "Pending layout is stale.");
} else if (layoutSizeDifferentFromBounds) {
as_log_verbose(ASLayoutLog(), "Pending layout size %@ doesn't match bounds size.", NSStringFromCGSize(nextLayout->layout.size));
@ -366,10 +366,10 @@ ASLayoutElementStyleExtensibilityForwarding
ASLayout *layout = [self calculateLayoutThatFits:constrainedSize
restrictedToSize:self.style.size
relativeToParentSize:boundsSizeForLayout];
nextLayout = std::make_shared<ASDisplayNodeLayout>(layout, constrainedSize, boundsSizeForLayout, version);
nextLayout = ASDisplayNodeLayout(layout, constrainedSize, boundsSizeForLayout, version);
// Now that the constrained size of pending layout might have been reused, the layout is useless
// Release it and any orphaned subnodes it retains
_pendingDisplayNodeLayout = nullptr;
_pendingDisplayNodeLayout.layout = nil;
}
if (didCreateNewContext) {
@ -378,8 +378,8 @@ ASLayoutElementStyleExtensibilityForwarding
// If our new layout's desired size for self doesn't match current size, ask our parent to update it.
// This can occur for either pre-calculated or newly-calculated layouts.
if (nextLayout->requestedLayoutFromAbove == NO
&& CGSizeEqualToSize(boundsSizeForLayout, nextLayout->layout.size) == NO) {
if (nextLayout.requestedLayoutFromAbove == NO
&& CGSizeEqualToSize(boundsSizeForLayout, nextLayout.layout.size) == NO) {
as_log_verbose(ASLayoutLog(), "Layout size doesn't match bounds size. Requesting layout from above.");
// The layout that we have specifies that this node (self) would like to be a different size
// than it currently is. Because that size has been computed within the constrainedSize, we
@ -387,7 +387,7 @@ ASLayoutElementStyleExtensibilityForwarding
// However, in some cases apps may manually interfere with this (setting a different bounds).
// In this case, we need to detect that we've already asked to be resized to match this
// particular ASLayout object, and shouldn't loop asking again unless we have a different ASLayout.
nextLayout->requestedLayoutFromAbove = YES;
nextLayout.requestedLayoutFromAbove = YES;
{
ASDN::MutexUnlocker u(__instanceLock__);
@ -396,11 +396,11 @@ ASLayoutElementStyleExtensibilityForwarding
// Update the layout's version here because _u_setNeedsLayoutFromAbove calls __setNeedsLayout which in turn increases _layoutVersion
// Failing to do this will cause the layout to be invalid immediately
nextLayout->version = _layoutVersion;
nextLayout.version = _layoutVersion;
}
// Prepare to transition to nextLayout
ASDisplayNodeAssertNotNil(nextLayout->layout, @"nextLayout->layout should not be nil! %@", self);
ASDisplayNodeAssertNotNil(nextLayout.layout, @"nextLayout->layout should not be nil! %@", self);
_pendingLayoutTransition = [[ASLayoutTransition alloc] initWithNode:self
pendingLayout:nextLayout
previousLayout:_calculatedDisplayNodeLayout];
@ -431,17 +431,16 @@ ASLayoutElementStyleExtensibilityForwarding
CGSize boundsSizeForLayout = ASCeilSizeValues(self.threadSafeBounds.size);
// Checkout if constrained size of pending or calculated display node layout can be used
if (_pendingDisplayNodeLayout != nullptr
&& (_pendingDisplayNodeLayout->requestedLayoutFromAbove
|| CGSizeEqualToSize(_pendingDisplayNodeLayout->layout.size, boundsSizeForLayout))) {
if (_pendingDisplayNodeLayout.requestedLayoutFromAbove
|| CGSizeEqualToSize(_pendingDisplayNodeLayout.layout.size, boundsSizeForLayout)) {
// We assume the size from the last returned layoutThatFits: layout was applied so use the pending display node
// layout constrained size
return _pendingDisplayNodeLayout->constrainedSize;
} else if (_calculatedDisplayNodeLayout->layout != nil
&& (_calculatedDisplayNodeLayout->requestedLayoutFromAbove
|| CGSizeEqualToSize(_calculatedDisplayNodeLayout->layout.size, boundsSizeForLayout))) {
return _pendingDisplayNodeLayout.constrainedSize;
} else if (_calculatedDisplayNodeLayout.layout != nil
&& (_calculatedDisplayNodeLayout.requestedLayoutFromAbove
|| CGSizeEqualToSize(_calculatedDisplayNodeLayout.layout.size, boundsSizeForLayout))) {
// We assume the _calculatedDisplayNodeLayout is still valid and the frame is not different
return _calculatedDisplayNodeLayout->constrainedSize;
return _calculatedDisplayNodeLayout.constrainedSize;
} else {
// In this case neither the _pendingDisplayNodeLayout or the _calculatedDisplayNodeLayout constrained size can
// be reused, so the current bounds is used. This is usual the case if a frame was set manually that differs to
@ -458,10 +457,10 @@ ASLayoutElementStyleExtensibilityForwarding
ASLayout *layout;
{
ASDN::MutexLocker l(__instanceLock__);
if (_calculatedDisplayNodeLayout->version < _layoutVersion) {
if (_calculatedDisplayNodeLayout.version < _layoutVersion) {
return;
}
layout = _calculatedDisplayNodeLayout->layout;
layout = _calculatedDisplayNodeLayout.layout;
}
for (ASDisplayNode *node in self.subnodes) {
@ -654,10 +653,10 @@ ASLayoutElementStyleExtensibilityForwarding
// Update calculated layout
let previousLayout = _calculatedDisplayNodeLayout;
let pendingLayout = std::make_shared<ASDisplayNodeLayout>(newLayout,
constrainedSize,
constrainedSize.max,
newLayoutVersion);
let pendingLayout = ASDisplayNodeLayout(newLayout,
constrainedSize,
constrainedSize.max,
newLayoutVersion);
[self _locked_setCalculatedDisplayNodeLayout:pendingLayout];
// Setup pending layout transition for animation
@ -869,7 +868,7 @@ ASLayoutElementStyleExtensibilityForwarding
{
ASAssertUnlocked(__instanceLock__);
ASLayoutTransition *pendingLayoutTransition = nil;
ASLayoutTransition *pendingLayoutTransition;
{
ASDN::MutexLocker l(__instanceLock__);
pendingLayoutTransition = _pendingLayoutTransition;
@ -918,7 +917,7 @@ ASLayoutElementStyleExtensibilityForwarding
}
NSArray *subnodes = [self subnodes];
NSArray *sublayouts = _calculatedDisplayNodeLayout->layout.sublayouts;
NSArray *sublayouts = _calculatedDisplayNodeLayout.layout.sublayouts;
let currentSubnodes = [[NSHashTable alloc] initWithOptions:NSHashTableObjectPointerPersonality
capacity:subnodes.count];
@ -970,8 +969,7 @@ ASLayoutElementStyleExtensibilityForwarding
if (_placeholderEnabled && !_placeholderImage && [self _locked_displaysAsynchronously]) {
// Zero-sized nodes do not require a placeholder.
ASLayout *layout = _calculatedDisplayNodeLayout->layout;
CGSize layoutSize = (layout ? layout.size : CGSizeZero);
CGSize layoutSize = _calculatedDisplayNodeLayout.layout.size;
if (layoutSize.width * layoutSize.height <= 0.0) {
return;
}
@ -995,26 +993,26 @@ ASLayoutElementStyleExtensibilityForwarding
_pendingLayoutTransition = nil;
}
- (void)_setCalculatedDisplayNodeLayout:(std::shared_ptr<ASDisplayNodeLayout>)displayNodeLayout
- (void)_setCalculatedDisplayNodeLayout:(const ASDisplayNodeLayout &)displayNodeLayout
{
ASDN::MutexLocker l(__instanceLock__);
[self _locked_setCalculatedDisplayNodeLayout:displayNodeLayout];
}
- (void)_locked_setCalculatedDisplayNodeLayout:(std::shared_ptr<ASDisplayNodeLayout>)displayNodeLayout
- (void)_locked_setCalculatedDisplayNodeLayout:(const ASDisplayNodeLayout &)displayNodeLayout
{
ASAssertLocked(__instanceLock__);
ASDisplayNodeAssertTrue(displayNodeLayout->layout.layoutElement == self);
ASDisplayNodeAssertTrue(displayNodeLayout->layout.size.width >= 0.0);
ASDisplayNodeAssertTrue(displayNodeLayout->layout.size.height >= 0.0);
ASDisplayNodeAssertTrue(displayNodeLayout.layout.layoutElement == self);
ASDisplayNodeAssertTrue(displayNodeLayout.layout.size.width >= 0.0);
ASDisplayNodeAssertTrue(displayNodeLayout.layout.size.height >= 0.0);
_calculatedDisplayNodeLayout = displayNodeLayout;
// Flatten the layout if it wasn't done before (@see -calculateLayoutThatFits:).
if ([ASDisplayNode shouldStoreUnflattenedLayouts]) {
_unflattenedLayout = displayNodeLayout->layout;
displayNodeLayout->layout = [_unflattenedLayout filteredNodeLayoutTree];
_unflattenedLayout = _calculatedDisplayNodeLayout.layout;
_calculatedDisplayNodeLayout.layout = [_unflattenedLayout filteredNodeLayoutTree];
}
_calculatedDisplayNodeLayout = displayNodeLayout;
}
@end

View File

@ -209,7 +209,7 @@
// For the root node in a Yoga tree, make sure to preserve the constrainedSize originally provided.
// This will be used for all relayouts triggered by children, since they escalate to root.
ASSizeRange range = parentNode ? ASSizeRangeUnconstrained : self.constrainedSizeForCalculatedLayout;
_pendingDisplayNodeLayout = std::make_shared<ASDisplayNodeLayout>(layout, range, parentSize, _layoutVersion);
_pendingDisplayNodeLayout = ASDisplayNodeLayout(layout, range, parentSize, _layoutVersion);
}
}

View File

@ -292,8 +292,6 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
_primitiveTraitCollection = ASPrimitiveTraitCollectionMakeDefault();
_calculatedDisplayNodeLayout = std::make_shared<ASDisplayNodeLayout>();
_pendingDisplayNodeLayout = nullptr;
_layoutVersion = 1;
_defaultLayoutTransitionDuration = 0.2;
@ -3812,21 +3810,19 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
[props addObject:@{ @"layoutVersion": @(_layoutVersion.load()) }];
[props addObject:@{ @"bounds": [NSValue valueWithCGRect:self.bounds] }];
if (_calculatedDisplayNodeLayout != nullptr) {
ASDisplayNodeLayout c = *_calculatedDisplayNodeLayout;
[props addObject:@{ @"calculatedLayout": c.layout }];
[props addObject:@{ @"calculatedVersion": @(c.version) }];
[props addObject:@{ @"calculatedConstrainedSize" : NSStringFromASSizeRange(c.constrainedSize) }];
if (c.requestedLayoutFromAbove) {
if (_calculatedDisplayNodeLayout.layout) {
[props addObject:@{ @"calculatedLayout": _calculatedDisplayNodeLayout.layout }];
[props addObject:@{ @"calculatedVersion": @(_calculatedDisplayNodeLayout.version) }];
[props addObject:@{ @"calculatedConstrainedSize" : NSStringFromASSizeRange(_calculatedDisplayNodeLayout.constrainedSize) }];
if (_calculatedDisplayNodeLayout.requestedLayoutFromAbove) {
[props addObject:@{ @"calculatedRequestedLayoutFromAbove": @"YES" }];
}
}
if (_pendingDisplayNodeLayout != nullptr) {
ASDisplayNodeLayout p = *_pendingDisplayNodeLayout;
[props addObject:@{ @"pendingLayout": p.layout }];
[props addObject:@{ @"pendingVersion": @(p.version) }];
[props addObject:@{ @"pendingConstrainedSize" : NSStringFromASSizeRange(p.constrainedSize) }];
if (p.requestedLayoutFromAbove) {
if (_pendingDisplayNodeLayout.layout) {
[props addObject:@{ @"pendingLayout": _pendingDisplayNodeLayout.layout }];
[props addObject:@{ @"pendingVersion": @(_pendingDisplayNodeLayout.version) }];
[props addObject:@{ @"pendingConstrainedSize" : NSStringFromASSizeRange(_pendingDisplayNodeLayout.constrainedSize) }];
if (_pendingDisplayNodeLayout.requestedLayoutFromAbove) {
[props addObject:@{ @"pendingRequestedLayoutFromAbove": (id)kCFNull }];
}
}

View File

@ -164,8 +164,8 @@ AS_EXTERN NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimest
std::atomic<int32_t> _pendingTransitionID;
ASLayoutTransition *_pendingLayoutTransition;
std::shared_ptr<ASDisplayNodeLayout> _calculatedDisplayNodeLayout;
std::shared_ptr<ASDisplayNodeLayout> _pendingDisplayNodeLayout;
ASDisplayNodeLayout _calculatedDisplayNodeLayout;
ASDisplayNodeLayout _pendingDisplayNodeLayout;
/// Sentinel for layout data. Incremented when we get -setNeedsLayout / -invalidateCalculatedLayout.
/// Starts at 1.

View File

@ -43,10 +43,16 @@ struct ASDisplayNodeLayout {
/**
* Returns whether this is valid for a given version
*/
BOOL isValid(NSUInteger version);
BOOL isValid(NSUInteger versionArg) {
return layout != nil && version >= versionArg;
}
/**
* Returns whether this is valid for a given constrained size, parent size, and version
*/
BOOL isValid(ASSizeRange constrainedSize, CGSize parentSize, NSUInteger version);
BOOL isValid(ASSizeRange theConstrainedSize, CGSize theParentSize, NSUInteger versionArg) {
return isValid(versionArg)
&& CGSizeEqualToSize(parentSize, theParentSize)
&& ASSizeRangeEqualToSizeRange(constrainedSize, theConstrainedSize);
}
};

View File

@ -1,22 +0,0 @@
//
// ASDisplayNodeLayout.mm
// Texture
//
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import <AsyncDisplayKit/ASDisplayNodeLayout.h>
BOOL ASDisplayNodeLayout::isValid(NSUInteger versionArg)
{
return layout != nil && version >= versionArg;
}
BOOL ASDisplayNodeLayout::isValid(ASSizeRange theConstrainedSize, CGSize theParentSize, NSUInteger versionArg)
{
return isValid(versionArg)
&& CGSizeEqualToSize(parentSize, theParentSize)
&& ASSizeRangeEqualToSizeRange(constrainedSize, theConstrainedSize);
}

View File

@ -15,8 +15,6 @@
#import <AsyncDisplayKit/ASDisplayNode.h>
#import <AsyncDisplayKit/ASLayoutSpec.h>
#import <memory>
NS_ASSUME_NONNULL_BEGIN
#pragma mark - ASLayoutElementTransition
@ -52,12 +50,12 @@ AS_SUBCLASSING_RESTRICTED
/**
* Previous layout to transition from
*/
@property (nonatomic, readonly) std::shared_ptr<ASDisplayNodeLayout> previousLayout;
@property (nonatomic, readonly) const ASDisplayNodeLayout &previousLayout NS_RETURNS_INNER_POINTER;
/**
* Pending layout to transition to
*/
@property (nonatomic, readonly) std::shared_ptr<ASDisplayNodeLayout> pendingLayout;
@property (nonatomic, readonly) const ASDisplayNodeLayout &pendingLayout NS_RETURNS_INNER_POINTER;
/**
* Returns if the layout transition needs to happen synchronously
@ -68,8 +66,8 @@ AS_SUBCLASSING_RESTRICTED
* Returns a newly initialized layout transition
*/
- (instancetype)initWithNode:(ASDisplayNode *)node
pendingLayout:(std::shared_ptr<ASDisplayNodeLayout>)pendingLayout
previousLayout:(std::shared_ptr<ASDisplayNodeLayout>)previousLayout NS_DESIGNATED_INITIALIZER;
pendingLayout:(const ASDisplayNodeLayout &)pendingLayout
previousLayout:(const ASDisplayNodeLayout &)previousLayout NS_DESIGNATED_INITIALIZER;
/**
* Insert and remove subnodes that were added or removed between the previousLayout and the pendingLayout

View File

@ -60,11 +60,13 @@ static inline BOOL ASLayoutCanTransitionAsynchronous(ASLayout *layout) {
NSArray<ASDisplayNode *> *_removedSubnodes;
std::vector<NSUInteger> _insertedSubnodePositions;
std::vector<std::pair<ASDisplayNode *, NSUInteger>> _subnodeMoves;
ASDisplayNodeLayout _pendingLayout;
ASDisplayNodeLayout _previousLayout;
}
- (instancetype)initWithNode:(ASDisplayNode *)node
pendingLayout:(std::shared_ptr<ASDisplayNodeLayout>)pendingLayout
previousLayout:(std::shared_ptr<ASDisplayNodeLayout>)previousLayout
pendingLayout:(const ASDisplayNodeLayout &)pendingLayout
previousLayout:(const ASDisplayNodeLayout &)previousLayout
{
self = [super init];
if (self) {
@ -80,7 +82,7 @@ static inline BOOL ASLayoutCanTransitionAsynchronous(ASLayout *layout) {
- (BOOL)isSynchronous
{
ASDN::MutexSharedLocker l(__instanceLock__);
return !ASLayoutCanTransitionAsynchronous(_pendingLayout->layout);
return !ASLayoutCanTransitionAsynchronous(_pendingLayout.layout);
}
- (void)commitTransition
@ -156,8 +158,8 @@ static inline BOOL ASLayoutCanTransitionAsynchronous(ASLayout *layout) {
// Create an activity even if no subnodes affected.
as_activity_create_for_scope("Calculate subnode operations");
ASLayout *previousLayout = _previousLayout->layout;
ASLayout *pendingLayout = _pendingLayout->layout;
ASLayout *previousLayout = _previousLayout.layout;
ASLayout *pendingLayout = _pendingLayout.layout;
if (previousLayout) {
#if AS_IG_LIST_KIT
@ -226,9 +228,9 @@ static inline BOOL ASLayoutCanTransitionAsynchronous(ASLayout *layout) {
{
ASDN::MutexSharedLocker l(__instanceLock__);
if ([key isEqualToString:ASTransitionContextFromLayoutKey]) {
return _previousLayout->layout;
return _previousLayout.layout;
} else if ([key isEqualToString:ASTransitionContextToLayoutKey]) {
return _pendingLayout->layout;
return _pendingLayout.layout;
} else {
return nil;
}
@ -238,9 +240,9 @@ static inline BOOL ASLayoutCanTransitionAsynchronous(ASLayout *layout) {
{
ASDN::MutexSharedLocker l(__instanceLock__);
if ([key isEqualToString:ASTransitionContextFromLayoutKey]) {
return _previousLayout->constrainedSize;
return _previousLayout.constrainedSize;
} else if ([key isEqualToString:ASTransitionContextToLayoutKey]) {
return _pendingLayout->constrainedSize;
return _pendingLayout.constrainedSize;
} else {
return ASSizeRangeMake(CGSizeZero, CGSizeZero);
}