Skip to content

Commit

Permalink
Implement redrawing when it needs for fixing Vinatorul#22.
Browse files Browse the repository at this point in the history
Piston use double buffering for drawing in 2d mode.
RenderState is used for redrawing both buffer when it needs.

On my computer, CPU load dropped from 6-7% percents to 0.3% without any input with default settings.

In general, it works fine, but there are some case that needed addition handling: window resizing, stoping timer after changing field size or mine count and may be something else.
  • Loading branch information
Evgeny Khudoba committed Oct 25, 2015
1 parent a8e3e05 commit 17bf631
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 9 deletions.
79 changes: 71 additions & 8 deletions src/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,35 @@ use piston_window::*;
use common::{ParamType, MoveDestination, GameEndState};
use chrono::{DateTime, UTC, Duration};

enum RenderState {
// redraw picture on current buffer
First,

// redraw picture on next buffer
Second,

// needn't redraw picture
None
}

impl RenderState {

// Update render state and return flag necessity of redrawing pickture
fn update_state(&mut self) -> bool {
match *self {
RenderState::First => *self = RenderState::Second,
RenderState::Second => *self = RenderState::None,
RenderState::None => return false
}

true
}

fn reset(&mut self) {
*self = RenderState::First
}
}

pub struct Game<'a> {
field: Field,
ui: UI<'a>,
Expand All @@ -16,7 +45,10 @@ pub struct Game<'a> {
panel_width: u32,
in_ui: bool,
game_start : Option<DateTime<UTC>>,
last_time : Option<DateTime<UTC>>,
game_end : Option<DateTime<UTC>>,
// state of rendering for drawing picture on both buffers
render_state: RenderState
}

impl<'a> Game<'a> {
Expand All @@ -32,11 +64,17 @@ impl<'a> Game<'a> {
panel_width: 350,
in_ui: false,
game_start: None,
game_end : None,
game_end: None,
last_time: None,
render_state: RenderState::First
}
}

pub fn render(&mut self, window: &PistonWindow) {
if !self.render_state.update_state() {
return;
}

window.draw_2d(|c, g| {
clear([0.0, 0.0, 0.0, 1.0], g);
let field_rect = self.get_field_rect(window);
Expand Down Expand Up @@ -89,6 +127,7 @@ impl<'a> Game<'a> {
}

pub fn proc_key(&mut self, button: Button, window: &PistonWindow) {
let mut need_redraw = true;
if self.in_ui {
match button {
Button::Keyboard(key) => {
Expand All @@ -100,7 +139,7 @@ impl<'a> Game<'a> {
self.msg.hide();
self.field.reinit_field(h, ParamType::Height);
}
_ => {}
_ => need_redraw = false
}
},
Key::M => {
Expand All @@ -110,7 +149,7 @@ impl<'a> Game<'a> {
self.msg.hide();
self.field.reinit_field(m, ParamType::Mines);
}
_ => {}
_ => need_redraw = false
}
},
Key::W => {
Expand All @@ -120,17 +159,17 @@ impl<'a> Game<'a> {
self.msg.hide();
self.field.reinit_field(w, ParamType::Width);
}
_ => {}
_ => need_redraw = false
}
},
Key::Up => self.ui.change_selected(MoveDestination::Up),
Key::Down => self.ui.change_selected(MoveDestination::Down),
Key::Left => self.ui.change_selected(MoveDestination::Left),
Key::Right => self.ui.change_selected(MoveDestination::Right),
_ => {}
_ => need_redraw = false
}
}
_ => {}
_ => need_redraw = false
}
} else {
match button {
Expand Down Expand Up @@ -161,7 +200,7 @@ impl<'a> Game<'a> {
self.ui.proc_key(ParamType::Width);
self.in_ui = true;
},
_ => {}
_ => need_redraw = false
}
},
Button::Mouse(btn) => {
Expand All @@ -185,11 +224,15 @@ impl<'a> Game<'a> {

self.toggle_mark(x + y*w);
},
_ => {}
_ => need_redraw = false
}
}
}
}

if need_redraw {
self.render_state.reset();
}
}

fn toggle_mark(&mut self, i: u32) {
Expand Down Expand Up @@ -285,11 +328,31 @@ impl<'a> Game<'a> {
self.mouse_y = mouse_rel[1];
}

pub fn update_state(&mut self) {
if let Some(_) = self.game_start {
if let None = self.game_end {
let now = UTC::now();
match self.last_time {
Some(last_time) => {
let time_from_last_tick = now - last_time;
if time_from_last_tick >= Duration::seconds(1) {
self.last_time = Some(now);
self.render_state.reset();
}
},
None => self.last_time = Some(now),
}
}
}
}

fn restart(&mut self) {
self.game_ended = false;
self.msg.hide();
self.game_start = None;
self.game_end = None;
self.last_time = None;
self.field.restart();
self.render_state.reset();
}
}
7 changes: 6 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,11 @@ fn main() {
let mut game = game::Game::new(glyphs, f_width, f_height, mines);
window.set_max_fps(max_fps);
for e in window {
game.render(&e);
game.update_state();

if let Some(_) = e.render_args() {
game.render(&e);
}

if let Some(mouse_rel) = e.mouse_cursor_args() {
game.mouse_move(mouse_rel);
Expand All @@ -143,5 +147,6 @@ fn main() {
if let Some(button) = e.press_args() {
game.proc_key(button, &e);
}

}
}

0 comments on commit 17bf631

Please sign in to comment.