Skip to content

Sketch: An Axum/Bevy inspired component model for Xilem #1070

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

Closed
wants to merge 4 commits into from

Conversation

DJMcNab
Copy link
Member

@DJMcNab DJMcNab commented Jun 10, 2025

This pull request is the result of an experiment I started during travel back from RustWeek, thinking about the shortcomings of Xilem's lifecycle/threading model (e.g. #1032, the hacks in #921).

Warning

This work is extremely incomplete.
I'd love to push this work forward, but I don't have anywhere near all the answers for how this will work.
This PR is largely to have something to point towards when discussing this idea.

The current model in Xilem has two distinct phases, the app logic and view "rebuild"/reconciliation. In the theoretical version of the model, the app logic is where all "user code" happens, and produces a pure view tree. However, in practise, the app logic cannot have local state, and so work is deferred to "rebuild" in order to access local state; see e.g. memoize. However, rebuild time doesn't have access to the app state.

Essentially, the idea in this work is to have a formalisation of the app logic into explicit "components", which both have access to the app state, and to their own local state. Components know how to create a view, which is the true lightweight description of the state of a widget tree.
The true advancement of this model, is that any function which returns a component is itself a component. That child component "works" by running the function, then running the component method on the function's return value. The user generally "actually writes" these components.
Importantly, these component functions can have parameters other than the app state, including e.g. "local" variables, as seen in Bevy.
(This isn't implemented yet, but it's worth noting that I have been in the weeds of the equivalent in Bevy, and understand how it works)


Note that in theory, we could go even further here, and also give the components access to the tree element itself; this would mix app logic and rebuild time directly. This might be the more natural expansion of the Xilem model. I haven't reasoned carefully about how that would look like.
This is likely the direction I'd like this exploration to go in next.

Other notes:

  • The model proposed here interacts reasonably nicely with hot reloading; the app logic can be hot reloaded, and only the final views need to be sent to the "main thread".

github-merge-queue bot pushed a commit that referenced this pull request Jun 16, 2025
…rdown}` (#1079)

This change is both a major departure from the prior state, and the most
natural thing in the world.

My proposing this change has come from thinking related to #1070, for
what build/rebuild/message actually represent, , how distinct important
the phases of the lifecycle actually are (they aren't at all), and the
reason that the Xilem model actually works. The core insight behind
Xilem is that if you can prove to the compiler that you only access a
piece of state in one place at once, the compiler will let you access it
exclusively. Everything else is following that to its logical
conclusion; this just continues that train of thought.

Current state of this PR: 
- This PR is ready to be merged
- This PR makes a lot of changes, so if we want this, merging quickly
would be helpful
- The only thing which is broken is the `adapt` view, which currently
unconditionally panicks, to avoid making behaviour changes in this PR
- The follow-up changes which make use of this (in task, worker,
virtual_scroll, memoize, the new use_state, run_once, etc.) have not
been done, to make this PR plausible to review.

Tradeoffs:
- In theory, this makes multi-threaded rebuild harder, but note that
this was already probably hard
- This is rejecting the premise that you don't need component local
state; this is something I treated as an experiment, but which has
probably held us back significantly.

There's some more work to be done here (in particular, I really want to
experiment with exclusive references in the app state, especially around
`use_state`, for event handling).

---------

Co-authored-by: Philipp Mildenberger <[email protected]>
@DJMcNab
Copy link
Member Author

DJMcNab commented Jul 18, 2025

This isn't a meaningful PR anymore. I've been continuing to explore some of the ideas I started thinking about here.
See e.g. #1079 and #1142

@DJMcNab DJMcNab closed this Jul 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant