1use eyre::Result;
2use num::BigInt;
3use std::{
4 cell::RefCell,
5 collections::{HashMap, VecDeque},
6 sync::{Arc, atomic::AtomicBool},
7};
8use tokio::task::JoinHandle;
9
10use egui::{Pos2, Rect};
11use surfer_translation_types::translator::VariableNameInfo;
12
13use std::rc::Rc;
14
15use crate::{
16 CachedDrawData, CanvasState, Channels, WcpClientCapabilities, command_prompt,
17 displayed_item::DisplayedItemRef,
18 file_history::FileHistory,
19 frame_buffer::{FrameBufferArrayCache, FrameBufferContent, FrameBufferPixelCache},
20 hierarchy::{AllVariableCacheKey, ScopeExpandType, VariableListRow},
21 message::Message,
22 mousegestures::AnnotationKind,
23 state::UserState,
24 time::TimeInputState,
25 translation::{TranslatorList, all_translators},
26 wave_container::VariableRef,
27 wave_source::{LoadOptions, LoadProgress},
28};
29
30#[cfg(feature = "performance_plot")]
31use crate::benchmark::Timing;
32
33pub struct SystemState {
34 pub user: UserState,
35 pub(crate) file_history: FileHistory,
36 pub(crate) translators: TranslatorList,
38 pub channels: Channels,
40
41 pub(crate) progress_tracker: Option<LoadProgress>,
43
44 pub(crate) command_prompt: command_prompt::CommandPrompt,
46
47 pub(crate) context: Option<Arc<egui::Context>>,
49
50 pub(crate) batch_messages: VecDeque<Message>,
52 pub(crate) batch_messages_completed: bool,
53
54 #[allow(unused)]
56 pub(crate) wcp_server_thread: Option<JoinHandle<()>>,
57 #[allow(unused)]
58 pub(crate) wcp_server_address: Option<String>,
59 #[allow(unused)]
60 pub(crate) wcp_stop_signal: Arc<AtomicBool>,
61 #[allow(unused)]
62 pub(crate) wcp_running_signal: Arc<AtomicBool>,
63 pub(crate) wcp_greeted_signal: Arc<AtomicBool>,
64 pub(crate) wcp_client_capabilities: WcpClientCapabilities,
65
66 pub(crate) draw_data: RefCell<Vec<Option<CachedDrawData>>>,
70
71 pub(crate) variable_name_info_cache: RefCell<HashMap<VariableRef, Option<VariableNameInfo>>>,
72
73 pub(crate) translator_generation: u64,
76 pub(crate) all_variable_rows_cache: Option<(AllVariableCacheKey, Rc<Vec<VariableListRow>>)>,
79
80 pub(crate) gesture_start_location: Option<Pos2>,
81 pub(crate) gesture_start_time: Option<BigInt>,
82
83 pub(crate) measure_start_location: Option<Pos2>,
84
85 pub(crate) annotation_kind: Option<AnnotationKind>,
86
87 pub(crate) url: RefCell<String>,
89 pub(crate) command_prompt_text: RefCell<String>,
90 pub(crate) last_canvas_rect: RefCell<Option<Rect>>,
91 pub(crate) surver_selected_file: RefCell<Option<usize>>,
92 pub(crate) surver_load_options: RefCell<LoadOptions>,
93
94 pub(crate) items_to_expand: RefCell<Vec<(DisplayedItemRef, usize)>>,
97 pub(crate) char_to_add_to_prompt: RefCell<Option<char>>,
100 pub scope_ref_to_expand: RefCell<Option<ScopeExpandType>>,
102
103 pub(crate) time_widget: RefCell<TimeInputState>,
104 pub(crate) time_edit_focused: bool,
105 pub(crate) request_time_edit_focus: bool,
106 pub(crate) frame_buffer_content: Option<FrameBufferContent>,
107 pub(crate) frame_buffer_array_cache: Option<FrameBufferArrayCache>,
108 pub(crate) frame_buffer_pixel_cache: Option<FrameBufferPixelCache>,
109
110 pub(crate) continuous_redraw: bool,
113 #[cfg(feature = "performance_plot")]
114 pub(crate) rendering_cpu_times: VecDeque<f32>,
115 #[cfg(feature = "performance_plot")]
116 pub(crate) timing: RefCell<Timing>,
117
118 pub(crate) undo_stack: Vec<CanvasState>,
120 pub(crate) redo_stack: Vec<CanvasState>,
121
122 pub(crate) url_callback: Option<Box<dyn Fn(String) -> Message + Send + 'static>>,
123
124 pub(crate) expand_parameter_section: bool,
126
127 pub(crate) annotation_id_source: u64,
128 pub(crate) click_handled: bool,
129}
130
131impl SystemState {
132 pub fn new() -> Result<SystemState> {
133 Self::new_inner(false)
134 }
135
136 #[cfg(test)]
137 pub(crate) fn new_default_config() -> Result<SystemState> {
138 Self::new_inner(true)
139 }
140
141 fn new_inner(force_default_config: bool) -> Result<SystemState> {
142 let channels = Channels::new();
143 let user = UserState::new(force_default_config)?;
144 let file_history = FileHistory::load(user.config.behavior.file_history_size());
145
146 let translators = all_translators();
148
149 let result = SystemState {
150 user,
151 file_history,
152 translators,
153 channels,
154 progress_tracker: None,
155 command_prompt: Default::default(),
156 context: None,
157 wcp_server_thread: None,
158 wcp_server_address: None,
159 wcp_stop_signal: Arc::new(AtomicBool::new(false)),
160 wcp_running_signal: Arc::new(AtomicBool::new(false)),
161 wcp_greeted_signal: Arc::new(AtomicBool::new(false)),
162 wcp_client_capabilities: WcpClientCapabilities::new(),
163 gesture_start_location: None,
164 gesture_start_time: None,
165
166 measure_start_location: None,
167 batch_messages: VecDeque::new(),
168 batch_messages_completed: false,
169 url: RefCell::new(String::new()),
170 command_prompt_text: RefCell::new(String::new()),
171 draw_data: RefCell::new(vec![None]),
172 variable_name_info_cache: RefCell::new(HashMap::new()),
173 translator_generation: 0,
174 all_variable_rows_cache: None,
175 last_canvas_rect: RefCell::new(None),
176
177 items_to_expand: RefCell::new(vec![]),
178 char_to_add_to_prompt: RefCell::new(None),
179 scope_ref_to_expand: RefCell::new(None),
180 surver_selected_file: RefCell::new(None),
181 surver_load_options: RefCell::new(LoadOptions::Clear),
182 expand_parameter_section: false,
183 time_widget: RefCell::new(TimeInputState::default()),
184 time_edit_focused: false,
185 request_time_edit_focus: false,
186 frame_buffer_content: None,
187 frame_buffer_array_cache: None,
188 frame_buffer_pixel_cache: None,
189
190 url_callback: None,
191 continuous_redraw: false,
192 #[cfg(feature = "performance_plot")]
193 rendering_cpu_times: VecDeque::new(),
194 #[cfg(feature = "performance_plot")]
195 timing: RefCell::new(Timing::new()),
196 undo_stack: vec![],
197 redo_stack: vec![],
198 annotation_kind: None,
199 annotation_id_source: 0,
200 click_handled: false,
201 };
202
203 Ok(result)
204 }
205}
206
207impl From<UserState> for SystemState {
208 fn from(serializable_state: UserState) -> SystemState {
209 let mut state = SystemState::new().unwrap();
210 state.user = serializable_state;
211 state
212 }
213}