pub struct SceneTree {
pub nodes: Vec<SceneNode>,
}Expand description
The scene tree itself. nodes[0] is always the synthetic root.
Fields§
§nodes: Vec<SceneNode>Implementations§
Source§impl SceneTree
impl SceneTree
Sourcepub fn root(&self) -> SceneNodeId
pub fn root(&self) -> SceneNodeId
Index of the synthetic root.
Sourcepub fn push(
&mut self,
parent: SceneNodeId,
kind: NodeKind,
name: impl Into<String>,
labels: impl Into<String>,
) -> SceneNodeId
pub fn push( &mut self, parent: SceneNodeId, kind: NodeKind, name: impl Into<String>, labels: impl Into<String>, ) -> SceneNodeId
Append a node under parent and return its id.
Idempotent by (parent, kind, name): if a child with
the same kind and name already exists under parent, its
id is returned and no new node is created. Per SRD 18b
§“Single Walker Contract” point 1, the same walker runs
once at depth=Phase to populate the tree (so subsequent
resume_plan / declare_scene_tree_phases /
pre_map_pending_uses reads see a populated tree) and
once at the configured execution depth to run cycles —
re-encountering nodes pushed by the first walk must be a
no-op, not a duplicate insertion.
Phase nodes are auto-assigned a 1-based sequence number
in insertion order (see SceneNode::seq); since the
walker pushes phases in DFS-of-the-scenario-tree order,
the resulting numbers match the order in which the
runtime executes them.
Sourcepub fn set_yaml_path(&mut self, id: SceneNodeId, path: Vec<PathSegment>)
pub fn set_yaml_path(&mut self, id: SceneNodeId, path: Vec<PathSegment>)
Set the structural YAML path for a node. Called by the pre-map walker as it descends through scenarios / for_each / for_combinations / do-loops, so each Scope and Phase node carries the full chain from the workload root down to its declaration site. Used by the checkpoint resume planner to identify phases across runs (per SRD-44 §“Phase identity”).
Sourcepub fn total_phases(&self) -> usize
pub fn total_phases(&self) -> usize
Total number of Phase entries in the tree. Equal to the
largest assigned seq value once the tree is fully built.
Sourcepub fn apply_phase_filter(
&mut self,
pattern: Option<&PhasePattern>,
) -> PhaseFilterStats
pub fn apply_phase_filter( &mut self, pattern: Option<&PhasePattern>, ) -> PhaseFilterStats
Apply a phase-name filter to the tree. Phase nodes whose
name does not match pattern are marked active=false;
Scope nodes inherit active=false iff every phase
descendant under them was filtered out. The synthetic
root is always active. When pattern is None, every
node stays active.
Inactive subtrees stay in the tree so the executor’s planning walk still constructs the scope-init kernels the active branches inherit from — only execution is skipped at the leaves.
Sourcepub fn is_phase_active(&self, id: SceneNodeId) -> bool
pub fn is_phase_active(&self, id: SceneNodeId) -> bool
Whether the phase node at id should be executed under
the active phase filter. Convenience for the executor’s
per-phase dispatch site.
Source§impl SceneTree
impl SceneTree
Sourcepub fn set_phase_op_names(&mut self, id: SceneNodeId, names: Vec<String>)
pub fn set_phase_op_names(&mut self, id: SceneNodeId, names: Vec<String>)
Set the op-template names for a phase node. Called at pre-map time once the workload model has been resolved so the TUI can drill into a phase and show its stanza elements.
Sourcepub fn set_own_names(&mut self, id: SceneNodeId, names: Vec<String>)
pub fn set_own_names(&mut self, id: SceneNodeId, names: Vec<String>)
Set the scope-local “own names” — names defined at this
scope vs. inherited via cascade. See
SceneNode::own_names. Called at pre-map time from
the scope kernel’s program.own_output_names().
Sourcepub fn dfs(&self) -> DfsIter<'_> ⓘ
pub fn dfs(&self) -> DfsIter<'_> ⓘ
DFS walk from the root, yielding every node in display
order. The synthetic root itself is included as the first
item; renderers filter on kind == Root to skip it.
Sourcepub fn dfs_phases(&self) -> impl Iterator<Item = &SceneNode>
pub fn dfs_phases(&self) -> impl Iterator<Item = &SceneNode>
DFS yielding only Phase-kind nodes, in the same order
the flat pre-map vector used to produce.
Sourcepub fn find_phase(
&self,
name: &str,
_labels: &str,
want: Option<&PhaseStatus>,
) -> Option<SceneNodeId>
pub fn find_phase( &self, name: &str, _labels: &str, want: Option<&PhaseStatus>, ) -> Option<SceneNodeId>
First phase node matching (name, status). Used by
observer callbacks to bind a phase_starting event to the
next pending phase, then phase_completed to its running
counterpart.
Matching is structural-order, not label-based: pre-map
(executor::pre_map_recursive) and runtime
(executor::execute_node → dispatch_comprehension) walk
the scenario tree in the same DFS order, so the i-th
runtime invocation of phase name always corresponds to
the i-th pre-mapped phase node by name. That lets us
avoid forcing pre-map’s coordinate-path label string to
match runtime’s format_scope_coordinate_path output
byte-for-byte — historically a fragile coupling that
silently degraded to the “push under root” fallback when
any workload-param vs. iter-var distinction shifted (e.g.
optimize_for_values vs. optimize_for).
labels was the legacy match key; preserved on the
signature so callers don’t have to change, but only used
now if the order-based lookup misses (which shouldn’t
happen — surface as a warning if it does).
Sourcepub fn set_phase_running_at(&mut self, id: SceneNodeId, op_count: usize)
pub fn set_phase_running_at(&mut self, id: SceneNodeId, op_count: usize)
Mark the phase node at id as running. No-op if id is out
of range (defensive against a stale/foreign id).
Sourcepub fn remove_node(&mut self, id: SceneNodeId)
pub fn remove_node(&mut self, id: SceneNodeId)
Mark the phase node at id as completed with duration_secs.
Detach id from its parent’s child list, removing it from every
tree walk (display folds, replay tree). The node’s allocation and
id remain valid — ids are stable — it is simply unreachable.
Used by the skipped_phases=elide|prune display modes to drop
fully-gated-off phases from the completed tree.
pub fn set_phase_completed_at(&mut self, id: SceneNodeId, duration_secs: f64)
Sourcepub fn set_phase_failed_at(&mut self, id: SceneNodeId, error: &str)
pub fn set_phase_failed_at(&mut self, id: SceneNodeId, error: &str)
Mark the phase node at id as failed with error.
Sourcepub fn set_phase_running(&mut self, name: &str, labels: &str, op_count: usize)
pub fn set_phase_running(&mut self, name: &str, labels: &str, op_count: usize)
Mark a phase as running. By-name convenience delegating to
Self::set_phase_running_at via Self::find_phase —
used by tests and non-concurrent by-name call sites. The
production lifecycle path threads the dispatch-time id
(P1c) and calls the _at form directly.
Sourcepub fn set_phase_completed(
&mut self,
name: &str,
labels: &str,
duration_secs: f64,
)
pub fn set_phase_completed( &mut self, name: &str, labels: &str, duration_secs: f64, )
Mark a phase as completed. By-name convenience (see
Self::set_phase_running).
Sourcepub fn set_phase_failed(&mut self, name: &str, labels: &str, error: &str)
pub fn set_phase_failed(&mut self, name: &str, labels: &str, error: &str)
Mark a phase as failed. By-name convenience matching the first phase with the given (name, labels) regardless of status — failure can arrive while the phase is still pending in the rare case of pre-flight resolution errors.
Sourcepub fn set_phase_outcome(
&mut self,
name: &str,
labels: &str,
outcome: PhaseOutcome,
)
pub fn set_phase_outcome( &mut self, name: &str, labels: &str, outcome: PhaseOutcome, )
SRD-76 — install the structured terminal outcome on
a phase node. Mirrors the legacy status /
duration_secs fields so existing renderers see
consistent state (the legacy fields stay
load-bearing until SRD-76 Push 4 lands the new
readouts that read outcome directly).
Matches the first phase with the given
(name, labels) regardless of current status — the
outcome can arrive on a Pending phase if pre-flight
failed before the running transition, on a Running
phase at normal completion, and idempotency in the
rare double-install case (debug-asserted off in
release builds).
Sourcepub fn set_phase_outcome_at(&mut self, id: SceneNodeId, outcome: PhaseOutcome)
pub fn set_phase_outcome_at(&mut self, id: SceneNodeId, outcome: PhaseOutcome)
SRD-100 P1c — install the structured outcome on the phase
node at id directly (dispatch-time-keyed, race-safe under
concurrent same-name phases). The by-name
Self::set_phase_outcome delegates here after a
Self::find_phase lookup.
Sourcepub fn session_disposition(&self) -> SessionDisposition
pub fn session_disposition(&self) -> SessionDisposition
SRD-76 — project every phase’s outcome onto the
session-wide pass/fail axis. Walks every phase node
that has been populated with a PhaseOutcome;
returns [SessionDisposition::Failure] when any
phase’s outcome carries Validity::Failed,
[SessionDisposition::Success] otherwise. Phases
that never ran (still Pending at session end)
contribute nothing — interrupted-mid-run is not a
failure per SRD-76 §“SessionDisposition”.
Sourcepub fn phase_outcome_present_at(&self, id: SceneNodeId) -> bool
pub fn phase_outcome_present_at(&self, id: SceneNodeId) -> bool
SRD-76 — iterate every phase node’s structured
outcome in DFS order. Used by the (Push 3) sqlite
persister and the (Push 5) replay rehydrator. Skips
phases that never reached terminal state.
True when the phase node already carries a recorded
crate::phase_outcome::PhaseOutcome. The run_phase
chokepoint uses this to detect an early config-resolution
failure (an Outcome::failed() returned before the failure
epilogue ran) so it can route it through the visible
surfaces exactly once.
pub fn iter_phase_outcomes(&self) -> impl Iterator<Item = &PhaseOutcome>
Sourcepub fn aggregate_status(&self, id: SceneNodeId) -> PhaseStatus
pub fn aggregate_status(&self, id: SceneNodeId) -> PhaseStatus
Effective status for a Scope (or Root) node, computed
by walking descendants:
- any descendant
Failed→ Failed - any descendant
Running→ Running - all descendant phases
Completed→ Completed - else → Pending
Sourcepub fn phase_count(&self) -> usize
pub fn phase_count(&self) -> usize
Total count of Phase-kind nodes in the tree.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for SceneTree
impl<'de> Deserialize<'de> for SceneTree
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl Freeze for SceneTree
impl RefUnwindSafe for SceneTree
impl Send for SceneTree
impl Sync for SceneTree
impl Unpin for SceneTree
impl UnsafeUnpin for SceneTree
impl UnwindSafe for SceneTree
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more