Remove Runtime and expose Cache instead
This commit is contained in:
parent
10b07b8028
commit
ec66e3fc1b
4 changed files with 135 additions and 117 deletions
|
|
@ -27,7 +27,8 @@ pub fn main() -> ggez::GameResult {
|
||||||
struct Game {
|
struct Game {
|
||||||
spritesheet: graphics::Image,
|
spritesheet: graphics::Image,
|
||||||
|
|
||||||
runtime: iced::Runtime,
|
cache: Option<iced::Cache>,
|
||||||
|
events: Vec<iced::Event>,
|
||||||
tour: Tour,
|
tour: Tour,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -38,7 +39,8 @@ impl Game {
|
||||||
Ok(Game {
|
Ok(Game {
|
||||||
spritesheet: graphics::Image::new(context, "/ui.png").unwrap(),
|
spritesheet: graphics::Image::new(context, "/ui.png").unwrap(),
|
||||||
|
|
||||||
runtime: iced::Runtime::new(),
|
cache: Some(iced::Cache::default()),
|
||||||
|
events: Vec::new(),
|
||||||
tour: Tour::new(),
|
tour: Tour::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -52,11 +54,11 @@ impl event::EventHandler for Game {
|
||||||
fn mouse_button_down_event(
|
fn mouse_button_down_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
_context: &mut ggez::Context,
|
_context: &mut ggez::Context,
|
||||||
button: mouse::MouseButton,
|
_button: mouse::MouseButton,
|
||||||
_x: f32,
|
_x: f32,
|
||||||
_y: f32,
|
_y: f32,
|
||||||
) {
|
) {
|
||||||
self.runtime.on_event(iced::Event::Mouse(
|
self.events.push(iced::Event::Mouse(
|
||||||
iced::input::mouse::Event::Input {
|
iced::input::mouse::Event::Input {
|
||||||
state: iced::input::ButtonState::Pressed,
|
state: iced::input::ButtonState::Pressed,
|
||||||
button: iced::input::mouse::Button::Left, // TODO: Map `button`
|
button: iced::input::mouse::Button::Left, // TODO: Map `button`
|
||||||
|
|
@ -67,11 +69,11 @@ impl event::EventHandler for Game {
|
||||||
fn mouse_button_up_event(
|
fn mouse_button_up_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
_context: &mut ggez::Context,
|
_context: &mut ggez::Context,
|
||||||
button: mouse::MouseButton,
|
_button: mouse::MouseButton,
|
||||||
_x: f32,
|
_x: f32,
|
||||||
_y: f32,
|
_y: f32,
|
||||||
) {
|
) {
|
||||||
self.runtime.on_event(iced::Event::Mouse(
|
self.events.push(iced::Event::Mouse(
|
||||||
iced::input::mouse::Event::Input {
|
iced::input::mouse::Event::Input {
|
||||||
state: iced::input::ButtonState::Released,
|
state: iced::input::ButtonState::Released,
|
||||||
button: iced::input::mouse::Button::Left, // TODO: Map `button`
|
button: iced::input::mouse::Button::Left, // TODO: Map `button`
|
||||||
|
|
@ -87,7 +89,7 @@ impl event::EventHandler for Game {
|
||||||
_dx: f32,
|
_dx: f32,
|
||||||
_dy: f32,
|
_dy: f32,
|
||||||
) {
|
) {
|
||||||
self.runtime.on_event(iced::Event::Mouse(
|
self.events.push(iced::Event::Mouse(
|
||||||
iced::input::mouse::Event::CursorMoved { x, y },
|
iced::input::mouse::Event::CursorMoved { x, y },
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
@ -130,11 +132,17 @@ impl event::EventHandler for Game {
|
||||||
let renderer =
|
let renderer =
|
||||||
&mut Renderer::new(context, self.spritesheet.clone());
|
&mut Renderer::new(context, self.spritesheet.clone());
|
||||||
|
|
||||||
let mut ui = self.runtime.compute(content.into(), renderer);
|
let mut ui = iced::UserInterface::build(
|
||||||
|
content.into(),
|
||||||
|
renderer,
|
||||||
|
self.cache.take().unwrap(),
|
||||||
|
);
|
||||||
|
|
||||||
let messages = ui.update();
|
let messages = ui.update(self.events.drain(..));
|
||||||
let cursor = ui.draw(renderer);
|
let cursor = ui.draw(renderer);
|
||||||
|
|
||||||
|
self.cache = Some(ui.into_cache());
|
||||||
|
|
||||||
renderer.flush();
|
renderer.flush();
|
||||||
|
|
||||||
(messages, cursor)
|
(messages, cursor)
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,8 @@ mod node;
|
||||||
mod point;
|
mod point;
|
||||||
mod rectangle;
|
mod rectangle;
|
||||||
mod renderer;
|
mod renderer;
|
||||||
mod runtime;
|
|
||||||
mod style;
|
mod style;
|
||||||
|
mod user_interface;
|
||||||
mod vector;
|
mod vector;
|
||||||
|
|
||||||
#[doc(no_inline)]
|
#[doc(no_inline)]
|
||||||
|
|
@ -31,7 +31,7 @@ pub use node::Node;
|
||||||
pub use point::Point;
|
pub use point::Point;
|
||||||
pub use rectangle::Rectangle;
|
pub use rectangle::Rectangle;
|
||||||
pub use renderer::Renderer;
|
pub use renderer::Renderer;
|
||||||
pub use runtime::{Interface, Runtime};
|
|
||||||
pub use style::{Align, Justify, Style};
|
pub use style::{Align, Justify, Style};
|
||||||
|
pub use user_interface::{Cache, UserInterface};
|
||||||
pub use vector::Vector;
|
pub use vector::Vector;
|
||||||
pub use widget::*;
|
pub use widget::*;
|
||||||
|
|
|
||||||
106
src/runtime.rs
106
src/runtime.rs
|
|
@ -1,106 +0,0 @@
|
||||||
use crate::{input::mouse, Column, Element, Event, Layout, MouseCursor, Point};
|
|
||||||
|
|
||||||
use std::hash::Hasher;
|
|
||||||
use stretch::result;
|
|
||||||
|
|
||||||
pub struct Runtime {
|
|
||||||
cache: Cache,
|
|
||||||
events: Vec<Event>,
|
|
||||||
cursor_position: Point,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Runtime {
|
|
||||||
pub fn new() -> Runtime {
|
|
||||||
// We use this as a placeholder to initialize the cache.
|
|
||||||
// This way, we can avoid the overhead of using an `Option`
|
|
||||||
// in `compute`.
|
|
||||||
let root: Element<'_, (), ()> = Column::new().into();
|
|
||||||
|
|
||||||
let hasher = &mut crate::Hasher::default();
|
|
||||||
root.hash(hasher);
|
|
||||||
|
|
||||||
Runtime {
|
|
||||||
cache: Cache {
|
|
||||||
hash: hasher.finish(),
|
|
||||||
layout: root.compute_layout(&()),
|
|
||||||
},
|
|
||||||
events: Vec::new(),
|
|
||||||
cursor_position: Point::new(0.0, 0.0),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn on_event(&mut self, event: Event) {
|
|
||||||
match event {
|
|
||||||
Event::Mouse(mouse::Event::CursorMoved { x, y }) => {
|
|
||||||
self.cursor_position = Point::new(x, y);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.events.push(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn compute<'a, Message, Renderer>(
|
|
||||||
&'a mut self,
|
|
||||||
root: Element<'a, Message, Renderer>,
|
|
||||||
renderer: &Renderer,
|
|
||||||
) -> Interface<'a, Message, Renderer> {
|
|
||||||
let hasher = &mut crate::Hasher::default();
|
|
||||||
root.hash(hasher);
|
|
||||||
|
|
||||||
let hash = hasher.finish();
|
|
||||||
|
|
||||||
if hash != self.cache.hash {
|
|
||||||
self.cache = Cache {
|
|
||||||
hash,
|
|
||||||
layout: root.compute_layout(renderer),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Interface {
|
|
||||||
root,
|
|
||||||
layout: &self.cache.layout,
|
|
||||||
events: &mut self.events,
|
|
||||||
cursor_position: self.cursor_position,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Cache {
|
|
||||||
hash: u64,
|
|
||||||
layout: result::Layout,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Interface<'a, Message, Renderer> {
|
|
||||||
root: Element<'a, Message, Renderer>,
|
|
||||||
layout: &'a result::Layout,
|
|
||||||
events: &'a mut Vec<Event>,
|
|
||||||
cursor_position: Point,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, Message, Renderer> Interface<'a, Message, Renderer> {
|
|
||||||
pub fn update(&mut self) -> Vec<Message> {
|
|
||||||
let mut messages = Vec::new();
|
|
||||||
|
|
||||||
for event in self.events.drain(..) {
|
|
||||||
self.root.widget.on_event(
|
|
||||||
event,
|
|
||||||
Layout::new(&self.layout),
|
|
||||||
self.cursor_position,
|
|
||||||
&mut messages,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
messages
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn draw(&self, renderer: &mut Renderer) -> MouseCursor {
|
|
||||||
let cursor = self.root.widget.draw(
|
|
||||||
renderer,
|
|
||||||
Layout::new(self.layout),
|
|
||||||
self.cursor_position,
|
|
||||||
);
|
|
||||||
|
|
||||||
cursor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
116
src/user_interface.rs
Normal file
116
src/user_interface.rs
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
use crate::{input::mouse, Column, Element, Event, Layout, MouseCursor, Point};
|
||||||
|
|
||||||
|
use std::hash::Hasher;
|
||||||
|
use stretch::result;
|
||||||
|
|
||||||
|
pub struct UserInterface<'a, Message, Renderer> {
|
||||||
|
hash: u64,
|
||||||
|
root: Element<'a, Message, Renderer>,
|
||||||
|
layout: result::Layout,
|
||||||
|
cursor_position: Point,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Message, Renderer> UserInterface<'a, Message, Renderer> {
|
||||||
|
pub fn build(
|
||||||
|
root: Element<'a, Message, Renderer>,
|
||||||
|
renderer: &Renderer,
|
||||||
|
cache: Cache,
|
||||||
|
) -> Self {
|
||||||
|
let hasher = &mut crate::Hasher::default();
|
||||||
|
root.hash(hasher);
|
||||||
|
|
||||||
|
let hash = hasher.finish();
|
||||||
|
|
||||||
|
let layout = if hash == cache.hash {
|
||||||
|
cache.layout
|
||||||
|
} else {
|
||||||
|
root.compute_layout(renderer)
|
||||||
|
};
|
||||||
|
|
||||||
|
UserInterface {
|
||||||
|
hash,
|
||||||
|
root,
|
||||||
|
layout,
|
||||||
|
cursor_position: cache.cursor_position,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(
|
||||||
|
&mut self,
|
||||||
|
events: std::vec::Drain<'_, Event>,
|
||||||
|
) -> Vec<Message> {
|
||||||
|
let mut messages = Vec::new();
|
||||||
|
|
||||||
|
for event in events {
|
||||||
|
match event {
|
||||||
|
Event::Mouse(mouse::Event::CursorMoved { x, y }) => {
|
||||||
|
self.cursor_position = Point::new(x, y);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.root.widget.on_event(
|
||||||
|
event,
|
||||||
|
Layout::new(&self.layout),
|
||||||
|
self.cursor_position,
|
||||||
|
&mut messages,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
messages
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw(&self, renderer: &mut Renderer) -> MouseCursor {
|
||||||
|
let cursor = self.root.widget.draw(
|
||||||
|
renderer,
|
||||||
|
Layout::new(&self.layout),
|
||||||
|
self.cursor_position,
|
||||||
|
);
|
||||||
|
|
||||||
|
cursor
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_cache(self) -> Cache {
|
||||||
|
Cache {
|
||||||
|
hash: self.hash,
|
||||||
|
layout: self.layout,
|
||||||
|
cursor_position: self.cursor_position,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Cache {
|
||||||
|
hash: u64,
|
||||||
|
layout: result::Layout,
|
||||||
|
cursor_position: Point,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Cache {
|
||||||
|
pub fn new() -> Cache {
|
||||||
|
let root: Element<'_, (), ()> = Column::new().into();
|
||||||
|
|
||||||
|
let hasher = &mut crate::Hasher::default();
|
||||||
|
root.hash(hasher);
|
||||||
|
|
||||||
|
Cache {
|
||||||
|
hash: hasher.finish(),
|
||||||
|
layout: root.compute_layout(&()),
|
||||||
|
cursor_position: Point::new(0.0, 0.0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Cache {
|
||||||
|
fn default() -> Cache {
|
||||||
|
Cache::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for Cache {
|
||||||
|
fn eq(&self, other: &Cache) -> bool {
|
||||||
|
self.hash == other.hash && self.cursor_position == other.cursor_position
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for Cache {}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue