runmat_plot/gui/
single_window_manager.rs1use crate::gui::window::WindowConfig;
7use crate::plots::Figure;
8use std::sync::atomic::{AtomicBool, Ordering};
9use std::sync::Mutex;
10
11static WINDOW_ACTIVE: AtomicBool = AtomicBool::new(false);
13
14static WINDOW_MANAGER: Mutex<()> = Mutex::new(());
16
17pub fn show_plot_sequential(figure: Figure) -> Result<String, String> {
19 let _guard = WINDOW_MANAGER
21 .lock()
22 .map_err(|_| "Window manager lock failed".to_string())?;
23
24 if WINDOW_ACTIVE.load(Ordering::Acquire) {
26 return Err("Another plot window is already open. Please close it first.".to_string());
27 }
28
29 WINDOW_ACTIVE.store(true, Ordering::Release);
31
32 let result = show_plot_internal(figure);
33
34 WINDOW_ACTIVE.store(false, Ordering::Release);
36
37 result
38}
39
40fn show_plot_internal(figure: Figure) -> Result<String, String> {
42 use crate::gui::PlotWindow;
43
44 let config = WindowConfig::default();
46
47 let handle = tokio::runtime::Handle::try_current();
49
50 match handle {
51 Ok(handle) => {
52 tokio::task::block_in_place(|| {
54 handle.block_on(async {
55 let mut window = PlotWindow::new(config)
56 .await
57 .map_err(|e| format!("Failed to create plot window: {e}"))?;
58
59 window.set_figure(figure);
61
62 window
64 .run()
65 .await
66 .map_err(|e| format!("Window execution failed: {e}"))?;
67
68 Ok("Plot window closed successfully".to_string())
69 })
70 })
71 }
72 Err(_) => {
73 let rt = tokio::runtime::Runtime::new()
75 .map_err(|e| format!("Failed to create async runtime: {e}"))?;
76
77 rt.block_on(async {
78 let mut window = PlotWindow::new(config)
79 .await
80 .map_err(|e| format!("Failed to create plot window: {e}"))?;
81
82 window.set_figure(figure);
84
85 window
87 .run()
88 .await
89 .map_err(|e| format!("Window execution failed: {e}"))?;
90
91 Ok("Plot window closed successfully".to_string())
92 })
93 }
94 }
95}
96
97pub fn is_window_available() -> bool {
99 !WINDOW_ACTIVE.load(Ordering::Acquire)
100}