collectMediaSources function
Gathers every declared MediaSource from scenes before the frame loop —
a pure structural walk over the constructor data, with no mounting and no
async.
Pre-resolution must finish before the first frame is pumped, so media
cannot be collected by mounting and registering: this walks the same tree
the user wrote (each scene's Background and its declared children, and the
children of the common layout widgets) and reads each MediaCarrier's
mediaSource straight off its constructor. Image, Clip, and
Background.image/.video are carriers; everything else is transparent.
This collector lives in the composition layer because it walks Scene
trees: composition legitimately depends on media and core, so the
dependency edge points one way (composition → media), not the other. The
result is a Set, so the same declaration across scenes resolves once (the
cache deduplicates by value equality). The render harness hands this set to
MediaResolver.preResolveAll before frame 0.
When a generative resolver is given (after its generateAll ran), a
GenerativeMedia of a visual kind folds in as its produced file-backed
MediaSource, so generated images and videos pre-resolve through the same
pass as hand-written Image/Clip.
Implementation
Set<MediaSource> collectMediaSources(List<Scene> scenes, {GenerativeResolver? generative}) {
final sources = <MediaSource>{};
walkSceneTree(scenes, (widget) {
if (widget is MediaCarrier) {
final source = (widget as MediaCarrier).mediaSource;
if (source != null) sources.add(source);
} else if (generative != null && widget is GenerativeMedia && widget.source.isVisual) {
sources.add(generative.mediaFor(widget.source));
}
});
return sources;
}