1pub mod input;
7pub mod render;
8pub mod state;
9
10use std::io;
11
12use crossterm::cursor::{Hide, Show};
13use crossterm::execute;
14use crossterm::terminal::{EnterAlternateScreen, LeaveAlternateScreen};
15use ratatui::Terminal;
16use ratatui::backend::CrosstermBackend;
17
18use nms_graph::GalaxyModel;
19
20use crate::session::SessionState;
21use state::MapState;
22
23pub fn run_map(model: &GalaxyModel, session: &SessionState) -> io::Result<()> {
28 crossterm::terminal::enable_raw_mode()?;
30 let mut stdout = io::stdout();
31 execute!(stdout, EnterAlternateScreen, Hide)?;
32 let backend = CrosstermBackend::new(stdout);
33 let mut terminal = Terminal::new(backend)?;
34
35 let result = run_map_loop(&mut terminal, model, session);
36
37 crossterm::terminal::disable_raw_mode()?;
39 execute!(terminal.backend_mut(), Show, LeaveAlternateScreen)?;
40
41 result
42}
43
44fn run_map_loop(
46 terminal: &mut Terminal<CrosstermBackend<io::Stdout>>,
47 model: &GalaxyModel,
48 session: &SessionState,
49) -> io::Result<()> {
50 let size = terminal.size()?;
51 let mut state = MapState::new(model, session);
52 state.resize(size.width, size.height);
53
54 loop {
55 terminal.draw(|frame| {
56 render::render(frame, &state, model);
57 })?;
58
59 input::handle_input(&mut state)?;
60
61 if state.should_quit {
62 break;
63 }
64 }
65
66 Ok(())
67}