bevy_ecs/schedule/
pass.rs

1use alloc::{boxed::Box, vec::Vec};
2use core::any::{Any, TypeId};
3
4use super::{DiGraph, NodeId, ScheduleBuildError, ScheduleGraph};
5use crate::{
6    schedule::{SystemKey, SystemSetKey},
7    world::World,
8};
9use bevy_utils::TypeIdMap;
10use core::fmt::Debug;
11
12/// A pass for modular modification of the dependency graph.
13pub trait ScheduleBuildPass: Send + Sync + Debug + 'static {
14    /// Custom options for dependencies between sets or systems.
15    type EdgeOptions: 'static;
16
17    /// Called when a dependency between sets or systems was explicitly added to the graph.
18    fn add_dependency(&mut self, from: NodeId, to: NodeId, options: Option<&Self::EdgeOptions>);
19
20    /// Called while flattening the dependency graph. For each `set`, this method is called
21    /// with the `systems` associated with the set as well as an immutable reference to the current graph.
22    /// Instead of modifying the graph directly, this method should return an iterator of edges to add to the graph.
23    fn collapse_set(
24        &mut self,
25        set: SystemSetKey,
26        systems: &[SystemKey],
27        dependency_flattening: &DiGraph<NodeId>,
28    ) -> impl Iterator<Item = (NodeId, NodeId)>;
29
30    /// The implementation will be able to modify the `ScheduleGraph` here.
31    fn build(
32        &mut self,
33        world: &mut World,
34        graph: &mut ScheduleGraph,
35        dependency_flattened: &mut DiGraph<SystemKey>,
36    ) -> Result<(), ScheduleBuildError>;
37}
38
39/// Object safe version of [`ScheduleBuildPass`].
40pub(super) trait ScheduleBuildPassObj: Send + Sync + Debug {
41    fn build(
42        &mut self,
43        world: &mut World,
44        graph: &mut ScheduleGraph,
45        dependency_flattened: &mut DiGraph<SystemKey>,
46    ) -> Result<(), ScheduleBuildError>;
47
48    fn collapse_set(
49        &mut self,
50        set: SystemSetKey,
51        systems: &[SystemKey],
52        dependency_flattening: &DiGraph<NodeId>,
53        dependencies_to_add: &mut Vec<(NodeId, NodeId)>,
54    );
55    fn add_dependency(&mut self, from: NodeId, to: NodeId, all_options: &TypeIdMap<Box<dyn Any>>);
56}
57
58impl<T: ScheduleBuildPass> ScheduleBuildPassObj for T {
59    fn build(
60        &mut self,
61        world: &mut World,
62        graph: &mut ScheduleGraph,
63        dependency_flattened: &mut DiGraph<SystemKey>,
64    ) -> Result<(), ScheduleBuildError> {
65        self.build(world, graph, dependency_flattened)
66    }
67    fn collapse_set(
68        &mut self,
69        set: SystemSetKey,
70        systems: &[SystemKey],
71        dependency_flattening: &DiGraph<NodeId>,
72        dependencies_to_add: &mut Vec<(NodeId, NodeId)>,
73    ) {
74        let iter = self.collapse_set(set, systems, dependency_flattening);
75        dependencies_to_add.extend(iter);
76    }
77    fn add_dependency(&mut self, from: NodeId, to: NodeId, all_options: &TypeIdMap<Box<dyn Any>>) {
78        let option = all_options
79            .get(&TypeId::of::<T::EdgeOptions>())
80            .and_then(|x| x.downcast_ref::<T::EdgeOptions>());
81        self.add_dependency(from, to, option);
82    }
83}