diff options
Diffstat (limited to '')
| -rw-r--r-- | examples/ggez/main.rs | 9 | ||||
| -rw-r--r-- | src/interface.rs | 77 | ||||
| -rw-r--r-- | src/layout.rs | 19 | ||||
| -rw-r--r-- | src/lib.rs | 4 | ||||
| -rw-r--r-- | src/runtime.rs | 103 | 
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) +        })      }  } @@ -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 +    } +} | 
