From e27e54774af2b9e3ae564f0bd01b41afac1b9f99 Mon Sep 17 00:00:00 2001 From: Zeenobit Date: Tue, 20 Aug 2024 20:25:40 -0400 Subject: [PATCH 1/4] Add `include_system_set` This is to allow the user to filter system sets in the output. Fixes #26 --- src/schedule_graph/mod.rs | 56 +++++++++++++++++++++++++++------- src/schedule_graph/settings.rs | 4 ++- 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/src/schedule_graph/mod.rs b/src/schedule_graph/mod.rs index 29de489..61a4994 100644 --- a/src/schedule_graph/mod.rs +++ b/src/schedule_graph/mod.rs @@ -477,19 +477,26 @@ impl ScheduleGraphContext<'_> { } fn included_systems_sets(graph: &ScheduleGraph, settings: &Settings) -> HashSet { + let system_set_filter = settings + .include_system_set + .as_deref() + .unwrap_or(&include_all_system_sets); + let Some(include_system) = &settings.include_system else { - return graph - .systems() - .map(|(id, ..)| id) - .chain(graph.system_sets().map(|(id, ..)| id)) - .collect(); + let systems = graph.systems().map(|(id, ..)| id); + let system_sets = graph + .system_sets() + .filter_map(|(id, set, _)| system_set_filter(set).then_some(id)); + return systems.chain(system_sets).collect(); }; let hierarchy = graph.hierarchy().graph(); let root_sets = hierarchy.nodes().filter(|&node| { + let system_set = graph.set_at(node); node.is_set() - && graph.set_at(node).system_type().is_none() + && system_set.system_type().is_none() + && system_set_filter(system_set) && hierarchy .neighbors_directed(node, Direction::Incoming) .next() @@ -502,16 +509,25 @@ fn included_systems_sets(graph: &ScheduleGraph, settings: &Settings) -> HashSet< .map(|(id, ..)| id) .collect(); + fn include_all_system_sets(_: &dyn SystemSet) -> bool { + true + } + fn include_ancestors( id: NodeId, + graph: &ScheduleGraph, hierarchy: &DiGraphMap, + filter: &impl Fn(&dyn SystemSet) -> bool, included_systems_sets: &mut HashSet, ) { let parents = hierarchy.neighbors_directed(id, Direction::Incoming); for parent in parents { - included_systems_sets.insert(parent); - include_ancestors(parent, hierarchy, included_systems_sets); + let system_set = graph.set_at(parent); + if filter(system_set) { + included_systems_sets.insert(parent); + include_ancestors(parent, graph, hierarchy, filter, included_systems_sets); + } } } @@ -519,7 +535,13 @@ fn included_systems_sets(graph: &ScheduleGraph, settings: &Settings) -> HashSet< included_systems_sets.extend(root_sets); for &id in &systems_of_interest { - include_ancestors(id, hierarchy, &mut included_systems_sets); + include_ancestors( + id, + graph, + hierarchy, + &system_set_filter, + &mut included_systems_sets, + ); } if settings.ambiguity_enable { @@ -540,12 +562,24 @@ fn included_systems_sets(graph: &ScheduleGraph, settings: &Settings) -> HashSet< for (from, to, ()) in graph.dependency().graph().all_edges() { if systems_of_interest.contains(&from) { included_systems_sets.insert(to); - include_ancestors(to, hierarchy, &mut included_systems_sets); + include_ancestors( + to, + graph, + hierarchy, + &system_set_filter, + &mut included_systems_sets, + ); } if systems_of_interest.contains(&to) { included_systems_sets.insert(from); - include_ancestors(to, hierarchy, &mut included_systems_sets); + include_ancestors( + to, + graph, + hierarchy, + &system_set_filter, + &mut included_systems_sets, + ); } } diff --git a/src/schedule_graph/settings.rs b/src/schedule_graph/settings.rs index c45a840..981d88b 100644 --- a/src/schedule_graph/settings.rs +++ b/src/schedule_graph/settings.rs @@ -183,6 +183,7 @@ pub struct Settings { /// When set to `Some`, will only include systems matching the predicate, and their ancestor sets pub include_system: Option>, + pub include_system_set: Option>, pub collapse_single_system_sets: bool, pub ambiguity_enable: bool, @@ -301,6 +302,7 @@ impl Default for Settings { system_style: Box::new(system_to_style), include_system: None, + include_system_set: None, collapse_single_system_sets: false, ambiguity_enable: true, @@ -324,4 +326,4 @@ pub fn full_system_name(system: &dyn System) -> String { pub fn default_system_set_name(system_set: &dyn SystemSet) -> String { format!("{:?}", system_set) -} \ No newline at end of file +} From 380dc3a7e1a294f5aaa745484a9fd4e91fad0dbc Mon Sep 17 00:00:00 2001 From: Zeenobit Date: Tue, 20 Aug 2024 20:34:25 -0400 Subject: [PATCH 2/4] Fix bad system set query --- src/schedule_graph/mod.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/schedule_graph/mod.rs b/src/schedule_graph/mod.rs index 61a4994..078c262 100644 --- a/src/schedule_graph/mod.rs +++ b/src/schedule_graph/mod.rs @@ -493,9 +493,11 @@ fn included_systems_sets(graph: &ScheduleGraph, settings: &Settings) -> HashSet< let hierarchy = graph.hierarchy().graph(); let root_sets = hierarchy.nodes().filter(|&node| { + if !node.is_set() { + return false; + } let system_set = graph.set_at(node); - node.is_set() - && system_set.system_type().is_none() + system_set.system_type().is_none() && system_set_filter(system_set) && hierarchy .neighbors_directed(node, Direction::Incoming) From 09dceb2e93b446c7cdf3a19387d280177f8f57f3 Mon Sep 17 00:00:00 2001 From: Zeenobit Date: Tue, 20 Aug 2024 20:45:17 -0400 Subject: [PATCH 3/4] Add methods for adding system and system set filters --- src/schedule_graph/settings.rs | 42 ++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/src/schedule_graph/settings.rs b/src/schedule_graph/settings.rs index 981d88b..9e6a857 100644 --- a/src/schedule_graph/settings.rs +++ b/src/schedule_graph/settings.rs @@ -197,29 +197,37 @@ pub struct Settings { impl Settings { /// Set the `include_system` predicate to match only systems for which their names matches `filter` - pub fn filter_name(mut self, filter: impl Fn(&str) -> bool + 'static) -> Self { - self.include_system = Some(Box::new(move |system| { - let name = system.name(); - filter(&name) - })); - self + pub fn filter_name(self, filter: impl Fn(&str) -> bool + 'static) -> Self { + self.with_system_filter(move |system| filter(&system.name())) } /// Set the `include_system` predicate to only match systems from the specified crate - pub fn filter_in_crate(mut self, crate_: &str) -> Self { + pub fn filter_in_crate(self, crate_: &str) -> Self { let crate_ = crate_.to_owned(); - self.include_system = Some(Box::new(move |system| { - let name = system.name(); - name.starts_with(&crate_) - })); - self + self.with_system_filter(move |system| system.name().starts_with(&crate_)) } /// Set the `include_system` predicate to only match systems from the specified crates - pub fn filter_in_crates(mut self, crates: &[&str]) -> Self { + pub fn filter_in_crates(self, crates: &[&str]) -> Self { let crates: Vec<_> = crates.iter().map(|&s| s.to_owned()).collect(); - self.include_system = Some(Box::new(move |system| { - let name = system.name(); - crates.iter().any(|crate_| name.starts_with(crate_)) - })); + self.with_system_filter(move |system| { + crates + .iter() + .any(|crate_| system.name().starts_with(crate_)) + }) + } + + pub fn with_system_filter( + mut self, + filter: impl Fn(&dyn System) -> bool + 'static, + ) -> Self { + self.include_system = Some(Box::new(filter)); + self + } + + pub fn with_system_set_filter( + mut self, + filter: impl Fn(&dyn SystemSet) -> bool + 'static, + ) -> Self { + self.include_system_set = Some(Box::new(filter)); self } From 4b4a4769b73cbab68a774bda1883005030f72d0f Mon Sep 17 00:00:00 2001 From: Zeenobit Date: Tue, 20 Aug 2024 20:45:25 -0400 Subject: [PATCH 4/4] Create print_schedule_graph_advanced_filters.rs --- .../print_schedule_graph_advanced_filters.rs | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 examples/print_schedule_graph_advanced_filters.rs diff --git a/examples/print_schedule_graph_advanced_filters.rs b/examples/print_schedule_graph_advanced_filters.rs new file mode 100644 index 0000000..dc5e473 --- /dev/null +++ b/examples/print_schedule_graph_advanced_filters.rs @@ -0,0 +1,38 @@ +use bevy::log::LogPlugin; +use bevy::prelude::*; +use bevy_app::DynEq; +use bevy_mod_debugdump::schedule_graph::Settings; + +fn special_system_a() {} +fn special_system_b() {} +fn regular_system_c() {} + +#[derive(Debug, Clone, Hash, PartialEq, Eq, SystemSet)] +enum ExampleSystemSet { + Special, + Regular, +} + +fn main() { + let mut app = App::new(); + app.add_plugins(DefaultPlugins.build().disable::()) + .configure_sets( + Update, + (ExampleSystemSet::Special, ExampleSystemSet::Regular), + ) + .add_systems( + Update, + (special_system_a, special_system_b, regular_system_c).chain(), + ); + + let settings = Settings::default() + .filter_in_crate("print_schedule_graph_advanced_filters") + .with_system_filter(|system| system.name().contains("special")) + .with_system_set_filter(|system_set| { + system_set + .as_dyn_eq() + .dyn_eq(ExampleSystemSet::Special.as_dyn_eq()) + }); + let dot = bevy_mod_debugdump::schedule_graph_dot(&mut app, Update, &settings); + println!("{dot}"); +}