MCPcopy Create free account
hub / github.com/Bloom-Engine/engine / schedule

Function schedule

native/shared/src/renderer/graph.rs:166–245  ·  view source on GitHub ↗
(nodes: &[PassNode<'a, Ctx>])

Source from the content-addressed store, hash-verified

164// =====================================================================
165
166fn schedule<'a, Ctx>(nodes: &[PassNode<'a, Ctx>]) -> Result<Vec<usize>, GraphError> {
167 let n = nodes.len();
168 if n == 0 { return Ok(Vec::new()); }
169
170 // Name → index lookup for `after` / `before` hint resolution.
171 let mut name_to_idx: HashMap<&'static str, usize> = HashMap::new();
172 for (i, node) in nodes.iter().enumerate() {
173 name_to_idx.insert(node.name, i);
174 }
175
176 // Build the predecessor set for each node.
177 // Edge A → B means A must run before B.
178 let mut preds: Vec<HashSet<usize>> = vec![HashSet::new(); n];
179
180 // 1) Data-dependency edges: if B reads what A writes, A → B.
181 // Approximate "writes" as "any write matches any read" — the
182 // enum comparison treats PassOutput::HdrColor as matching
183 // PassInput::SceneColor via the `matches_write` helper below.
184 for b in 0..n {
185 for read in &nodes[b].reads {
186 for a in 0..n {
187 if a == b { continue; }
188 for write in &nodes[a].writes {
189 if input_matches_write(read, write) {
190 preds[b].insert(a);
191 }
192 }
193 }
194 }
195 }
196 // 2) Explicit `after` hints: node B.after = [A] → A → B.
197 for (b, node) in nodes.iter().enumerate() {
198 for name in &node.after {
199 let a = name_to_idx.get(name).ok_or_else(|| GraphError::UnknownNode {
200 node: node.name.to_string(),
201 referenced: name.to_string(),
202 })?;
203 if *a != b { preds[b].insert(*a); }
204 }
205 }
206 // 3) Explicit `before` hints: node A.before = [B] → A → B.
207 for (a, node) in nodes.iter().enumerate() {
208 for name in &node.before {
209 let b = name_to_idx.get(name).ok_or_else(|| GraphError::UnknownNode {
210 node: node.name.to_string(),
211 referenced: name.to_string(),
212 })?;
213 if *b != a { preds[*b].insert(a); }
214 }
215 }
216
217 // Kahn's algorithm: repeatedly pick a node whose `preds` is empty
218 // (or whose unsatisfied preds are already in the output), add it,
219 // strip it from every other preds set. Break ties by declaration
220 // order to keep the schedule deterministic.
221 let mut in_degree: Vec<usize> = preds.iter().map(|p| p.len()).collect();
222 let mut out: Vec<usize> = Vec::with_capacity(n);
223 loop {

Callers 2

scheduleMethod · 0.85
executeMethod · 0.85

Calls 4

input_matches_writeFunction · 0.85
iterMethod · 0.80
getMethod · 0.45
pushMethod · 0.45

Tested by

no test coverage detected