unify event queues with Generics
This commit is contained in:
parent
761b9ba295
commit
993f608cfa
25
src/gui.rs
25
src/gui.rs
|
@ -4,10 +4,14 @@ pub mod settings_menu;
|
||||||
pub mod texture_store;
|
pub mod texture_store;
|
||||||
mod tile_render;
|
mod tile_render;
|
||||||
pub mod top_menu;
|
pub mod top_menu;
|
||||||
pub mod ui_event;
|
|
||||||
|
use crate::{logic::game_board::ModifyMode, util::Events};
|
||||||
|
|
||||||
use self::{
|
use self::{
|
||||||
highlighter::Highlighter, settings_menu::SettingsMenu, texture_store::TextureStore, top_menu::GUITop, ui_event::GUIEvents,
|
highlighter::Highlighter,
|
||||||
|
settings_menu::SettingsMenu,
|
||||||
|
texture_store::TextureStore,
|
||||||
|
top_menu::{smile::SmileyState, GUITop},
|
||||||
};
|
};
|
||||||
use macroquad::prelude::*;
|
use macroquad::prelude::*;
|
||||||
#[derive(Default, Copy, Clone, Debug)]
|
#[derive(Default, Copy, Clone, Debug)]
|
||||||
|
@ -16,6 +20,21 @@ pub enum Language {
|
||||||
English,
|
English,
|
||||||
Japanese,
|
Japanese,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum GUIEvent {
|
||||||
|
ClickReset,
|
||||||
|
OpenSettings,
|
||||||
|
CloseSettings,
|
||||||
|
SwitchLanguage(Language),
|
||||||
|
ClickTile(usize, usize),
|
||||||
|
ModifyTile(usize, usize),
|
||||||
|
HighlightTile(usize, usize),
|
||||||
|
UnHighlightTile(usize, usize),
|
||||||
|
CreateNewGame(usize, usize, usize),
|
||||||
|
SetQuestionMode(ModifyMode),
|
||||||
|
SetSmileyState(SmileyState),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct UIState {
|
pub struct UIState {
|
||||||
pub width: usize,
|
pub width: usize,
|
||||||
|
@ -85,7 +104,7 @@ impl UIState {
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct GameUI {
|
pub struct GameUI {
|
||||||
pub event_handler: GUIEvents,
|
pub event_handler: Events<GUIEvent>,
|
||||||
pub highlighter: Highlighter,
|
pub highlighter: Highlighter,
|
||||||
pub state: UIState,
|
pub state: UIState,
|
||||||
pub settings_menu: SettingsMenu,
|
pub settings_menu: SettingsMenu,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::logic::game_board::GameBoard;
|
use crate::{logic::game_board::GameBoard, util::Events};
|
||||||
use macroquad::prelude::*;
|
use macroquad::prelude::*;
|
||||||
|
|
||||||
use super::{texture_store::TextureStore, ui_event::GUIEvents, UIState};
|
use super::{texture_store::TextureStore, GUIEvent, UIState};
|
||||||
impl GameBoard {
|
impl GameBoard {
|
||||||
pub fn render(&self, textures: &TextureStore, settings: &UIState) {
|
pub fn render(&self, textures: &TextureStore, settings: &UIState) {
|
||||||
// dbg!(&settings.top_offset, &settings.render_scale);
|
// dbg!(&settings.top_offset, &settings.render_scale);
|
||||||
|
@ -32,13 +32,13 @@ impl GameBoard {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn events(&self, settings: &UIState, event_handler: &mut GUIEvents) {
|
pub fn events(&self, settings: &UIState, event_handler: &mut Events<GUIEvent>) {
|
||||||
if settings.mouse_in_minefield && !settings.frozen {
|
if settings.mouse_in_minefield && !settings.frozen {
|
||||||
if is_mouse_button_released(MouseButton::Left) {
|
if is_mouse_button_released(MouseButton::Left) {
|
||||||
event_handler.add(super::ui_event::GUIEvent::ClickTile(settings.cursor.0, settings.cursor.1))
|
event_handler.add(GUIEvent::ClickTile(settings.cursor.0, settings.cursor.1))
|
||||||
}
|
}
|
||||||
if is_mouse_button_released(MouseButton::Right) {
|
if is_mouse_button_released(MouseButton::Right) {
|
||||||
event_handler.add(super::ui_event::GUIEvent::ModifyTile(settings.cursor.0, settings.cursor.1))
|
event_handler.add(GUIEvent::ModifyTile(settings.cursor.0, settings.cursor.1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,11 @@ use crate::{
|
||||||
game_board::GameBoard,
|
game_board::GameBoard,
|
||||||
tile::{TileModifier, TileState},
|
tile::{TileModifier, TileState},
|
||||||
},
|
},
|
||||||
|
util::Events,
|
||||||
util::{ADJACENT_WITHOUT_CENTER, ADJACENT_WITH_CENTER},
|
util::{ADJACENT_WITHOUT_CENTER, ADJACENT_WITH_CENTER},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{top_menu::smile::SmileyState, ui_event::GUIEvent, ui_event::GUIEvents, UIState};
|
use super::{top_menu::smile::SmileyState, GUIEvent, UIState};
|
||||||
use macroquad::prelude::*;
|
use macroquad::prelude::*;
|
||||||
use std::default;
|
use std::default;
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ pub enum Highlight {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Highlighter {
|
impl Highlighter {
|
||||||
pub fn events(&mut self, ui_state: &UIState, event_handler: &mut GUIEvents, game_board: &mut GameBoard) {
|
pub fn events(&mut self, ui_state: &UIState, event_handler: &mut Events<GUIEvent>, game_board: &mut GameBoard) {
|
||||||
if !ui_state.frozen && ui_state.mouse_in_minefield {
|
if !ui_state.frozen && ui_state.mouse_in_minefield {
|
||||||
if is_mouse_button_pressed(MouseButton::Left) {
|
if is_mouse_button_pressed(MouseButton::Left) {
|
||||||
self.highlight = Highlight::Normal;
|
self.highlight = Highlight::Normal;
|
||||||
|
@ -49,7 +50,7 @@ impl Highlighter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn check_reveal(&self, event_handler: &mut GUIEvents, interface: &UIState, game_board: &mut GameBoard) {
|
fn check_reveal(&self, event_handler: &mut Events<GUIEvent>, interface: &UIState, game_board: &mut GameBoard) {
|
||||||
let (x, y) = interface.cursor;
|
let (x, y) = interface.cursor;
|
||||||
if let Some(tile) = game_board.get_tile_mut(x, y) {
|
if let Some(tile) = game_board.get_tile_mut(x, y) {
|
||||||
let adjacent_mines = tile.adjacent;
|
let adjacent_mines = tile.adjacent;
|
||||||
|
@ -87,7 +88,7 @@ impl Highlighter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn highlight(&mut self, interface: &UIState, event_handler: &mut GUIEvents) {
|
pub fn highlight(&mut self, interface: &UIState, event_handler: &mut Events<GUIEvent>) {
|
||||||
if interface.frozen {
|
if interface.frozen {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -119,7 +120,7 @@ impl Highlighter {
|
||||||
self.move_highlight(&interface, event_handler);
|
self.move_highlight(&interface, event_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_highlight(&mut self, interface: &UIState, event_handler: &mut GUIEvents) {
|
fn move_highlight(&mut self, interface: &UIState, event_handler: &mut Events<GUIEvent>) {
|
||||||
if let Some((old_x, old_y)) = self.cursor_old {
|
if let Some((old_x, old_y)) = self.cursor_old {
|
||||||
match self.highlight {
|
match self.highlight {
|
||||||
Highlight::None => (),
|
Highlight::None => (),
|
||||||
|
@ -165,7 +166,7 @@ impl Highlighter {
|
||||||
self.cursor_old = Some(interface.cursor);
|
self.cursor_old = Some(interface.cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_highlight(&mut self, interface: &UIState, event_handler: &mut GUIEvents) {
|
fn reset_highlight(&mut self, interface: &UIState, event_handler: &mut Events<GUIEvent>) {
|
||||||
if let Some((x, y)) = self.cursor_old {
|
if let Some((x, y)) = self.cursor_old {
|
||||||
match self.highlight {
|
match self.highlight {
|
||||||
Highlight::None => (),
|
Highlight::None => (),
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
use crate::logic::game_board::ModifyMode;
|
use crate::{logic::game_board::ModifyMode, util::Events};
|
||||||
|
|
||||||
use super::{
|
use super::{texture_store::TextureStore, GUIEvent, Language, UIState};
|
||||||
texture_store::TextureStore,
|
|
||||||
ui_event::{GUIEvent, GUIEvents},
|
|
||||||
Language, UIState,
|
|
||||||
};
|
|
||||||
use macroquad::{
|
use macroquad::{
|
||||||
hash,
|
hash,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
|
@ -32,7 +28,7 @@ impl SettingsMenu {
|
||||||
pub fn render(
|
pub fn render(
|
||||||
&mut self,
|
&mut self,
|
||||||
ui_state: &UIState,
|
ui_state: &UIState,
|
||||||
event_handler: &mut GUIEvents,
|
event_handler: &mut Events<GUIEvent>,
|
||||||
textures: &TextureStore,
|
textures: &TextureStore,
|
||||||
skin: &Skin,
|
skin: &Skin,
|
||||||
exit_button_skin: &Skin,
|
exit_button_skin: &Skin,
|
||||||
|
@ -53,7 +49,7 @@ impl SettingsMenu {
|
||||||
const MIN_MINEFIELD_WIDTH: usize = 5;
|
const MIN_MINEFIELD_WIDTH: usize = 5;
|
||||||
const MAX_MINEFIELD_WIDTH: usize = 100;
|
const MAX_MINEFIELD_WIDTH: usize = 100;
|
||||||
const MIN_MINEFIELD_HEIGHT: usize = 5;
|
const MIN_MINEFIELD_HEIGHT: usize = 5;
|
||||||
const MAX_MINEFIELD_HEIGHT: usize = 100;
|
// const MAX_MINEFIELD_HEIGHT: usize = 100;
|
||||||
render_counter(
|
render_counter(
|
||||||
&mut self.width,
|
&mut self.width,
|
||||||
ui,
|
ui,
|
||||||
|
|
|
@ -7,15 +7,11 @@ pub mod flag_counter;
|
||||||
pub mod smile;
|
pub mod smile;
|
||||||
pub mod timer;
|
pub mod timer;
|
||||||
|
|
||||||
use crate::logic::Minesweeper;
|
use crate::{gui::GUIEvent, logic::Minesweeper, util::Events};
|
||||||
|
|
||||||
use self::{flag_counter::GUIFlagCounter, smile::GUISmile, timer::GUITimer};
|
use self::{flag_counter::GUIFlagCounter, smile::GUISmile, timer::GUITimer};
|
||||||
|
|
||||||
use super::{
|
use super::{texture_store::TextureStore, UIState};
|
||||||
texture_store::TextureStore,
|
|
||||||
ui_event::{GUIEvent, GUIEvents},
|
|
||||||
UIState,
|
|
||||||
};
|
|
||||||
use macroquad::prelude::*;
|
use macroquad::prelude::*;
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct GUITop {
|
pub struct GUITop {
|
||||||
|
@ -29,7 +25,7 @@ impl GUITop {
|
||||||
&mut self,
|
&mut self,
|
||||||
ui_state: &UIState,
|
ui_state: &UIState,
|
||||||
game_logic: &Minesweeper,
|
game_logic: &Minesweeper,
|
||||||
event_handler: &mut GUIEvents,
|
event_handler: &mut Events<GUIEvent>,
|
||||||
textures: &TextureStore,
|
textures: &TextureStore,
|
||||||
) {
|
) {
|
||||||
let background_color = Color::from_rgba(192, 192, 192, 255);
|
let background_color = Color::from_rgba(192, 192, 192, 255);
|
||||||
|
|
|
@ -3,9 +3,9 @@ use macroquad::{
|
||||||
ui::{widgets, Ui},
|
ui::{widgets, Ui},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::gui::{
|
use crate::{
|
||||||
texture_store::TextureStore,
|
gui::{texture_store::TextureStore, GUIEvent},
|
||||||
ui_event::{GUIEvent, GUIEvents},
|
util::Events,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::UIState;
|
use super::UIState;
|
||||||
|
@ -34,7 +34,7 @@ const WIDTH: usize = 70;
|
||||||
const HEIGHT: usize = 70;
|
const HEIGHT: usize = 70;
|
||||||
|
|
||||||
impl GUISmile {
|
impl GUISmile {
|
||||||
pub fn render(&mut self, ui_state: &UIState, ui: &mut Ui, event_handler: &mut GUIEvents, textures: &TextureStore) {
|
pub fn render(&mut self, ui_state: &UIState, ui: &mut Ui, event_handler: &mut Events<GUIEvent>, textures: &TextureStore) {
|
||||||
let top_height = ui_state.top_offset;
|
let top_height = ui_state.top_offset;
|
||||||
let top_width = ui_state.width * ui_state.tile_size;
|
let top_width = ui_state.width * ui_state.tile_size;
|
||||||
let pos_x = (top_width - HEIGHT) / 2;
|
let pos_x = (top_width - HEIGHT) / 2;
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
use crate::logic::game_board::ModifyMode;
|
|
||||||
|
|
||||||
use super::{top_menu::smile::SmileyState, Language};
|
|
||||||
|
|
||||||
pub enum GUIEvent {
|
|
||||||
ClickReset,
|
|
||||||
OpenSettings,
|
|
||||||
CloseSettings,
|
|
||||||
SwitchLanguage(Language),
|
|
||||||
ClickTile(usize, usize),
|
|
||||||
ModifyTile(usize, usize),
|
|
||||||
HighlightTile(usize, usize),
|
|
||||||
UnHighlightTile(usize, usize),
|
|
||||||
CreateNewGame(usize, usize, usize),
|
|
||||||
SetQuestionMode(ModifyMode),
|
|
||||||
SetSmileyState(SmileyState),
|
|
||||||
}
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct GUIEvents {
|
|
||||||
events: Vec<GUIEvent>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GUIEvents {
|
|
||||||
pub fn add(&mut self, event: GUIEvent) {
|
|
||||||
self.events.push(event);
|
|
||||||
}
|
|
||||||
pub fn next(&mut self) -> Option<GUIEvent> {
|
|
||||||
if self.events.len() > 0 {
|
|
||||||
self.events.pop()
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn clear(&mut self) {
|
|
||||||
self.events.clear();
|
|
||||||
}
|
|
||||||
}
|
|
23
src/logic.rs
23
src/logic.rs
|
@ -1,11 +1,10 @@
|
||||||
pub mod events;
|
// pub mod events;
|
||||||
pub mod game_board;
|
pub mod game_board;
|
||||||
pub mod tile;
|
pub mod tile;
|
||||||
mod timer;
|
mod timer;
|
||||||
use self::{
|
use crate::util::Events;
|
||||||
events::{Events, GameEvent},
|
|
||||||
timer::Timer,
|
use self::{tile::Tile, timer::Timer};
|
||||||
};
|
|
||||||
use game_board::GameBoard;
|
use game_board::GameBoard;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
|
@ -17,13 +16,25 @@ pub enum GameState {
|
||||||
GameOver,
|
GameOver,
|
||||||
Victory,
|
Victory,
|
||||||
}
|
}
|
||||||
|
pub enum GameEvent {
|
||||||
|
Lose(usize, usize, Tile),
|
||||||
|
RevealTile(usize, usize, Tile),
|
||||||
|
FlagTile(usize, usize, Tile),
|
||||||
|
QuestionTile(usize, usize, Tile),
|
||||||
|
SweepDone,
|
||||||
|
SweepBegin,
|
||||||
|
InitDone,
|
||||||
|
Win,
|
||||||
|
Reset,
|
||||||
|
GameEnd(GameBoard),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Minesweeper {
|
pub struct Minesweeper {
|
||||||
pub board: GameBoard,
|
pub board: GameBoard,
|
||||||
|
pub events: Events<GameEvent>,
|
||||||
pub state: GameState,
|
pub state: GameState,
|
||||||
timer: Timer,
|
timer: Timer,
|
||||||
pub events: Events,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Minesweeper {
|
impl Minesweeper {
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
use super::game_board::GameBoard;
|
|
||||||
use super::tile::Tile;
|
|
||||||
pub enum GameEvent {
|
|
||||||
Lose(usize, usize, Tile),
|
|
||||||
RevealTile(usize, usize, Tile),
|
|
||||||
FlagTile(usize, usize, Tile),
|
|
||||||
QuestionTile(usize, usize, Tile),
|
|
||||||
SweepDone,
|
|
||||||
SweepBegin,
|
|
||||||
InitDone,
|
|
||||||
Win,
|
|
||||||
Reset,
|
|
||||||
GameEnd(GameBoard),
|
|
||||||
}
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct Events {
|
|
||||||
events: Vec<GameEvent>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Events {
|
|
||||||
pub fn add(&mut self, event: GameEvent) {
|
|
||||||
self.events.push(event);
|
|
||||||
}
|
|
||||||
pub fn next(&mut self) -> Option<GameEvent> {
|
|
||||||
if self.events.len() > 0 {
|
|
||||||
self.events.pop()
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn clear(&mut self) {
|
|
||||||
self.events.clear();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -98,7 +98,7 @@ impl GameBoard {
|
||||||
self.mines as isize - self.flags as isize
|
self.mines as isize - self.flags as isize
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn modify(&mut self, x: usize, y: usize, event_handler: &mut Events) {
|
pub fn modify(&mut self, x: usize, y: usize, event_handler: &mut Events<GameEvent>) {
|
||||||
if let Some(&tile) = &self.get_tile(x, y) {
|
if let Some(&tile) = &self.get_tile(x, y) {
|
||||||
if tile.swept {
|
if tile.swept {
|
||||||
return;
|
return;
|
||||||
|
@ -132,7 +132,7 @@ impl GameBoard {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sweep(&mut self, x: usize, y: usize, event_handler: &mut Events) -> Option<GameState> {
|
pub fn sweep(&mut self, x: usize, y: usize, event_handler: &mut Events<GameEvent>) -> Option<GameState> {
|
||||||
if let BoardState::Ungenerated = self.state {
|
if let BoardState::Ungenerated = self.state {
|
||||||
self.generate(x, y);
|
self.generate(x, y);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use gui::top_menu::smile::SmileyState;
|
use gui::top_menu::smile::SmileyState;
|
||||||
use gui::ui_event::*;
|
use gui::{GUIEvent, GameUI, UIState};
|
||||||
use gui::{GameUI, UIState};
|
use logic::{GameEvent, Minesweeper};
|
||||||
use logic::{events::GameEvent, Minesweeper};
|
|
||||||
use macroquad::{
|
use macroquad::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
ui::{root_ui, Skin},
|
ui::{root_ui, Skin},
|
||||||
|
|
29
src/util.rs
29
src/util.rs
|
@ -2,3 +2,32 @@ pub const ADJACENT_WITH_CENTER: [(isize, isize); 9] =
|
||||||
[(-1, -1), (0, -1), (1, -1), (-1, 0), (0, 0), (1, 0), (-1, 1), (0, 1), (1, 1)];
|
[(-1, -1), (0, -1), (1, -1), (-1, 0), (0, 0), (1, 0), (-1, 1), (0, 1), (1, 1)];
|
||||||
|
|
||||||
pub const ADJACENT_WITHOUT_CENTER: [(isize, isize); 8] = [(-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1)];
|
pub const ADJACENT_WITHOUT_CENTER: [(isize, isize); 8] = [(-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1)];
|
||||||
|
|
||||||
|
// Event Queue
|
||||||
|
pub struct Events<E> {
|
||||||
|
events: Vec<E>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E> Events<E> {
|
||||||
|
pub fn add(&mut self, event: E) {
|
||||||
|
self.events.push(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next(&mut self) -> Option<E> {
|
||||||
|
if self.events.len() > 0 {
|
||||||
|
self.events.pop()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn clear(&mut self) {
|
||||||
|
self.events.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<E> Default for Events<E> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
events: Vec::<E>::with_capacity(10),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue