pn_editor_core/
state_info.rs

1use pns::{FireChanges, State, Tid};
2use rfd::FileDialog;
3
4use std::{collections::BTreeMap, path::PathBuf};
5
6/// Indicates if some transition is callable.
7#[derive(Default, Copy, Clone)]
8pub struct CallableState {
9    /// The transition is callable forward.
10    pub forward: bool,
11    /// The transition is callable backward.
12    pub backward: bool,
13}
14
15pub struct StateInfo {
16    pub state_path: Option<PathBuf>,
17    pub changes: bool,
18    pub callables: BTreeMap<Tid, CallableState>,
19}
20
21impl StateInfo {
22    pub fn update_state(&mut self, state: &mut State) {
23        let FireChanges { added, removed } = state.changed_transitions();
24
25        for added in added {
26            unsafe { self.callables.get_mut(&added).unwrap_unchecked() }.forward = true;
27        }
28        for removed in removed {
29            unsafe { self.callables.get_mut(&removed).unwrap_unchecked() }.forward = false;
30        }
31
32        let FireChanges { added, removed } = state.changed_transitions_backward();
33
34        for added in added {
35            unsafe { self.callables.get_mut(&added).unwrap_unchecked() }.backward = true;
36        }
37        for removed in removed {
38            unsafe { self.callables.get_mut(&removed).unwrap_unchecked() }.backward = false;
39        }
40    }
41
42    pub fn file_dialog(&self) -> FileDialog {
43        let dialog = FileDialog::new().add_filter("Petri net interactive files", &["pns"]);
44
45        if let Some(path) = &self.state_path {
46            dialog.set_directory(path)
47        } else if let Ok(path) = std::env::current_dir() {
48            dialog.set_directory(path)
49        } else {
50            dialog
51        }
52    }
53}