Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor LayoutTree, create PartialLayoutTree, and add examples of custom trees #564

Merged
merged 31 commits into from
Oct 22, 2023

Conversation

nicoburns
Copy link
Collaborator

@nicoburns nicoburns commented Oct 15, 2023

Objective

Enable algorithm-agnostic code such as caching and rounding logic to work with custom trees. And make such trees easier to implement.

Context

Changes made:

  • Simplify function signature of compute_leaf_layout function: instead of taking a context and a closure that accepts the context as a parameter, it now just takes a closure and expects the context to have already been closed over. This doesn't affect the high level API.
  • Split LayoutTree into PartialLayoutTree and LayoutTree: PartialLayoutTree traits. The idea here is that PartialLayoutTree can be implemented by consumers of Taffy that only have access to one node and it's direct children at once. This gives access to Taffy's layout algorithms. LayoutTree can be implemented in addition to PartialLayoutTree if you have access to the full tree. This gives access to rounding and the print_tree function.
  • Add cache_mut method to PartialLayoutTree, and create new public compute_cached_layout function that handles caching logic.
  • Combine measure_child_size and perform_child_layout methods back into a single compute_child_layout with a SizingMode parameter (not entirely sure about this, but it means users of Taffy only have to implement one method).
  • Move layout algorithm "dispatch" code (match on display style and call appropriate algorithm) into the implementation of PartialLayoutTree.compute_child_layout for the Taffy struct). This now uses the above compute_cached_layout function.
  • Rename a bunch of (Partial)LayoutTree methods and parameters.
  • Make round_layout and compute_layout functions public
  • Make TaffyView private (this is an implementation detail of Taffy)
  • Make CacheEntry private (the public API is now Cache)
  • Add examples of custom trees: one backed by a Vec, one where each node directly owns it's children.

Feedback wanted

  • API design review
  • Some of these algorithm-agnostic features require you to be able to recurse down a tree (other than measuring children). Specifically, rounding and hidden layout (display: none) both do. Hidden layout could be fixed by adding a new method to the trait. Or perhaps a new variant to the RunMode enum. This has now been implemented

Old notes

I'm wondering if perhaps we ought to split the LayoutTree into two traits (perhaps PartialLayoutTree and LayoutTree? Where LayoutTree: PartialLayoutTree, and LayoutTree comes with an additional requirement that you can recurse down the tree just using IDs. This has also been implemented

  • It is possible to implement LayoutTree for "each node directly owns a Vec of children" trees as demonstrated in the example, but it's not very nice: it involves using unsafe to stuff a pointer into the NodeId. I think this could be fixed by making the NodeId type generic and adding a lifetime to it, but it still won't always be possible if for example the children are trait objects of a trait that doesn't have methods to access the relevant properties or it's own children (which a Widget trait for a not-all-in-on-Taffy UI system likely wouldn't).

This hasn't ended up as neat as I had hoped. I might split out some of the less controversial changes from this PR into separate PRs. I'm much happier with this after splitting out the LayoutTree into PartialLayoutTree and (Full)LayoutTree. This split gives us some type safety around which Taffy methods require infinite tree traversal and which ones only need to access direct children. So while users of Taffy will still need to read the docs carefully when implementing PartialLayoutTree/LayoutTree, which methods they can use will be enforced by the type system assuming that implementation is done correctly.

Removing the (Full)LayoutTree requirement from perform_hidden_layout, along with splitting rounding into a separate compute_layout_with_rounding method, also allows it to be removed from the top-level compute_layout method). So it's now only rounding and debug printing that require FullLayoutTree.

@nicoburns nicoburns added documentation Improvements or additions to documentation usability Make the library more comfortable to use breaking-change A change that breaks our public interface controversial This work requires a heightened standard of review due to implementation or design complexity labels Oct 15, 2023
@nicoburns nicoburns force-pushed the reinstate-layoutree-cache-mut branch 2 times, most recently from 66aff50 to fd61962 Compare October 18, 2023 23:07
@nicoburns nicoburns force-pushed the reinstate-layoutree-cache-mut branch from fd61962 to 7fc640d Compare October 18, 2023 23:17
@nicoburns nicoburns force-pushed the reinstate-layoutree-cache-mut branch from dbb73f3 to a0034cb Compare October 19, 2023 00:47
@nicoburns nicoburns changed the title WIP: Further LayoutTree tweaks + examples of custom trees Refactor LayoutTree + add examples of custom trees Oct 21, 2023
@nicoburns nicoburns marked this pull request as ready for review October 21, 2023 22:27
@nicoburns nicoburns changed the title Refactor LayoutTree + add examples of custom trees Refactor LayoutTree, create PartialLayoutTree, and add examples of custom trees Oct 22, 2023
@nicoburns nicoburns merged commit d4374b9 into DioxusLabs:main Oct 22, 2023
17 checks passed
@nicoburns
Copy link
Collaborator Author

Release notes to follow once an API design for Taffy 0.4 has been settled on.

@nicoburns nicoburns added this to the 0.4 milestone Oct 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking-change A change that breaks our public interface controversial This work requires a heightened standard of review due to implementation or design complexity documentation Improvements or additions to documentation usability Make the library more comfortable to use
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant