bevy_ecs/schedule/graph/
mod.rs

1use alloc::{boxed::Box, vec::Vec};
2use core::{
3    any::{Any, TypeId},
4    fmt::Debug,
5};
6
7use bevy_utils::TypeIdMap;
8
9use crate::schedule::InternedSystemSet;
10
11mod dag;
12mod graph_map;
13mod tarjan_scc;
14
15pub use dag::*;
16pub use graph_map::{DiGraph, DiGraphToposortError, Direction, GraphNodeId, UnGraph};
17
18/// Specifies what kind of edge should be added to the dependency graph.
19#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)]
20pub(crate) enum DependencyKind {
21    /// A node that should be preceded.
22    Before,
23    /// A node that should be succeeded.
24    After,
25}
26
27/// An edge to be added to the dependency graph.
28pub(crate) struct Dependency {
29    pub(crate) kind: DependencyKind,
30    pub(crate) set: InternedSystemSet,
31    pub(crate) options: TypeIdMap<Box<dyn Any>>,
32}
33
34impl Dependency {
35    pub fn new(kind: DependencyKind, set: InternedSystemSet) -> Self {
36        Self {
37            kind,
38            set,
39            options: Default::default(),
40        }
41    }
42    pub fn add_config<T: 'static>(mut self, option: T) -> Self {
43        self.options.insert(TypeId::of::<T>(), Box::new(option));
44        self
45    }
46}
47
48/// Configures ambiguity detection for a single system.
49#[derive(Clone, Debug, Default)]
50pub(crate) enum Ambiguity {
51    #[default]
52    Check,
53    /// Ignore warnings with systems in any of these system sets. May contain duplicates.
54    IgnoreWithSet(Vec<InternedSystemSet>),
55    /// Ignore all warnings.
56    IgnoreAll,
57}
58
59/// Metadata about how the node fits in the schedule graph
60#[derive(Default)]
61pub struct GraphInfo {
62    /// the sets that the node belongs to (hierarchy)
63    pub(crate) hierarchy: Vec<InternedSystemSet>,
64    /// the sets that the node depends on (must run before or after)
65    pub(crate) dependencies: Vec<Dependency>,
66    pub(crate) ambiguous_with: Ambiguity,
67}
68
69/// Converts 2D row-major pair of indices into a 1D array index.
70pub(crate) fn index(row: usize, col: usize, num_cols: usize) -> usize {
71    debug_assert!(col < num_cols);
72    (row * num_cols) + col
73}
74
75/// Converts a 1D array index into a 2D row-major pair of indices.
76pub(crate) fn row_col(index: usize, num_cols: usize) -> (usize, usize) {
77    (index / num_cols, index % num_cols)
78}