|
|
|
@ -1,17 +1,73 @@ |
|
|
|
|
use ggez::{ |
|
|
|
|
event::{EventHandler, KeyCode, KeyMods, MouseButton}, |
|
|
|
|
Context, GameResult, |
|
|
|
|
graphics, Context, GameResult, |
|
|
|
|
}; |
|
|
|
|
use std::collections::BTreeMap; |
|
|
|
|
use std::sync::{ |
|
|
|
|
atomic::{AtomicUsize, Ordering}, |
|
|
|
|
mpsc::{channel, Receiver, Sender}, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static ID_CTR: AtomicUsize = AtomicUsize::new(0); |
|
|
|
|
|
|
|
|
|
static mut tx: Option<Sender<HandlerDiff>> = None; |
|
|
|
|
static mut rx: Option<Receiver<HandlerDiff>> = None; |
|
|
|
|
|
|
|
|
|
#[inline(always)] |
|
|
|
|
pub fn get_tx() -> Sender<HandlerDiff> { |
|
|
|
|
unsafe { tx.as_ref() }.expect("Call event::setup() first!").clone() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Must absolutely call this function before using the event system!
|
|
|
|
|
pub fn setup() { |
|
|
|
|
let (tx_, rx_) = channel(); |
|
|
|
|
unsafe { tx = Some(tx_) }; |
|
|
|
|
unsafe { rx = Some(rx_) }; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub struct EventLayer<L: EventHandler> { |
|
|
|
|
layers: Vec<Box<dyn EventHandler>>, |
|
|
|
|
pub type EventId = usize; |
|
|
|
|
|
|
|
|
|
pub fn new_id() -> EventId { |
|
|
|
|
ID_CTR.fetch_add(1, Ordering::Relaxed) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub type BoxedHandler = Box<dyn EventHandler + 'static>; |
|
|
|
|
|
|
|
|
|
pub enum HandlerDiff { |
|
|
|
|
Add { id: usize, inner: BoxedHandler }, |
|
|
|
|
Remove(usize), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl HandlerDiff { |
|
|
|
|
pub fn add(inner: impl EventHandler + 'static) -> (usize, Self) { |
|
|
|
|
let id = new_id(); |
|
|
|
|
( |
|
|
|
|
id, |
|
|
|
|
Self::Add { |
|
|
|
|
id, |
|
|
|
|
inner: Box::new(inner), |
|
|
|
|
}, |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub fn remove(id: usize) -> Self { |
|
|
|
|
Self::Remove(id) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub struct EventLayer<L> { |
|
|
|
|
layers: BTreeMap<usize, BoxedHandler>, |
|
|
|
|
layer_rx: Receiver<HandlerDiff>, |
|
|
|
|
render: L, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl<L: EventHandler> EventLayer<L> { |
|
|
|
|
pub fn new(render: L) -> Self { |
|
|
|
|
let layer_rx = unsafe { rx.take().expect("Call event::setup() first!") }; |
|
|
|
|
|
|
|
|
|
Self { |
|
|
|
|
layers: vec![], |
|
|
|
|
layers: BTreeMap::new(), |
|
|
|
|
layer_rx, |
|
|
|
|
render, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -19,38 +75,59 @@ impl<L: EventHandler> EventLayer<L> { |
|
|
|
|
|
|
|
|
|
impl<L: EventHandler> EventHandler for EventLayer<L> { |
|
|
|
|
fn update(&mut self, ctx: &mut Context) -> GameResult<()> { |
|
|
|
|
// Add all new layers to the update stack
|
|
|
|
|
while let Ok(l) = self.layer_rx.try_recv() { |
|
|
|
|
match l { |
|
|
|
|
HandlerDiff::Add { id, inner } => { |
|
|
|
|
self.layers.insert(id, inner); |
|
|
|
|
} |
|
|
|
|
HandlerDiff::Remove(ref id) => { |
|
|
|
|
self.layers.remove(id); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Then update all the layers
|
|
|
|
|
self.layers |
|
|
|
|
.iter_mut() |
|
|
|
|
.map(|l| l.update(ctx)) |
|
|
|
|
.map(|(_, l)| l.update(ctx)) |
|
|
|
|
.collect::<GameResult<Vec<()>>>()?; |
|
|
|
|
|
|
|
|
|
// Update the renderer last
|
|
|
|
|
self.render.update(ctx)?; |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn draw(&mut self, ctx: &mut Context) -> GameResult<()> { |
|
|
|
|
graphics::clear(ctx, graphics::Color::from_rgb(15, 15, 15)); |
|
|
|
|
self.render.draw(ctx)?; |
|
|
|
|
Ok(()) |
|
|
|
|
|
|
|
|
|
self.layers |
|
|
|
|
.iter_mut() |
|
|
|
|
.map(|(_, l)| l.draw(ctx)) |
|
|
|
|
.collect::<Vec<_>>(); |
|
|
|
|
|
|
|
|
|
graphics::present(ctx) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn mouse_button_down_event(&mut self, ctx: &mut Context, button: MouseButton, x: f32, y: f32) { |
|
|
|
|
self.layers |
|
|
|
|
.iter_mut() |
|
|
|
|
.map(|l| l.mouse_button_down_event(ctx, button, x, y)) |
|
|
|
|
.map(|(_, l)| l.mouse_button_down_event(ctx, button, x, y)) |
|
|
|
|
.collect::<Vec<_>>(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn mouse_button_up_event(&mut self, ctx: &mut Context, button: MouseButton, x: f32, y: f32) { |
|
|
|
|
self.layers |
|
|
|
|
.iter_mut() |
|
|
|
|
.map(|l| l.mouse_button_up_event(ctx, button, x, y)) |
|
|
|
|
.map(|(_, l)| l.mouse_button_up_event(ctx, button, x, y)) |
|
|
|
|
.collect::<Vec<_>>(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn mouse_motion_event(&mut self, ctx: &mut Context, x: f32, y: f32, dx: f32, dy: f32) { |
|
|
|
|
self.layers |
|
|
|
|
.iter_mut() |
|
|
|
|
.map(|l| l.mouse_motion_event(ctx, x, y, dx, dy)) |
|
|
|
|
.map(|(_, l)| l.mouse_motion_event(ctx, x, y, dx, dy)) |
|
|
|
|
.collect::<Vec<_>>(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -69,7 +146,7 @@ impl<L: EventHandler> EventHandler for EventLayer<L> { |
|
|
|
|
) { |
|
|
|
|
self.layers |
|
|
|
|
.iter_mut() |
|
|
|
|
.map(|l| l.key_down_event(ctx, keycode, keymods, repeat)) |
|
|
|
|
.map(|(_, l)| l.key_down_event(ctx, keycode, keymods, repeat)) |
|
|
|
|
.collect::<Vec<_>>(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -77,7 +154,7 @@ impl<L: EventHandler> EventHandler for EventLayer<L> { |
|
|
|
|
fn key_up_event(&mut self, ctx: &mut Context, keycode: KeyCode, keymods: KeyMods) { |
|
|
|
|
self.layers |
|
|
|
|
.iter_mut() |
|
|
|
|
.map(|l| l.key_up_event(ctx, keycode, keymods)) |
|
|
|
|
.map(|(_, l)| l.key_up_event(ctx, keycode, keymods)) |
|
|
|
|
.collect::<Vec<_>>(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -86,7 +163,7 @@ impl<L: EventHandler> EventHandler for EventLayer<L> { |
|
|
|
|
fn text_input_event(&mut self, ctx: &mut Context, character: char) { |
|
|
|
|
self.layers |
|
|
|
|
.iter_mut() |
|
|
|
|
.map(|l| l.text_input_event(ctx, character)) |
|
|
|
|
.map(|(_, l)| l.text_input_event(ctx, character)) |
|
|
|
|
.collect::<Vec<_>>(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|