1use eyre::{Context, Result};
2use std::{
3 cell::RefCell,
4 collections::{HashMap, HashSet, VecDeque},
5 sync::{atomic::AtomicBool, Arc},
6};
7use tokio::task::JoinHandle;
8
9use egui::{Pos2, Rect};
10use surfer_translation_types::translator::VariableNameInfo;
11
12use crate::{
13 command_prompt,
14 config::SurferConfig,
15 displayed_item::DisplayedItemRef,
16 message::Message,
17 state::UserState,
18 time::TimeUnit,
19 translation::{all_translators, TranslatorList},
20 variable_filter::VariableFilter,
21 wave_container::VariableRef,
22 wave_source::LoadProgress,
23 CachedDrawData, CanvasState, Channels, WcpClientCapabilities,
24};
25
26#[cfg(feature = "performance_plot")]
27use crate::benchmark::Timing;
28
29pub struct SystemState {
30 pub user: UserState,
31
32 pub(crate) translators: TranslatorList,
34 pub channels: Channels,
36
37 pub(crate) progress_tracker: Option<LoadProgress>,
39
40 pub(crate) command_prompt: command_prompt::CommandPrompt,
42
43 pub(crate) context: Option<Arc<egui::Context>>,
45
46 pub(crate) batch_messages: VecDeque<Message>,
48 pub(crate) batch_messages_completed: bool,
49
50 #[allow(unused)]
52 pub(crate) wcp_server_thread: Option<JoinHandle<()>>,
53 #[allow(unused)]
54 pub(crate) wcp_server_address: Option<String>,
55 #[allow(unused)]
56 pub(crate) wcp_stop_signal: Arc<AtomicBool>,
57 #[allow(unused)]
58 pub(crate) wcp_running_signal: Arc<AtomicBool>,
59 pub(crate) wcp_greeted_signal: Arc<AtomicBool>,
60 pub(crate) wcp_client_capabilities: WcpClientCapabilities,
61
62 pub(crate) draw_data: RefCell<Vec<Option<CachedDrawData>>>,
66
67 pub(crate) variable_name_info_cache: RefCell<HashMap<VariableRef, Option<VariableNameInfo>>>,
68
69 pub(crate) gesture_start_location: Option<Pos2>,
70
71 pub(crate) measure_start_location: Option<Pos2>,
72
73 pub(crate) url: RefCell<String>,
75 pub(crate) command_prompt_text: RefCell<String>,
76 pub(crate) last_canvas_rect: RefCell<Option<Rect>>,
77 pub(crate) item_renaming_string: RefCell<String>,
78
79 pub(crate) items_to_expand: RefCell<Vec<(DisplayedItemRef, usize)>>,
82 pub(crate) char_to_add_to_prompt: RefCell<Option<char>>,
85
86 pub(crate) continuous_redraw: bool,
89 #[cfg(feature = "performance_plot")]
90 pub(crate) rendering_cpu_times: VecDeque<f32>,
91 #[cfg(feature = "performance_plot")]
92 pub(crate) timing: RefCell<Timing>,
93
94 pub(crate) undo_stack: Vec<CanvasState>,
96 pub(crate) redo_stack: Vec<CanvasState>,
97
98 pub(crate) url_callback: Option<Box<dyn Fn(String) -> Message + Send + 'static>>,
99
100 pub(crate) expand_parameter_section: bool,
102}
103
104impl SystemState {
105 pub fn new() -> Result<SystemState> {
106 Self::new_inner(false)
107 }
108
109 #[cfg(test)]
110 pub(crate) fn new_default_config() -> Result<SystemState> {
111 Self::new_inner(true)
112 }
113
114 fn new_inner(force_default_config: bool) -> Result<SystemState> {
115 let config = SurferConfig::new(force_default_config)
116 .with_context(|| "Failed to load config file")?;
117 let channels = Channels::new();
118
119 let translators = all_translators();
121
122 let result = SystemState {
123 user: UserState {
124 config,
125 waves: None,
126 previous_waves: None,
127 count: None,
128 blacklisted_translators: HashSet::new(),
129 show_about: false,
130 show_keys: false,
131 show_gestures: false,
132 show_performance: false,
133 show_license: false,
134 show_logs: false,
135 show_cursor_window: false,
136 wanted_timeunit: TimeUnit::None,
137 time_string_format: None,
138 show_url_entry: false,
139 show_quick_start: false,
140 rename_target: None,
141 show_reload_suggestion: None,
142 variable_name_filter_focused: false,
143 variable_filter: VariableFilter::new(),
144 ui_zoom_factor: None,
145 state_file: None,
146 show_hierarchy: None,
147 show_menu: None,
148 show_ticks: None,
149 show_toolbar: None,
150 show_tooltip: None,
151 show_scope_tooltip: None,
152 show_default_timeline: None,
153 show_overview: None,
154 show_statusbar: None,
155 show_variable_direction: None,
156 show_open_sibling_state_file_suggestion: None,
157 align_names_right: None,
158 show_variable_indices: None,
159 show_empty_scopes: None,
160 show_parameters_in_scopes: None,
161 highlight_focused: None,
162 fill_high_values: None,
163 drag_started: false,
164 drag_source_idx: None,
165 drag_target_idx: None,
166 sidepanel_width: None,
167 primary_button_drag_behavior: None,
168 arrow_key_bindings: None,
169 clock_highlight_type: None,
170 hierarchy_style: None,
171 autoload_sibling_state_files: None,
172 autoreload_files: None,
173 },
174 translators,
175 channels,
176 progress_tracker: None,
177 command_prompt: command_prompt::CommandPrompt {
178 visible: false,
179 suggestions: vec![],
180 selected: 0,
181 new_selection: None,
182 new_cursor_pos: None,
183 previous_commands: vec![],
184 },
185 context: None,
186 wcp_server_thread: None,
187 wcp_server_address: None,
188 wcp_stop_signal: Arc::new(AtomicBool::new(false)),
189 wcp_running_signal: Arc::new(AtomicBool::new(false)),
190 wcp_greeted_signal: Arc::new(AtomicBool::new(false)),
191 wcp_client_capabilities: WcpClientCapabilities::new(),
192 gesture_start_location: None,
193 measure_start_location: None,
194 batch_messages: VecDeque::new(),
195 batch_messages_completed: false,
196 url: RefCell::new(String::new()),
197 command_prompt_text: RefCell::new(String::new()),
198 draw_data: RefCell::new(vec![None]),
199 variable_name_info_cache: RefCell::new(HashMap::new()),
200 last_canvas_rect: RefCell::new(None),
201 item_renaming_string: RefCell::new(String::new()),
202
203 items_to_expand: RefCell::new(vec![]),
204 char_to_add_to_prompt: RefCell::new(None),
205 expand_parameter_section: false,
206
207 url_callback: None,
208 continuous_redraw: false,
209 #[cfg(feature = "performance_plot")]
210 rendering_cpu_times: VecDeque::new(),
211 #[cfg(feature = "performance_plot")]
212 timing: RefCell::new(Timing::new()),
213 undo_stack: vec![],
214 redo_stack: vec![],
215 };
216
217 Ok(result)
218 }
219}
220
221impl From<UserState> for SystemState {
222 fn from(serializable_state: UserState) -> SystemState {
223 let mut state = SystemState::new().unwrap();
224 state.user = serializable_state;
225 state
226 }
227}