pub fn keep_frame_loop_awake_for_assets(
waiting: Query<'_, '_, (), (With<ImageSource>, Without<LoadedImage>, Without<LoadedSvg>, Without<ImageLoadFailed>)>,
active: Option<Res<'_, AnimationsActive>>,
)Expand description
Keeps the frame loop scheduled while an element is still waiting on the content it named.
An event-driven loop parks the moment a tick leaves no work behind, and a
parked loop runs no system. An <image> that enters the tree late in a
tick - a hot reload respawning the tree, a page swap mounting a shared
template - is spawned after spawn_pending_decodes has already run, so
without a scheduled follow-up tick it sits unserviced and the window
keeps showing an empty box until some unrelated event wakes the app. A
decode already in flight needs the same thing for a different reason:
nothing wakes the loop when a worker finishes, so the result waits in the
channel until a tick runs drain_completed_decodes to read it.
Both states are one state on the element: an ImageSource with no
verdict on it yet. Keying the claim there rather than on the server’s
in-flight map is what bounds it. A despawn takes the claim with it, so
the page swap that drops an element mid-decode parks the app instead of
pinning it at the frame rate, and every way out of the waiting state
retires the claim: the next tick looks an unlooked-up source up, and
every job answers with a payload or a failure, a panicking loader
included (see [worker_loop]). The flag therefore reaches false on its
own once the last element has its content, which is what
lumen_core::tick::work_pending promises the loops that read it.
Runs late in the tick so it sees the tree as the reconcilers left it.