runmat_plot/gui/
single_window_manager.rs1use crate::gui::lifecycle::CloseSignal;
7use crate::gui::window::WindowConfig;
8use crate::plots::Figure;
9use std::sync::atomic::{AtomicBool, Ordering};
10use std::sync::Mutex;
11
12static WINDOW_ACTIVE: AtomicBool = AtomicBool::new(false);
14
15static WINDOW_MANAGER: Mutex<()> = Mutex::new(());
17
18pub fn show_plot_sequential(figure: Figure) -> Result<String, String> {
20 show_plot_sequential_with_signal(figure, None)
21}
22
23pub fn show_plot_sequential_with_signal(
27 figure: Figure,
28 close_signal: Option<CloseSignal>,
29) -> Result<String, String> {
30 let _guard = WINDOW_MANAGER
32 .lock()
33 .map_err(|_| "Window manager lock failed".to_string())?;
34
35 if WINDOW_ACTIVE.load(Ordering::Acquire) {
37 return Err("Another plot window is already open. Please close it first.".to_string());
38 }
39
40 WINDOW_ACTIVE.store(true, Ordering::Release);
42
43 let result = show_plot_internal(figure, close_signal);
44
45 WINDOW_ACTIVE.store(false, Ordering::Release);
47
48 result
49}
50
51fn show_plot_internal(figure: Figure, close_signal: Option<CloseSignal>) -> Result<String, String> {
53 use crate::gui::PlotWindow;
54
55 let config = WindowConfig::default();
57
58 let handle = tokio::runtime::Handle::try_current();
60
61 match handle {
62 Ok(handle) => {
63 tokio::task::block_in_place(|| {
65 handle.block_on(async {
66 let mut window = PlotWindow::new(config)
67 .await
68 .map_err(|e| format!("Failed to create plot window: {e}"))?;
69
70 if let Some(signal) = close_signal.clone() {
71 window.install_close_signal(signal);
72 }
73
74 window.set_figure(figure);
76
77 window
79 .run()
80 .await
81 .map_err(|e| format!("Window execution failed: {e}"))?;
82
83 Ok("Plot window closed successfully".to_string())
84 })
85 })
86 }
87 Err(_) => {
88 let rt = tokio::runtime::Runtime::new()
90 .map_err(|e| format!("Failed to create async runtime: {e}"))?;
91
92 rt.block_on(async {
93 let mut window = PlotWindow::new(config)
94 .await
95 .map_err(|e| format!("Failed to create plot window: {e}"))?;
96
97 if let Some(signal) = close_signal {
98 window.install_close_signal(signal);
99 }
100
101 window.set_figure(figure);
103
104 window
106 .run()
107 .await
108 .map_err(|e| format!("Window execution failed: {e}"))?;
109
110 Ok("Plot window closed successfully".to_string())
111 })
112 }
113 }
114}
115
116pub fn is_window_available() -> bool {
118 !WINDOW_ACTIVE.load(Ordering::Acquire)
119}