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::{ScopeRef, 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 pub scope_ref_to_expand: RefCell<Option<ScopeRef>>,
87
88 pub(crate) continuous_redraw: bool,
91 #[cfg(feature = "performance_plot")]
92 pub(crate) rendering_cpu_times: VecDeque<f32>,
93 #[cfg(feature = "performance_plot")]
94 pub(crate) timing: RefCell<Timing>,
95
96 pub(crate) undo_stack: Vec<CanvasState>,
98 pub(crate) redo_stack: Vec<CanvasState>,
99
100 pub(crate) url_callback: Option<Box<dyn Fn(String) -> Message + Send + 'static>>,
101
102 pub(crate) expand_parameter_section: bool,
104}
105
106impl SystemState {
107 pub fn new() -> Result<SystemState> {
108 Self::new_inner(false)
109 }
110
111 #[cfg(test)]
112 pub(crate) fn new_default_config() -> Result<SystemState> {
113 Self::new_inner(true)
114 }
115
116 fn new_inner(force_default_config: bool) -> Result<SystemState> {
117 let config = SurferConfig::new(force_default_config)
118 .with_context(|| "Failed to load config file")?;
119 let channels = Channels::new();
120
121 let translators = all_translators();
123
124 let result = SystemState {
125 user: UserState {
126 config,
127 waves: None,
128 previous_waves: None,
129 count: None,
130 blacklisted_translators: HashSet::new(),
131 show_about: false,
132 show_keys: false,
133 show_gestures: false,
134 show_performance: false,
135 show_license: false,
136 show_logs: false,
137 show_cursor_window: false,
138 wanted_timeunit: TimeUnit::None,
139 time_string_format: None,
140 show_url_entry: false,
141 show_quick_start: false,
142 rename_target: None,
143 show_reload_suggestion: None,
144 variable_name_filter_focused: false,
145 variable_filter: VariableFilter::new(),
146 ui_zoom_factor: None,
147 state_file: None,
148 show_hierarchy: None,
149 show_menu: None,
150 show_ticks: None,
151 show_toolbar: None,
152 show_tooltip: None,
153 show_scope_tooltip: None,
154 show_default_timeline: None,
155 show_overview: None,
156 show_statusbar: None,
157 show_variable_direction: None,
158 show_open_sibling_state_file_suggestion: None,
159 align_names_right: None,
160 show_variable_indices: None,
161 show_empty_scopes: None,
162 show_parameters_in_scopes: None,
163 highlight_focused: None,
164 fill_high_values: None,
165 drag_started: false,
166 drag_source_idx: None,
167 drag_target_idx: None,
168 sidepanel_width: None,
169 primary_button_drag_behavior: None,
170 arrow_key_bindings: None,
171 clock_highlight_type: None,
172 hierarchy_style: None,
173 autoload_sibling_state_files: None,
174 autoreload_files: None,
175 },
176 translators,
177 channels,
178 progress_tracker: None,
179 command_prompt: command_prompt::CommandPrompt {
180 visible: false,
181 suggestions: vec![],
182 selected: 0,
183 new_selection: None,
184 new_cursor_pos: None,
185 previous_commands: vec![],
186 },
187 context: None,
188 wcp_server_thread: None,
189 wcp_server_address: None,
190 wcp_stop_signal: Arc::new(AtomicBool::new(false)),
191 wcp_running_signal: Arc::new(AtomicBool::new(false)),
192 wcp_greeted_signal: Arc::new(AtomicBool::new(false)),
193 wcp_client_capabilities: WcpClientCapabilities::new(),
194 gesture_start_location: None,
195 measure_start_location: None,
196 batch_messages: VecDeque::new(),
197 batch_messages_completed: false,
198 url: RefCell::new(String::new()),
199 command_prompt_text: RefCell::new(String::new()),
200 draw_data: RefCell::new(vec![None]),
201 variable_name_info_cache: RefCell::new(HashMap::new()),
202 last_canvas_rect: RefCell::new(None),
203 item_renaming_string: RefCell::new(String::new()),
204
205 items_to_expand: RefCell::new(vec![]),
206 char_to_add_to_prompt: RefCell::new(None),
207 scope_ref_to_expand: RefCell::new(None),
208 expand_parameter_section: false,
209
210 url_callback: None,
211 continuous_redraw: false,
212 #[cfg(feature = "performance_plot")]
213 rendering_cpu_times: VecDeque::new(),
214 #[cfg(feature = "performance_plot")]
215 timing: RefCell::new(Timing::new()),
216 undo_stack: vec![],
217 redo_stack: vec![],
218 };
219
220 Ok(result)
221 }
222}
223
224impl From<UserState> for SystemState {
225 fn from(serializable_state: UserState) -> SystemState {
226 let mut state = SystemState::new().unwrap();
227 state.user = serializable_state;
228 state
229 }
230}