* Minor refactors in ASCollectionView and its private cell classes
- `_ASCollectionReusableView` and `_ASCollectionViewCell` no longer expose getters for their collection element and cell node properties. This is to make sure that clients can only obtain elements from the visible map which is always the source of truth.
- Since the map can return `nil` for an element request, it's much safer to check and avoid adding/removing a nil pointer to an `NSArray`.
- Since we use a special way to check whether an object of kind of `_ASCollectionViewCell` or `_ASCollectionReusableView`, based on the assumption that these classes are subclass restricted, I added cast-or-return macros in the header files, closer to where the restrictions are declared.
* Add ASDynamicCastStrict
* Add element and node properties back to _ASCollectionReusableView and _ASCollectionViewCell
* Assert unexpected nil elements
* Always mark an element visible even if it is backed by an UIKit / non-_ASCollection* view
* Fix typo
* Remove unnecessary changes
* Dump mistakes
* Update CHANGELOG
* Can't track visibility of elements backed by non-_AS views
This was originally added for ASCollectionNode and ASTableNode preloading to work
as intended when nested inside of another ASRangeController-powered node. Indeed,
it is still necessary to trigger layout on these UIKit-backed components in order
for their own ASRangeControllers to start preparing content within them.
However, unlike the comment suggests, it is *not* necessary to do this for image
nodes. ASNetworkImageNode has only one .URL, and does not use the .bounds or
.calculatedLayout at all during loading. Even the ASMultiplexImageNode does not
use the .bounds, and the ASMapNode uses .calculatedLayout instead of .bounds.
This change has important performance benefits. In particular, it avoids
layouts that would occur on the main thread, often including text sizing,
and also can result in redundant layout passes (even during a layout pass that
triggers a node to enter the preload range, it may force its own layout early).
It would be great to test this change with Pinterest to confirm its safety, but
based on a full audit of the framework codebase, the only possibility that I
see for a regression is if app implementations of -didEnterPreloadState make
direct use of .bounds instead of .calculatedLayout (which is easy to fix).
* Fix a crash in table view caused by executing an empty change set during layoutSubviews
- Previously, when a change set is empty, `ASDataController` forwards the change set to its delegate right away, without dispatching to its editing queue and then back to main.
- This behaviour can potentially cause bad internal states in UITableView which trigger a crash reported in https://github.com/TextureGroup/Texture/issues/83.
- Fix by still reusing the existing pending map, because the data source's state has not changed, but go through the editing queue and main queue tunnel.
* Update CHANGELOG
I believe this check is supposed to be here. Unit tests pass with it in place.
Without it, calling layoutThatFits: (as ASDataController does) and then calling
it again later (as ASCollectionNode does when answering the sizeForItem: call)
will recompute the layout, potentially on main.
This seems to have more of an impact / benefit for Yoga layouts, but I don't think
its benefit is exclusive to them.
* [ASTextNode2] Provide compiler flag to enable ASTextNode2 for all usages.
The runtime switch is helpful, but is too slow to be shipped in a large
production application where startup time is carefully optimized.
Although this doesn't pass text-related snapshot tests when enabled, it
does allow apps to rely on built-in components like ASButtonNode using
the same text stack as when they are manually creating ASTextNode2
instances.
A simpler approach would be to use a #define ASTextNode ASTextNode2,
but this would create unusual keyword highlighting in code referencing
ASTextNode. However, because it would be less invasive and this is
not on by default, we could do that instead if preferred.
* Update AsyncDisplayKit.h
* [ASTextNode2] Improve naming and documentation of ASTEXTNODE_EXPERIMENT_GLOBAL_ENABLE
* [ASTextNode2] CHANGELOG.md for #410.
* [ASTextNode2] Add initial implementation for link handling.
This is a fairly basic first step to achieving feature parity between ASTextNode2
and ASTextNode. It does not yet do the 9-box detection of links, and there is
other code from ASTextNode that could be shared to improve this.
However, in the interest of getting a shippable implementation running as soon
as possible, I'm hoping to quickly refine this. Then we can continue improving
it based on the original ASTextNode with the benefit of testing UI against it.
* [ASTextNode2] Refine implementation of link handling.
This ensures that measure funcs are not set for container / empty spacer
nodes, because Yoga has more internal capabilities than layoutThatFits:
knows about.
Avoid need for the main layout pass to directly call setup for measure
funcs, by making it an implicit part of .yogaLayoutInProgress =.
Tear down the measure func after the layout pass to avoid retain cycle.
* Implement tests for the layout flattening process
* Refactor the flattening algorithm
- Remove flattened flag
- No more self check
- Stop traversing a layout tree branch when hits a displaynode node.
- Reuse as many existing ASLayout objects as possible
* Update changelog
* Ceil position values before comparing
* Explain why sublayout elements must be retained
This has one important benefit: fixing the stretching behavior of spacer nodes.
In addition, it should help efficiency of Yoga and certainly minimize calls
to layoutThatFits:.
Next up for Yoga is a mostly-red diff, deleting the non-Contiguous code branches.
* [Yoga] Rewrite YOGA_TREE_CONTIGUOUS mode with support for mixing with ASLayoutSpec.
After experimentation with the ASYogaLayoutSpec (or non-contiguous) approach to
integrating Yoga, test results and feedback from the authors of Yoga have shown
that this approach can't be made completely correct,
There are issues with some of the features required to represent Web-style
flexbox; in particular: padding, margins, and border handling have varience.
This diff is a first step towards a truly correct and elegant implementation of
Yoga integration with Texture. In addition to reducing the footprint of
the integration, which is an explicit goal of work at this stage, these changes
already support improved behavior - including mixing between ASLayoutSpecs
even as subnodes of Yoga layout-driven nodes, in addition to above them. Yoga
may be used for any set of nodes.
Because Yoga usage is limited at this time, it's safe to merge this diff and
further improvements will be refinements in this direction.
* [ASDKgram] Add Yoga layout implementation for PhotoCellNode.
* [Yoga] Final fixes for the upgraded implementation of the Contiguous layout mode.
* [Yoga] Add CHANGELOG.md entry and fix for Yoga rounding to screen scale.
* [Yoga] Minor cleanup to remove old comments and generalize utility methods.
* [ASTraitCollection] Convert ASPrimitiveTraitCollection from lock to atomic.
This resolves a deadlock case: https://github.com/TextureGroup/Texture/issues/353
* [ASTraitCollection] Use assignment operator instead of .store() for C++ atomic.
* Add support for skipping reload if node decides it is compatible with new view model also
* Sort things right
* Put the order back
* No need for redundant expectation
* Fix license header
* Fix comment
* [Performance] Convert ASLayoutElementSize to atomic
* [ASLayoutElementStyle] Put locks around setter methods.
* Also add lock to setSize: internal method.
* Small changes required by the layout debugger
- `ASDisplayNode` can be told to not flatten its layout immediately but later on. The unflattened layout is also stored in a separate property. It's needed for inspecting not only display nodes but also layout specs used to compute a layout tree.
- `ASLayout` can be told to always retain its sublayout elements. This is needed especially for layout specs since they are usually not retained after an ASLayout was computed.
* Update CHANGELOG
* Address comments
It is rare that this code has any effect, but I've discovered a case in which it occurs.
This task tracks moving this code to a DEBUG-only assertion: https://github.com/TextureGroup/Texture/issues/335
* [Yoga] Implement ASYogaLayoutSpec, an experimental alternative to full-tree integration.
This approach allows us to avoid any ASDisplayNode.mm integration points.
However, it is not yet proven to be possible to achieve correctness with this approach.
The entry point (to start calculating), and the measurement function inputs, lack
the full expressiveness of ASSizeRange; we need to make sure that workarounds like
using style.minSize are successful in simulating the behavior of a full Yoga tree.
* [Yoga] Fix file comments, move towards <ASLayoutElement> support.
* [Yoga] Important fix for simplified, non-contiguous Yoga integration.
* [Yoga] Complete implementation of manual memory management (__bridge_transfer, YGNodeFree)