Skip to content

Commit

Permalink
[ASDisplayNode+Layout] Ensure a pending layout is applied once (#695)
Browse files Browse the repository at this point in the history
Before:
  - Even if a pending layout was applied before, it'll be unnecessarily applied again in next layout passes and cause `-calculatedLayoutDidChange` being called multiple times.

After:
  - If a pending layout was applied, the calculated layout will not be ignored but reused, if possible, in next layout passes.

Test plan: testSetNeedsLayoutAndNormalLayoutPass in #424.
  • Loading branch information
nguyenhuy committed Dec 1, 2017
1 parent d8cda8d commit b01fac3
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- [API CHANGES] `ASPerformMainThreadDeallocation` and `ASPerformBackgroundDeallocation` functions take `id *` instead of `id` and they're now more reliable. Also, in Swift, `ASDeallocQueue.sharedDeallocationQueue() -> ASDeallocQueue.sharedDeallocationQueue`. [Adlai Holler](https://github.com/Adlai-Holler) [#651](https://github.com/TextureGroup/Texture/pull/651)
- [Collection/Table] Added direct support for mapping section indexes between data spaces. [Adlai Holler](https://github.com/Adlai-Holler) [#651](https://github.com/TextureGroup/Texture/pull/660)
- [ASCornerLayoutSpec] New layout spec class for declarative corner element layout. [#657](https://github.com/TextureGroup/Texture/pull/657) [huangkun](https://github.com/huang-kun)
- [Layout] Fix an issue that causes a pending layout to be applied multiple times. [Huy Nguyen](https://github.com/nguyenhuy) [#695](https://github.com/TextureGroup/Texture/pull/695)

## 2.6
- [Xcode 9] Updated to require Xcode 9 (to fix warnings) [Garrett Moon](https://github.com/garrettmoon)
Expand Down
18 changes: 10 additions & 8 deletions Source/ASDisplayNode+Layout.mm
Original file line number Diff line number Diff line change
Expand Up @@ -300,14 +300,16 @@ - (void)_u_measureNodeWithBoundsIfNecessary:(CGRect)bounds

CGSize boundsSizeForLayout = ASCeilSizeValues(bounds.size);

// Prefer _pendingDisplayNodeLayout over _calculatedDisplayNodeLayout (if exists, it's the newest)
// If there is no _pending, check if _calculated is valid to reuse (avoiding recalculation below).
if (_pendingDisplayNodeLayout == nullptr || _pendingDisplayNodeLayout->version < _layoutVersion) {
if (_calculatedDisplayNodeLayout->version >= _layoutVersion
&& (_calculatedDisplayNodeLayout->requestedLayoutFromAbove == YES
|| CGSizeEqualToSize(_calculatedDisplayNodeLayout->layout.size, boundsSizeForLayout))) {
return;
}
// 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 = (_pendingDisplayNodeLayout != nullptr
&& _pendingDisplayNodeLayout->version >= _layoutVersion
&& _pendingDisplayNodeLayout->version > _calculatedDisplayNodeLayout->version); // _pending is not yet applied
BOOL calculatedLayoutIsReusable = (_calculatedDisplayNodeLayout->version >= _layoutVersion
&& (_calculatedDisplayNodeLayout->requestedLayoutFromAbove
|| CGSizeEqualToSize(_calculatedDisplayNodeLayout->layout.size, boundsSizeForLayout)));
if (!pendingLayoutIsPreferred && calculatedLayoutIsReusable) {
return;
}

as_activity_create_for_scope("Update node layout for current bounds");
Expand Down

0 comments on commit b01fac3

Please sign in to comment.