mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
add schedule docs (#13174)
# Objective I'm reading through the schedule code, which is somewhat lacking documentation. I've been adding some docstrings to help me understand the code; I feel like some of them could be useful to also help others read this code. --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
This commit is contained in:
parent
6d25545c51
commit
fab83471b5
5 changed files with 60 additions and 12 deletions
|
@ -48,9 +48,15 @@ impl IntoSystemConfigs<()> for BoxedSystem<(), ()> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Stores configuration for a single generic node.
|
||||
/// Stores configuration for a single generic node (a system or a system set)
|
||||
///
|
||||
/// The configuration includes the node itself, scheduling metadata
|
||||
/// (hierarchy: in which sets is the node contained,
|
||||
/// dependencies: before/after which other nodes should this node run)
|
||||
/// and the run conditions associated with this node.
|
||||
pub struct NodeConfig<T> {
|
||||
pub(crate) node: T,
|
||||
/// Hierarchy and dependency metadata for this node
|
||||
pub(crate) graph_info: GraphInfo,
|
||||
pub(crate) conditions: Vec<BoxedCondition>,
|
||||
}
|
||||
|
@ -83,7 +89,7 @@ impl SystemConfigs {
|
|||
Self::NodeConfig(SystemConfig {
|
||||
node: system,
|
||||
graph_info: GraphInfo {
|
||||
sets,
|
||||
hierarchy: sets,
|
||||
..Default::default()
|
||||
},
|
||||
conditions: Vec::new(),
|
||||
|
@ -96,7 +102,7 @@ impl<T> NodeConfigs<T> {
|
|||
pub fn in_set_inner(&mut self, set: InternedSystemSet) {
|
||||
match self {
|
||||
Self::NodeConfig(config) => {
|
||||
config.graph_info.sets.push(set);
|
||||
config.graph_info.hierarchy.push(set);
|
||||
}
|
||||
Self::Configs { configs, .. } => {
|
||||
for config in configs {
|
||||
|
|
|
@ -62,16 +62,22 @@ pub struct SystemSchedule {
|
|||
/// Indexed by system node id.
|
||||
pub(super) system_conditions: Vec<Vec<BoxedCondition>>,
|
||||
/// Indexed by system node id.
|
||||
/// Number of systems that the system immediately depends on.
|
||||
pub(super) system_dependencies: Vec<usize>,
|
||||
/// Indexed by system node id.
|
||||
/// List of systems that immediately depend on the system.
|
||||
pub(super) system_dependents: Vec<Vec<usize>>,
|
||||
/// Indexed by system node id.
|
||||
/// List of sets containing the system that have conditions
|
||||
pub(super) sets_with_conditions_of_systems: Vec<FixedBitSet>,
|
||||
/// List of system set node ids.
|
||||
pub(super) set_ids: Vec<NodeId>,
|
||||
/// Indexed by system set node id.
|
||||
pub(super) set_conditions: Vec<Vec<BoxedCondition>>,
|
||||
/// Indexed by system set node id.
|
||||
/// List of systems that are in sets that have conditions.
|
||||
///
|
||||
/// If a set doesn't run because of its conditions, this is used to skip all systems in it.
|
||||
pub(super) systems_in_sets_with_conditions: Vec<FixedBitSet>,
|
||||
}
|
||||
|
||||
|
|
|
@ -73,9 +73,12 @@ pub(crate) enum Ambiguity {
|
|||
IgnoreAll,
|
||||
}
|
||||
|
||||
/// Metadata about how the node fits in the schedule graph
|
||||
#[derive(Clone, Default)]
|
||||
pub(crate) struct GraphInfo {
|
||||
pub(crate) sets: Vec<InternedSystemSet>,
|
||||
/// the sets that the node belongs to (hierarchy)
|
||||
pub(crate) hierarchy: Vec<InternedSystemSet>,
|
||||
/// the sets that the node depends on (must run before or after)
|
||||
pub(crate) dependencies: Vec<Dependency>,
|
||||
pub(crate) ambiguous_with: Ambiguity,
|
||||
}
|
||||
|
|
|
@ -532,15 +532,27 @@ impl SystemNode {
|
|||
}
|
||||
|
||||
/// Metadata for a [`Schedule`].
|
||||
///
|
||||
/// The order isn't optimized; calling `ScheduleGraph::build_schedule` will return a
|
||||
/// `SystemSchedule` where the order is optimized for execution.
|
||||
#[derive(Default)]
|
||||
pub struct ScheduleGraph {
|
||||
/// List of systems in the schedule
|
||||
systems: Vec<SystemNode>,
|
||||
/// List of conditions for each system, in the same order as `systems`
|
||||
system_conditions: Vec<Vec<BoxedCondition>>,
|
||||
/// List of system sets in the schedule
|
||||
system_sets: Vec<SystemSetNode>,
|
||||
/// List of conditions for each system set, in the same order as `system_sets`
|
||||
system_set_conditions: Vec<Vec<BoxedCondition>>,
|
||||
/// Map from system set to node id
|
||||
system_set_ids: HashMap<InternedSystemSet, NodeId>,
|
||||
/// Systems that have not been initialized yet; for system sets, we store the index of the first uninitialized condition
|
||||
/// (all the conditions after that index still need to be initialized)
|
||||
uninit: Vec<(NodeId, usize)>,
|
||||
/// Directed acyclic graph of the hierarchy (which systems/sets are children of which sets)
|
||||
hierarchy: Dag,
|
||||
/// Directed acyclic graph of the dependency (which systems/sets have to run before which other systems/sets)
|
||||
dependency: Dag,
|
||||
ambiguous_with: UnGraphMap<NodeId, ()>,
|
||||
ambiguous_with_all: HashSet<NodeId>,
|
||||
|
@ -548,6 +560,7 @@ pub struct ScheduleGraph {
|
|||
anonymous_sets: usize,
|
||||
changed: bool,
|
||||
settings: ScheduleBuildSettings,
|
||||
/// Dependency edges that will **not** automatically insert an instance of `apply_deferred` on the edge.
|
||||
no_sync_edges: BTreeSet<(NodeId, NodeId)>,
|
||||
auto_sync_node_ids: HashMap<u32, NodeId>,
|
||||
}
|
||||
|
@ -613,7 +626,7 @@ impl ScheduleGraph {
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
/// Returns an iterator over all systems in this schedule.
|
||||
/// Returns an iterator over all systems in this schedule, along with the conditions for each system.
|
||||
pub fn systems(
|
||||
&self,
|
||||
) -> impl Iterator<Item = (NodeId, &dyn System<In = (), Out = ()>, &[BoxedCondition])> {
|
||||
|
@ -627,7 +640,8 @@ impl ScheduleGraph {
|
|||
})
|
||||
}
|
||||
|
||||
/// Returns an iterator over all system sets in this schedule.
|
||||
/// Returns an iterator over all system sets in this schedule, along with the conditions for each
|
||||
/// system set.
|
||||
pub fn system_sets(&self) -> impl Iterator<Item = (NodeId, &dyn SystemSet, &[BoxedCondition])> {
|
||||
self.system_set_ids.iter().map(|(_, &node_id)| {
|
||||
let set_node = &self.system_sets[node_id.index()];
|
||||
|
@ -787,6 +801,7 @@ impl ScheduleGraph {
|
|||
}
|
||||
}
|
||||
|
||||
/// Add a [`SystemConfig`] to the graph, including its dependencies and conditions.
|
||||
fn add_system_inner(&mut self, config: SystemConfig) -> Result<NodeId, ScheduleBuildError> {
|
||||
let id = NodeId::System(self.systems.len());
|
||||
|
||||
|
@ -806,6 +821,7 @@ impl ScheduleGraph {
|
|||
self.process_configs(sets.into_configs(), false);
|
||||
}
|
||||
|
||||
/// Add a single `SystemSetConfig` to the graph, including its dependencies and conditions.
|
||||
fn configure_set_inner(&mut self, set: SystemSetConfig) -> Result<NodeId, ScheduleBuildError> {
|
||||
let SystemSetConfig {
|
||||
node: set,
|
||||
|
@ -837,7 +853,13 @@ impl ScheduleGraph {
|
|||
id
|
||||
}
|
||||
|
||||
fn check_set(&mut self, id: &NodeId, set: InternedSystemSet) -> Result<(), ScheduleBuildError> {
|
||||
/// Checks that a system set isn't included in itself.
|
||||
/// If not present, add the set to the graph.
|
||||
fn check_hierarchy_set(
|
||||
&mut self,
|
||||
id: &NodeId,
|
||||
set: InternedSystemSet,
|
||||
) -> Result<(), ScheduleBuildError> {
|
||||
match self.system_set_ids.get(&set) {
|
||||
Some(set_id) => {
|
||||
if id == set_id {
|
||||
|
@ -858,18 +880,22 @@ impl ScheduleGraph {
|
|||
AnonymousSet::new(id)
|
||||
}
|
||||
|
||||
fn check_sets(
|
||||
/// Check that no set is included in itself.
|
||||
/// Add all the sets from the [`GraphInfo`]'s hierarchy to the graph.
|
||||
fn check_hierarchy_sets(
|
||||
&mut self,
|
||||
id: &NodeId,
|
||||
graph_info: &GraphInfo,
|
||||
) -> Result<(), ScheduleBuildError> {
|
||||
for &set in &graph_info.sets {
|
||||
self.check_set(id, set)?;
|
||||
for &set in &graph_info.hierarchy {
|
||||
self.check_hierarchy_set(id, set)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Checks that no system set is dependent on itself.
|
||||
/// Add all the sets from the [`GraphInfo`]'s dependencies to the graph.
|
||||
fn check_edges(
|
||||
&mut self,
|
||||
id: &NodeId,
|
||||
|
@ -899,17 +925,18 @@ impl ScheduleGraph {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Update the internal graphs (hierarchy, dependency, ambiguity) by adding a single [`GraphInfo`]
|
||||
fn update_graphs(
|
||||
&mut self,
|
||||
id: NodeId,
|
||||
graph_info: GraphInfo,
|
||||
) -> Result<(), ScheduleBuildError> {
|
||||
self.check_sets(&id, &graph_info)?;
|
||||
self.check_hierarchy_sets(&id, &graph_info)?;
|
||||
self.check_edges(&id, &graph_info)?;
|
||||
self.changed = true;
|
||||
|
||||
let GraphInfo {
|
||||
sets,
|
||||
hierarchy: sets,
|
||||
dependencies,
|
||||
ambiguous_with,
|
||||
..
|
||||
|
@ -1137,6 +1164,9 @@ impl ScheduleGraph {
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
/// Return a map from system set `NodeId` to a list of system `NodeId`s that are included in the set.
|
||||
/// Also return a map from system set `NodeId` to a `FixedBitSet` of system `NodeId`s that are included in the set,
|
||||
/// where the bitset order is the same as `self.systems`
|
||||
fn map_sets_to_systems(
|
||||
&self,
|
||||
hierarchy_topsort: &[NodeId],
|
||||
|
@ -1397,6 +1427,7 @@ impl ScheduleGraph {
|
|||
}
|
||||
}
|
||||
|
||||
/// Updates the `SystemSchedule` from the `ScheduleGraph`.
|
||||
fn update_schedule(
|
||||
&mut self,
|
||||
schedule: &mut SystemSchedule,
|
||||
|
|
|
@ -105,6 +105,8 @@ pub trait System: Send + Sync + 'static {
|
|||
fn check_change_tick(&mut self, change_tick: Tick);
|
||||
|
||||
/// Returns the system's default [system sets](crate::schedule::SystemSet).
|
||||
///
|
||||
/// Each system will create a default system set that contains the system.
|
||||
fn default_system_sets(&self) -> Vec<InternedSystemSet> {
|
||||
Vec::new()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue