use alloc::{boxed::Box, vec::Vec};
use core::{
any::{Any, TypeId},
fmt::Debug,
};
use bevy_utils::TypeIdMap;
use crate::schedule::InternedSystemSet;
mod dag;
mod graph_map;
mod tarjan_scc;
pub use dag::*;
pub use graph_map::{DiGraph, DiGraphToposortError, Direction, GraphNodeId, UnGraph};
#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)]
pub(crate) enum DependencyKind {
Before,
After,
}
pub(crate) struct Dependency {
pub(crate) kind: DependencyKind,
pub(crate) set: InternedSystemSet,
pub(crate) options: TypeIdMap<Box<dyn Any>>,
}
impl Dependency {
pub fn new(kind: DependencyKind, set: InternedSystemSet) -> Self {
Self {
kind,
set,
options: Default::default(),
}
}
pub fn add_config<T: 'static>(mut self, option: T) -> Self {
self.options.insert(TypeId::of::<T>(), Box::new(option));
self
}
}
#[derive(Clone, Debug, Default)]
pub(crate) enum Ambiguity {
#[default]
Check,
IgnoreWithSet(Vec<InternedSystemSet>),
IgnoreAll,
}
#[derive(Default)]
pub struct GraphInfo {
pub(crate) hierarchy: Vec<InternedSystemSet>,
pub(crate) dependencies: Vec<Dependency>,
pub(crate) ambiguous_with: Ambiguity,
}
pub(crate) fn index(row: usize, col: usize, num_cols: usize) -> usize {
debug_assert!(col < num_cols);
(row * num_cols) + col
}
pub(crate) fn row_col(index: usize, num_cols: usize) -> (usize, usize) {
(index / num_cols, index % num_cols)
}