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