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

Commit 5a96985

Browse files
committed
Merge pull request #1104 from facebook/ASTextNodeInvalidationOptimization
[ASLayout, ASTextNode] Create -calculatedLayoutDidChange and use it in text node.
2 parents 2a63868 + 2713bdd commit 5a96985

File tree

3 files changed

+41
-14
lines changed

3 files changed

+41
-14
lines changed

AsyncDisplayKit/ASDisplayNode+Subclasses.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@ NS_ASSUME_NONNULL_BEGIN
9191
*/
9292
- (void)layoutDidFinish;
9393

94+
/**
95+
* @abstract Called on a background thread if !isNodeLoaded - called on the main thread if isNodeLoaded.
96+
*
97+
* @discussion When the .calculatedLayout property is set to a new ASLayout (directly from -calculateLayoutThatFits: or
98+
* calculated via use of -layoutSpecThatFits:), subclasses may inspect it here.
99+
*/
100+
- (void)calculatedLayoutDidChange;
94101

95102
/** @name Layout calculation */
96103

AsyncDisplayKit/ASDisplayNode.mm

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,7 @@ - (ASLayout *)__measureWithSizeRange:(ASSizeRange)constrainedSize
594594
_layout = [self calculateLayoutThatFits:constrainedSize];
595595
_constrainedSize = constrainedSize;
596596
_flags.isMeasured = YES;
597+
[self calculatedLayoutDidChange];
597598
}
598599

599600
ASDisplayNodeAssertTrue(_layout.layoutableObject == self);
@@ -615,6 +616,10 @@ - (ASLayout *)__measureWithSizeRange:(ASSizeRange)constrainedSize
615616
return _layout;
616617
}
617618

619+
- (void)calculatedLayoutDidChange
620+
{
621+
}
622+
618623
- (BOOL)displaysAsynchronously
619624
{
620625
ASDN::MutexLocker l(_propertyLock);

AsyncDisplayKit/ASTextNode.mm

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -185,19 +185,6 @@ - (NSString *)description
185185

186186
#pragma mark - ASDisplayNode
187187

188-
- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
189-
{
190-
ASDisplayNodeAssert(constrainedSize.width >= 0, @"Constrained width for text (%f) is too narrow", constrainedSize.width);
191-
ASDisplayNodeAssert(constrainedSize.height >= 0, @"Constrained height for text (%f) is too short", constrainedSize.height);
192-
193-
_constrainedSize = constrainedSize;
194-
[self _invalidateRenderer];
195-
ASDisplayNodeRespectThreadAffinityOfNode(self, ^{
196-
[self setNeedsDisplay];
197-
});
198-
return [[self _renderer] size];
199-
}
200-
201188
// FIXME: Re-evaluate if it is still the right decision to clear the renderer at this stage.
202189
// This code was written before TextKit and when 512MB devices were still the overwhelming majority.
203190
- (void)displayDidFinish
@@ -303,6 +290,8 @@ - (void)_invalidateRendererIfNeededForBoundsSize:(CGSize)boundsSize
303290
}
304291
}
305292

293+
#pragma mark - Layout and Sizing
294+
306295
- (BOOL)_needInvalidateRendererForBoundsSize:(CGSize)boundsSize
307296
{
308297
if (!_renderer) {
@@ -323,7 +312,7 @@ - (BOOL)_needInvalidateRendererForBoundsSize:(CGSize)boundsSize
323312
// as this would essentially serve to set its constrainedSize to be its calculatedSize (unnecessary).
324313
ASLayout *layout = self.calculatedLayout;
325314
if (layout != nil && CGSizeEqualToSize(boundsSize, layout.size)) {
326-
if (!CGSizeEqualToSize(boundsSize, rendererConstrainedSize)) {
315+
if (boundsSize.width != rendererConstrainedSize.width) {
327316
// Don't bother changing _constrainedSize, as ASDisplayNode's -measure: method would have a cache miss
328317
// and ask us to recalculate layout if it were called with the same calculatedSize that got us to this point!
329318
_renderer.constrainedSize = boundsSize;
@@ -335,6 +324,32 @@ - (BOOL)_needInvalidateRendererForBoundsSize:(CGSize)boundsSize
335324
}
336325
}
337326

327+
- (void)calculatedLayoutDidChange
328+
{
329+
ASLayout *layout = self.calculatedLayout;
330+
if (layout != nil) {
331+
_renderer.constrainedSize = layout.size;
332+
}
333+
}
334+
335+
- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
336+
{
337+
ASDisplayNodeAssert(constrainedSize.width >= 0, @"Constrained width for text (%f) is too narrow", constrainedSize.width);
338+
ASDisplayNodeAssert(constrainedSize.height >= 0, @"Constrained height for text (%f) is too short", constrainedSize.height);
339+
340+
_constrainedSize = constrainedSize;
341+
342+
// Instead of invalidating the renderer, in case this is a new call with a different constrained size,
343+
// just update the size of the NSTextContainer that is owned by the renderer's internal context object.
344+
[self _renderer].constrainedSize = _constrainedSize;
345+
346+
ASDisplayNodeRespectThreadAffinityOfNode(self, ^{
347+
[self setNeedsDisplay];
348+
});
349+
350+
return [[self _renderer] size];
351+
}
352+
338353
#pragma mark - Modifying User Text
339354

340355
- (void)setAttributedString:(NSAttributedString *)attributedString

0 commit comments

Comments
 (0)