re_viewport/
system_execution.rs1use std::collections::BTreeMap;
2
3use ahash::HashMap;
4use nohash_hasher::IntMap;
5use rayon::prelude::*;
6
7use re_viewer_context::{
8 PerSystemDataResults, SystemExecutionOutput, ViewContextCollection,
9 ViewContextSystemStaticExecResult, ViewId, ViewQuery, ViewState, ViewStates,
10 ViewSystemIdentifier, ViewerContext, VisualizerCollection,
11};
12
13use crate::view_highlights::highlights_for_view;
14use re_viewport_blueprint::ViewBlueprint;
15
16fn run_view_systems(
17 ctx: &ViewerContext<'_>,
18 view: &ViewBlueprint,
19 query: &ViewQuery<'_>,
20 view_state: &dyn ViewState,
21 context_system_static_exec_results: &IntMap<
22 ViewSystemIdentifier,
23 ViewContextSystemStaticExecResult,
24 >,
25 context_systems: &mut ViewContextCollection,
26 view_systems: &mut VisualizerCollection,
27) -> Vec<re_renderer::QueueableDrawData> {
28 re_tracing::profile_function!(view.class_identifier().as_str());
29
30 let view_ctx = view.bundle_context_with_state(ctx, view_state);
31
32 {
33 re_tracing::profile_wait!("ViewContextSystem::execute");
34 context_systems
35 .systems
36 .par_iter_mut()
37 .for_each(|(name, system)| {
38 re_tracing::profile_scope!("ViewContextSystem::execute", name.as_str());
39 let static_execution_result = context_system_static_exec_results
40 .get(name)
41 .expect("Context system execution result didn't occur");
42 system.execute(&view_ctx, query, static_execution_result);
43 });
44 };
45
46 re_tracing::profile_wait!("VisualizerSystem::execute");
47 view_systems
48 .systems
49 .par_iter_mut()
50 .map(|(name, part)| {
51 re_tracing::profile_scope!("VisualizerSystem::execute", name.as_str());
52 match part.execute(&view_ctx, query, context_systems) {
53 Ok(part_draw_data) => part_draw_data,
54 Err(err) => {
55 re_log::error_once!("Error executing visualizer {name:?}: {err}");
56 Vec::new()
57 }
58 }
59 })
60 .flatten()
61 .collect()
62}
63
64pub fn execute_systems_for_view<'a>(
65 ctx: &'a ViewerContext<'_>,
66 view: &'a ViewBlueprint,
67 view_state: &dyn ViewState,
68 context_system_static_exec_results: &IntMap<
69 ViewSystemIdentifier,
70 ViewContextSystemStaticExecResult,
71 >,
72) -> (ViewQuery<'a>, SystemExecutionOutput) {
73 re_tracing::profile_function!(view.class_identifier().as_str());
74
75 let highlights = highlights_for_view(ctx, view.id);
76
77 let query_result = ctx.lookup_query_result(view.id);
78
79 let mut per_visualizer_data_results = PerSystemDataResults::default();
80 {
81 re_tracing::profile_scope!("per_system_data_results");
82
83 query_result.tree.visit(&mut |node| {
84 for system in &node.data_result.visualizers {
85 per_visualizer_data_results
86 .entry(*system)
87 .or_default()
88 .push(&node.data_result);
89 }
90 true
91 });
92 }
93
94 let current_query = ctx.time_ctrl.current_query();
95 let query = re_viewer_context::ViewQuery {
96 view_id: view.id,
97 space_origin: &view.space_origin,
98 per_visualizer_data_results,
99 timeline: current_query.timeline(),
100 latest_at: current_query.at(),
101 highlights,
102 };
103
104 let mut context_systems = ctx
105 .view_class_registry()
106 .new_context_collection(view.class_identifier());
107 let mut view_systems = ctx
108 .view_class_registry()
109 .new_visualizer_collection(view.class_identifier());
110
111 let draw_data = run_view_systems(
112 ctx,
113 view,
114 &query,
115 view_state,
116 context_system_static_exec_results,
117 &mut context_systems,
118 &mut view_systems,
119 );
120
121 (
122 query,
123 SystemExecutionOutput {
124 view_systems,
125 context_systems,
126 draw_data,
127 },
128 )
129}
130
131pub fn execute_systems_for_all_views<'a>(
132 ctx: &'a ViewerContext<'a>,
133 tree: &egui_tiles::Tree<ViewId>,
134 views: &'a BTreeMap<ViewId, ViewBlueprint>,
135 view_states: &mut ViewStates,
136) -> HashMap<ViewId, (ViewQuery<'a>, SystemExecutionOutput)> {
137 re_tracing::profile_wait!("execute_systems");
138
139 for (view_id, view) in views {
141 view_states.ensure_state_exists(*view_id, view.class(ctx.view_class_registry()));
142 }
143
144 let context_system_static_exec_results = ctx
148 .view_class_registry()
149 .run_static_context_systems_for_views(
150 ctx,
151 views.values().map(|view| view.class_identifier()),
152 );
153
154 tree.active_tiles()
155 .into_par_iter()
156 .filter_map(|tile_id| {
157 let tile = tree.tiles.get(tile_id)?;
158 match tile {
159 egui_tiles::Tile::Pane(view_id) => {
160 let view = views.get(view_id)?;
161 let Some(view_state) = view_states.get(*view_id) else {
162 debug_assert!(false, "View state for view {view_id:?} not found. That shouldn't be possible since we just ensured they exist above.");
163 return None;
164 };
165
166 let result = execute_systems_for_view(ctx, view, view_state, &context_system_static_exec_results);
167 Some((*view_id, result))
168 },
169 egui_tiles::Tile::Container(_) => None,
170 }
171 })
172 .collect::<HashMap<_, _>>()
173}