I don't actually think it was correct to allow the future to borrow a mutable app reference. I went back to passing a wrapper around the refcell to async tests. They'll be a bit more annoying to write but also totally safe.
I used the word "dirty" because it felt more expressive than "modified" to me, but not married to it. Tagging Max because we did a lot of this thinking together.
Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>
This guarantees that the spawning entity will be present and simplifies
the logic for obtaining the entity. Now we can forward the results of spawned futures and streams in the same way regardless of whether what spawned them was a model or a view.
Doing things in parallel has a constant factor associated with it (e.g.,
spawning threads and coordinating them) that dwarves its benefits on a
code path like this where things take < 2-3ms when done sequentially.
Avoid filtering sprites redundantly on every layer and allocating intermediate vectors to group by atlas.
Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>
Now the Element trait is designed to be wrapped in a Lifecycle enum that gets placed inside an ElementBox. This allows the framework to store data on behalf of the Element implementation, such as sizes, bounds, and also implementation-specific LayoutState and PaintState types. This makes it easier to reason about which data is available in each Element method.
Also, eliminate the background spawning methods. We can spawn futures
on the executor and then spawn those on the app if we need to wait for
the result of running one.