generated from GarandPLG/rust-flake-template
104 lines
2.6 KiB
Rust
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(())
|
|
}
|
|
}
|