diff options
author | 2019-07-23 10:49:24 +0200 | |
---|---|---|
committer | 2019-07-23 10:49:24 +0200 | |
commit | e55ac637a9c4422b2fccfcc56c25449160e56e02 (patch) | |
tree | dabc064bf3668d3a3fb9f9e1e6ad30051ea2a522 /src/runtime.rs | |
parent | eb45c51a7b8b9a595e318048712362c8d65d77b3 (diff) | |
download | iced-e55ac637a9c4422b2fccfcc56c25449160e56e02.tar.gz iced-e55ac637a9c4422b2fccfcc56c25449160e56e02.tar.bz2 iced-e55ac637a9c4422b2fccfcc56c25449160e56e02.zip |
Add `Runtime` concept to abstract caching
Diffstat (limited to '')
-rw-r--r-- | src/runtime.rs | 103 |
1 files changed, 103 insertions, 0 deletions
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 + } +} |