summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/ggez/main.rs9
-rw-r--r--src/interface.rs77
-rw-r--r--src/layout.rs19
-rw-r--r--src/lib.rs4
-rw-r--r--src/runtime.rs103
5 files changed, 123 insertions, 89 deletions
diff --git a/examples/ggez/main.rs b/examples/ggez/main.rs
index 770f79b1..f6d82ad1 100644
--- a/examples/ggez/main.rs
+++ b/examples/ggez/main.rs
@@ -9,8 +9,6 @@ use ggez::event;
use ggez::graphics;
use ggez::input::mouse;
-use iced::Interface;
-
pub fn main() -> ggez::GameResult {
let cb = ggez::ContextBuilder::new("iced", "ggez");
let (ctx, event_loop) = &mut cb.build()?;
@@ -20,6 +18,8 @@ pub fn main() -> ggez::GameResult {
struct Game {
spritesheet: graphics::Image,
+
+ runtime: iced::Runtime,
button: button::State,
}
@@ -27,6 +27,8 @@ impl Game {
fn new(context: &mut ggez::Context) -> ggez::GameResult<Game> {
Ok(Game {
spritesheet: graphics::Image::new(context, "/ui.png").unwrap(),
+
+ runtime: iced::Runtime::new(),
button: button::State::new(),
})
}
@@ -69,8 +71,7 @@ impl event::EventHandler for Game {
let renderer =
&mut Renderer::new(context, self.spritesheet.clone());
- let ui: Interface<Message, Renderer> =
- Interface::compute(content.into(), renderer);
+ let ui = self.runtime.compute(content.into(), renderer);
let cursor = ui.draw(renderer, iced::Point::new(0.0, 0.0));
diff --git a/src/interface.rs b/src/interface.rs
deleted file mode 100644
index 6c4982e5..00000000
--- a/src/interface.rs
+++ /dev/null
@@ -1,77 +0,0 @@
-use std::hash::Hasher;
-use stretch::result;
-
-use crate::{Element, Event, Layout, MouseCursor, Point};
-
-pub struct Interface<'a, Message, Renderer> {
- hash: u64,
- root: Element<'a, Message, Renderer>,
- layout: result::Layout,
-}
-
-pub struct Cache {
- hash: u64,
- layout: result::Layout,
-}
-
-impl<'a, Message, Renderer> Interface<'a, Message, Renderer> {
- pub fn compute(
- root: Element<'a, Message, Renderer>,
- renderer: &Renderer,
- ) -> Interface<'a, Message, Renderer> {
- let hasher = &mut crate::Hasher::default();
- root.hash(hasher);
-
- let hash = hasher.finish();
- let layout = root.compute_layout(renderer);
-
- Interface { hash, root, layout }
- }
-
- pub fn compute_with_cache(
- root: Element<'a, Message, Renderer>,
- renderer: &Renderer,
- cache: Cache,
- ) -> Interface<'a, Message, Renderer> {
- 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)
- };
-
- Interface { hash, root, layout }
- }
-
- pub fn on_event(&mut self, event: Event, cursor_position: Point, messages: &mut Vec<Message>) {
- let Interface { root, layout, .. } = self;
-
- root.widget
- .on_event(event, Self::layout(layout), cursor_position, messages);
- }
-
- pub fn draw(&self, renderer: &mut Renderer, cursor_position: Point) -> MouseCursor {
- let Interface { root, layout, .. } = self;
-
- let cursor = root
- .widget
- .draw(renderer, Self::layout(layout), cursor_position);
-
- cursor
- }
-
- pub fn cache(self) -> Cache {
- Cache {
- hash: self.hash,
- layout: self.layout,
- }
- }
-
- fn layout(layout: &result::Layout) -> Layout<'_> {
- Layout::new(layout, Point::new(0.0, 0.0))
- }
-}
diff --git a/src/layout.rs b/src/layout.rs
index 011f859a..481b4166 100644
--- a/src/layout.rs
+++ b/src/layout.rs
@@ -19,8 +19,16 @@ pub struct Layout<'a> {
}
impl<'a> Layout<'a> {
- pub(crate) fn new(layout: &'a result::Layout, parent_position: Point) -> Self {
- let position = parent_position + Vector::new(layout.location.x, layout.location.y);
+ pub(crate) fn new(layout: &'a result::Layout) -> Self {
+ Self::with_parent_position(layout, Point::new(0.0, 0.0))
+ }
+
+ fn with_parent_position(
+ layout: &'a result::Layout,
+ parent_position: Point,
+ ) -> Self {
+ let position =
+ parent_position + Vector::new(layout.location.x, layout.location.y);
Layout { layout, position }
}
@@ -47,9 +55,8 @@ impl<'a> Layout<'a> {
/// [`Layout`]: struct.Layout.html
/// [`Node`]: struct.Node.html
pub fn children(&'a self) -> impl Iterator<Item = Layout<'a>> {
- self.layout
- .children
- .iter()
- .map(move |layout| Layout::new(layout, self.position))
+ self.layout.children.iter().map(move |layout| {
+ Layout::with_parent_position(layout, self.position)
+ })
}
}
diff --git a/src/lib.rs b/src/lib.rs
index 9c7eed8d..6ea3e60d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -9,13 +9,13 @@ pub mod widget;
mod element;
mod event;
mod hasher;
-mod interface;
mod layout;
mod mouse_cursor;
mod node;
mod point;
mod rectangle;
mod renderer;
+mod runtime;
mod style;
mod vector;
@@ -25,13 +25,13 @@ pub use stretch::{geometry::Size, number::Number};
pub use element::Element;
pub use event::Event;
pub use hasher::Hasher;
-pub use interface::Interface;
pub use layout::Layout;
pub use mouse_cursor::MouseCursor;
pub use node::Node;
pub use point::Point;
pub use rectangle::Rectangle;
pub use renderer::Renderer;
+pub use runtime::{Interface, Runtime};
pub use style::{Align, Justify, Style};
pub use vector::Vector;
pub use widget::*;
diff --git a/src/runtime.rs b/src/runtime.rs
new file mode 100644
index 00000000..f8a5aaa3
--- /dev/null
+++ b/src/runtime.rs
@@ -0,0 +1,103 @@
+use crate::{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) {
+ 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,
+ cursor_position: Point,
+ ) -> MouseCursor {
+ let cursor = self.root.widget.draw(
+ renderer,
+ Layout::new(self.layout),
+ cursor_position,
+ );
+
+ cursor
+ }
+}