summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2019-07-23 10:49:24 +0200
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2019-07-23 10:49:24 +0200
commite55ac637a9c4422b2fccfcc56c25449160e56e02 (patch)
treedabc064bf3668d3a3fb9f9e1e6ad30051ea2a522 /src
parenteb45c51a7b8b9a595e318048712362c8d65d77b3 (diff)
downloadiced-e55ac637a9c4422b2fccfcc56c25449160e56e02.tar.gz
iced-e55ac637a9c4422b2fccfcc56c25449160e56e02.tar.bz2
iced-e55ac637a9c4422b2fccfcc56c25449160e56e02.zip
Add `Runtime` concept to abstract caching
Diffstat (limited to 'src')
-rw-r--r--src/interface.rs77
-rw-r--r--src/layout.rs19
-rw-r--r--src/lib.rs4
-rw-r--r--src/runtime.rs103
4 files changed, 118 insertions, 85 deletions
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
+ }
+}