1use eyre::Result;
2use std::{
3 cell::RefCell,
4 collections::{HashMap, VecDeque},
5 sync::{Arc, atomic::AtomicBool},
6};
7use tokio::task::JoinHandle;
8
9use egui::{Pos2, Rect};
10use surfer_translation_types::translator::VariableNameInfo;
11
12use crate::{
13 CachedDrawData, CanvasState, Channels, WcpClientCapabilities, command_prompt,
14 displayed_item::DisplayedItemRef,
15 frame_buffer::{FrameBufferArrayCache, FrameBufferContent, FrameBufferPixelCache},
16 hierarchy::ScopeExpandType,
17 message::Message,
18 state::UserState,
19 time::TimeInputState,
20 translation::{TranslatorList, all_translators},
21 wave_container::VariableRef,
22 wave_source::{LoadOptions, LoadProgress},
23};
24
25#[cfg(feature = "performance_plot")]
26use crate::benchmark::Timing;
27
28pub struct SystemState {
29 pub user: UserState,
30
31 pub(crate) translators: TranslatorList,
33 pub channels: Channels,
35
36 pub(crate) progress_tracker: Option<LoadProgress>,
38
39 pub(crate) command_prompt: command_prompt::CommandPrompt,
41
42 pub(crate) context: Option<Arc<egui::Context>>,
44
45 pub(crate) batch_messages: VecDeque<Message>,
47 pub(crate) batch_messages_completed: bool,
48
49 #[allow(unused)]
51 pub(crate) wcp_server_thread: Option<JoinHandle<()>>,
52 #[allow(unused)]
53 pub(crate) wcp_server_address: Option<String>,
54 #[allow(unused)]
55 pub(crate) wcp_stop_signal: Arc<AtomicBool>,
56 #[allow(unused)]
57 pub(crate) wcp_running_signal: Arc<AtomicBool>,
58 pub(crate) wcp_greeted_signal: Arc<AtomicBool>,
59 pub(crate) wcp_client_capabilities: WcpClientCapabilities,
60
61 pub(crate) draw_data: RefCell<Vec<Option<CachedDrawData>>>,
65
66 pub(crate) variable_name_info_cache: RefCell<HashMap<VariableRef, Option<VariableNameInfo>>>,
67
68 pub(crate) gesture_start_location: Option<Pos2>,
69
70 pub(crate) measure_start_location: Option<Pos2>,
71
72 pub(crate) url: RefCell<String>,
74 pub(crate) command_prompt_text: RefCell<String>,
75 pub(crate) last_canvas_rect: RefCell<Option<Rect>>,
76 pub(crate) surver_selected_file: RefCell<Option<usize>>,
77 pub(crate) surver_load_options: RefCell<LoadOptions>,
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<ScopeExpandType>>,
87
88 pub(crate) time_widget: RefCell<TimeInputState>,
89 pub(crate) time_edit_focused: bool,
90 pub(crate) request_time_edit_focus: bool,
91 pub(crate) frame_buffer_content: Option<FrameBufferContent>,
92 pub(crate) frame_buffer_array_cache: Option<FrameBufferArrayCache>,
93 pub(crate) frame_buffer_pixel_cache: Option<FrameBufferPixelCache>,
94
95 pub(crate) continuous_redraw: bool,
98 #[cfg(feature = "performance_plot")]
99 pub(crate) rendering_cpu_times: VecDeque<f32>,
100 #[cfg(feature = "performance_plot")]
101 pub(crate) timing: RefCell<Timing>,
102
103 pub(crate) undo_stack: Vec<CanvasState>,
105 pub(crate) redo_stack: Vec<CanvasState>,
106
107 pub(crate) url_callback: Option<Box<dyn Fn(String) -> Message + Send + 'static>>,
108
109 pub(crate) expand_parameter_section: bool,
111}
112
113impl SystemState {
114 pub fn new() -> Result<SystemState> {
115 Self::new_inner(false)
116 }
117
118 #[cfg(test)]
119 pub(crate) fn new_default_config() -> Result<SystemState> {
120 Self::new_inner(true)
121 }
122
123 fn new_inner(force_default_config: bool) -> Result<SystemState> {
124 let channels = Channels::new();
125
126 let translators = all_translators();
128
129 let result = SystemState {
130 user: UserState::new(force_default_config)?,
131 translators,
132 channels,
133 progress_tracker: None,
134 command_prompt: Default::default(),
135 context: None,
136 wcp_server_thread: None,
137 wcp_server_address: None,
138 wcp_stop_signal: Arc::new(AtomicBool::new(false)),
139 wcp_running_signal: Arc::new(AtomicBool::new(false)),
140 wcp_greeted_signal: Arc::new(AtomicBool::new(false)),
141 wcp_client_capabilities: WcpClientCapabilities::new(),
142 gesture_start_location: None,
143 measure_start_location: None,
144 batch_messages: VecDeque::new(),
145 batch_messages_completed: false,
146 url: RefCell::new(String::new()),
147 command_prompt_text: RefCell::new(String::new()),
148 draw_data: RefCell::new(vec![None]),
149 variable_name_info_cache: RefCell::new(HashMap::new()),
150 last_canvas_rect: RefCell::new(None),
151
152 items_to_expand: RefCell::new(vec![]),
153 char_to_add_to_prompt: RefCell::new(None),
154 scope_ref_to_expand: RefCell::new(None),
155 surver_selected_file: RefCell::new(None),
156 surver_load_options: RefCell::new(LoadOptions::Clear),
157 expand_parameter_section: false,
158 time_widget: RefCell::new(TimeInputState::default()),
159 time_edit_focused: false,
160 request_time_edit_focus: false,
161 frame_buffer_content: None,
162 frame_buffer_array_cache: None,
163 frame_buffer_pixel_cache: None,
164
165 url_callback: None,
166 continuous_redraw: false,
167 #[cfg(feature = "performance_plot")]
168 rendering_cpu_times: VecDeque::new(),
169 #[cfg(feature = "performance_plot")]
170 timing: RefCell::new(Timing::new()),
171 undo_stack: vec![],
172 redo_stack: vec![],
173 };
174
175 Ok(result)
176 }
177}
178
179impl From<UserState> for SystemState {
180 fn from(serializable_state: UserState) -> SystemState {
181 let mut state = SystemState::new().unwrap();
182 state.user = serializable_state;
183 state
184 }
185}