Avoid filtering sprites redundantly on every layer and allocating intermediate vectors to group by atlas.
Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>
Previously, when splicing an edit that deleted all transforms, we would
leave the `FoldMap` empty, thus violating a bunch of downstream
invariants and e.g. causing the `BufferRows` iterator to not return any
buffer row.
This commit ensures we always have at least one transform (an isomorphic
one, specifically) and adds additional test coverage for the
`FoldMap::buffer_rows` method by adding it to the randomized tests.
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.