Skip to content
This repository was archived by the owner on Feb 2, 2023. It is now read-only.

Commit f809d4a

Browse files
author
Levi McCallum
committed
Let ASLayout determine if a node should measure
1 parent c809609 commit f809d4a

4 files changed

Lines changed: 26 additions & 15 deletions

File tree

AsyncDisplayKit/ASDisplayNode.mm

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -650,10 +650,15 @@ - (BOOL)shouldMeasureWithSizeRange:(ASSizeRange)constrainedSize
650650
}
651651
}
652652

653-
// only calculate the size if
654-
// - we haven't already
655-
// - the constrained size range is different
656-
return (!_flags.isMeasured || !ASSizeRangeEqualToSizeRange(constrainedSize, _layout.constrainedSizeRange));
653+
// Only generate a new layout if:
654+
// - The current layout is dirty
655+
// - The passed constrained size is different than the layout's constrained size
656+
return ([self _dirtyLayout] || !ASSizeRangeEqualToSizeRange(constrainedSize, _layout.constrainedSizeRange));
657+
}
658+
659+
- (BOOL)_dirtyLayout
660+
{
661+
return _layout == nil || _layout.isDirty;
657662
}
658663

659664
#pragma mark - Layout Transition
@@ -1019,7 +1024,7 @@ - (void)__setNeedsLayout
10191024
ASDisplayNodeAssertThreadAffinity(self);
10201025
ASDN::MutexLocker l(_propertyLock);
10211026

1022-
if (!_flags.isMeasured) {
1027+
if ([self _dirtyLayout]) {
10231028
return;
10241029
}
10251030

@@ -1095,7 +1100,7 @@ - (void)measureNodeWithBoundsIfNecessary:(CGRect)bounds
10951100
// Normally measure will be called before layout occurs. If this doesn't happen, nothing is going to call it at all.
10961101
// We simply call measureWithSizeRange: using a size range equal to whatever bounds were provided to that element or
10971102
// try to measure the node with the largest size as possible
1098-
if (self.supernode == nil && !self.supportsRangeManagedInterfaceState && !_flags.isMeasured) {
1103+
if (self.supernode == nil && !self.supportsRangeManagedInterfaceState && [self _dirtyLayout] == NO) {
10991104
if (CGRectEqualToRect(bounds, CGRectZero)) {
11001105
LOG(@"Warning: No size given for node before node was trying to layout itself: %@. Please provide a frame for the node.", self);
11011106
} else {
@@ -1108,7 +1113,7 @@ - (void)layout
11081113
{
11091114
ASDisplayNodeAssertMainThread();
11101115

1111-
if (!_flags.isMeasured) {
1116+
if ([self _dirtyLayout]) {
11121117
return;
11131118
}
11141119

@@ -2058,8 +2063,10 @@ - (UIImage *)placeholderImage
20582063
- (void)invalidateCalculatedLayout
20592064
{
20602065
ASDN::MutexLocker l(_propertyLock);
2061-
// This will cause -measureWithSizeRange: to actually compute the size instead of returning the previously cached size
2062-
_flags.isMeasured = NO;
2066+
2067+
// This will cause the next call to -measureWithSizeRange: to actually compute a new layout
2068+
// instead of returning the current layout
2069+
_layout.dirty = YES;
20632070
}
20642071

20652072
- (void)__didLoad
@@ -2395,17 +2402,14 @@ - (void)applyPendingLayoutContext
23952402
}
23962403
}
23972404

2398-
- (void)applyLayout:(ASLayout *)layout
2399-
layoutContext:(ASLayoutTransition *)layoutContext
2405+
- (void)applyLayout:(ASLayout *)layout layoutContext:(ASLayoutTransition *)layoutContext
24002406
{
24012407
ASDN::MutexLocker l(_propertyLock);
24022408
_layout = layout;
24032409

24042410
ASDisplayNodeAssertTrue(layout.layoutableObject == self);
24052411
ASDisplayNodeAssertTrue(layout.size.width >= 0.0);
24062412
ASDisplayNodeAssertTrue(layout.size.height >= 0.0);
2407-
2408-
_flags.isMeasured = YES;
24092413

24102414
if (self.usesImplicitHierarchyManagement && layoutContext != nil) {
24112415
[layoutContext applySubnodeInsertions];

AsyncDisplayKit/Layout/ASLayout.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ extern CGPoint const CGPointNull;
2121

2222
extern BOOL CGPointIsNull(CGPoint point);
2323

24-
/** Represents a computed immutable layout tree. */
24+
/**
25+
* A node in the layout tree that represents the size and position of the object that created it (ASLayoutable).
26+
*/
2527
@interface ASLayout : NSObject
2628

2729
/**
@@ -56,6 +58,11 @@ extern BOOL CGPointIsNull(CGPoint point);
5658
*/
5759
@property (nonatomic, readonly) NSArray<ASLayout *> *immediateSublayouts;
5860

61+
/**
62+
* Mark the layout dirty for future regeneration.
63+
*/
64+
@property (nonatomic, getter=isDirty) BOOL dirty;
65+
5966
/**
6067
* A boolean describing if the current layout has been flattened.
6168
*/

AsyncDisplayKit/Layout/ASLayout.mm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ + (instancetype)layoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject
5050
}
5151
l->_constrainedSizeRange = sizeRange;
5252
l->_size = size;
53+
l->_dirty = NO;
5354

5455
if (CGPointIsNull(position) == NO) {
5556
l->_position = CGPointMake(ASCeilPixelValue(position.x), ASCeilPixelValue(position.y));

AsyncDisplayKit/Private/ASDisplayNodeInternal.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayNodesScheduledBefo
8282
unsigned implementsDrawParameters:1;
8383

8484
// internal state
85-
unsigned isMeasured:1;
8685
unsigned isEnteringHierarchy:1;
8786
unsigned isExitingHierarchy:1;
8887
unsigned isInHierarchy:1;

0 commit comments

Comments
 (0)