1use pancurses::{cbreak, curs_set, endwin, has_colors, initscr, noecho, start_color, Window};
4
5use crate::{color, prelude::Stage};
6
7pub struct Game<G> {
10 globals: G,
11 running: bool,
12 win: Window,
13}
14
15impl<G> Drop for Game<G> {
16 fn drop(&mut self) {
17 endwin();
18 }
19}
20
21impl<G> Game<G> {
22 pub fn new(initial_globals: G) -> Self {
24 let win = Self::init();
25 Self {
26 globals: initial_globals,
27 running: true,
28 win,
29 }
30 }
31
32 pub fn with_colors(initial_globals: G) -> Option<Self> {
35 let win = Self::init();
36 if !has_colors() {
37 endwin();
38 return None;
39 }
40 start_color();
41 color::init_colors();
42 Some(Self {
43 globals: initial_globals,
44 running: true,
45 win,
46 })
47 }
48
49 fn init() -> Window {
50 let win = initscr();
51 win.keypad(true);
52 win.nodelay(true);
53 cbreak();
54 noecho();
55 curs_set(0);
56 win
57 }
58
59 pub fn globals(&self) -> &G {
61 &self.globals
62 }
63 pub fn globals_mut(&mut self) -> &mut G {
65 &mut self.globals
66 }
67 pub fn is_running(&self) -> bool {
69 self.win().refresh();
70 self.running
71 }
72 pub fn running(&self) -> bool {
74 self.running
75 }
76 pub fn start(&mut self) {
78 self.running = true;
79 }
80 pub fn stop(&mut self) {
82 self.running = false;
83 }
84 pub fn win(&self) -> &Window {
86 &self.win
87 }
88 pub fn win_mut(&mut self) -> &mut Window {
90 &mut self.win
91 }
92
93 pub fn perform<T, E>(&mut self, stage: &mut Stage<T, E, G>) -> Result<(), E> {
95 stage.draw(self)?;
96 stage.update(self)?;
97 Ok(())
98 }
99}