Files
war-in-tunnels/src/app/app.rs
T

104 lines
2.6 KiB
Rust

use crate::{
app::{GameStates, handle_keybindings, threads::AudioCmd, view::View},
cli::Cli,
};
use ratatui::{DefaultTerminal, Frame, crossterm::event::KeyEvent, layout::Rect};
use std::{
io::Result,
sync::mpsc::{Receiver, Sender},
thread::sleep,
time::Duration,
};
pub struct App {
pub exit: bool,
pub view: View,
pub window_area: Rect,
pub args: Cli,
pub states: Option<GameStates>,
pub audio_tx: Sender<AudioCmd>,
}
impl App {
pub fn new(args: Cli, audio_tx: Sender<AudioCmd>) -> Self {
Self {
exit: false,
view: args.view,
window_area: Rect::default(),
args: args,
states: None,
audio_tx,
}
}
pub fn states_ref(&self) -> Option<&GameStates> {
self.states.as_ref()
}
pub fn states_mut(&mut self) -> Option<&mut GameStates> {
self.states.as_mut()
}
pub fn run(
&mut self,
terminal: &mut DefaultTerminal,
input_rx: Receiver<KeyEvent>,
resize_rx: Receiver<(u16, u16)>,
tick_rx: Receiver<()>,
) -> Result<()> {
while !self.exit {
terminal.draw(|frame: &mut Frame<'_>| self.draw(frame))?;
if let Ok(key) = input_rx.try_recv() {
self.handle_key_event(key)?;
}
if let Ok((_, _)) = resize_rx.try_recv() {
let window_area: Rect = self.window_area;
if let Some(state) = self.states_mut() {
state
.skirmish
.board
.change_resize(&window_area, state.skirmish.side_panel);
}
}
if let Ok(()) = tick_rx.try_recv() {
self.update()?;
}
sleep(Duration::from_millis(10));
}
Ok(())
}
fn draw(&mut self, frame: &mut Frame<'_>) {
let window_area: Rect = frame.area();
if window_area.width != self.window_area.width
|| window_area.height != self.window_area.height
{
self.window_area = window_area;
if self.states.is_none() {
self.states = Some(GameStates::new(&self.args, &self.window_area))
}
}
frame.render_widget(self, window_area);
}
fn handle_key_event(&mut self, key_event: KeyEvent) -> Result<()> {
handle_keybindings(self, key_event);
Ok(())
}
fn update(&mut self) -> Result<()> {
if let Some(state) = self.states_mut() {
state.skirmish.tick_update();
}
Ok(())
}
}