From 33d80b5a0b8b5b2837c99be2a152bdeb73ca60c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 12 Nov 2020 02:00:08 +0100 Subject: [PATCH] Return `event::Status` in `UserInterface::update` --- glutin/src/application.rs | 39 ++++++++------- native/src/program/state.rs | 20 +++++--- native/src/user_interface.rs | 97 +++++++++++++++++++----------------- winit/src/application.rs | 43 ++++++++-------- 4 files changed, 107 insertions(+), 92 deletions(-) diff --git a/glutin/src/application.rs b/glutin/src/application.rs index 68612978..bc590912 100644 --- a/glutin/src/application.rs +++ b/glutin/src/application.rs @@ -155,30 +155,23 @@ async fn run_instance( user_interface.draw(&mut renderer, state.cursor_position()); let mut mouse_interaction = mouse::Interaction::default(); - let mut events = Vec::new(); - let mut external_messages = Vec::new(); + let mut messages = Vec::new(); + let mut is_clean = true; debug.startup_finished(); while let Some(event) = receiver.next().await { match event { + event::Event::NewEvents(_) => { + debug.event_processing_started(); + } event::Event::MainEventsCleared => { - if events.is_empty() && external_messages.is_empty() { + debug.event_processing_finished(); + + if is_clean && messages.is_empty() { continue; } - debug.event_processing_started(); - let mut messages = user_interface.update( - &events, - state.cursor_position(), - clipboard.as_ref().map(|c| c as _), - &mut renderer, - ); - - messages.extend(external_messages.drain(..)); - events.clear(); - debug.event_processing_finished(); - if !messages.is_empty() { let cache = ManuallyDrop::into_inner(user_interface).into_cache(); @@ -188,7 +181,7 @@ async fn run_instance( &mut application, &mut runtime, &mut debug, - messages, + &mut messages, ); // Update window @@ -210,9 +203,10 @@ async fn run_instance( debug.draw_finished(); context.window().request_redraw(); + is_clean = true; } event::Event::UserEvent(message) => { - external_messages.push(message); + messages.push(message); } event::Event::RedrawRequested(_) => { debug.render_started(); @@ -283,8 +277,17 @@ async fn run_instance( state.scale_factor(), state.modifiers(), ) { - events.push(event.clone()); + let _ = user_interface.update( + event.clone(), + state.cursor_position(), + clipboard.as_ref().map(|c| c as _), + &mut renderer, + &mut messages, + ); + runtime.broadcast(event); + + is_clean = false; } } _ => {} diff --git a/native/src/program/state.rs b/native/src/program/state.rs index 95e6b60c..5557347b 100644 --- a/native/src/program/state.rs +++ b/native/src/program/state.rs @@ -120,15 +120,19 @@ where ); debug.event_processing_started(); - let mut messages = user_interface.update( - &self.queued_events, - cursor_position, - clipboard, - renderer, - ); - messages.extend(self.queued_messages.drain(..)); + let mut messages = Vec::new(); - self.queued_events.clear(); + for event in self.queued_events.drain(..) { + let _ = user_interface.update( + event, + cursor_position, + clipboard, + renderer, + &mut messages, + ); + } + + messages.extend(self.queued_messages.drain(..)); debug.event_processing_finished(); if messages.is_empty() { diff --git a/native/src/user_interface.rs b/native/src/user_interface.rs index 6da46115..793d341c 100644 --- a/native/src/user_interface.rs +++ b/native/src/user_interface.rs @@ -1,6 +1,7 @@ +use crate::event::{self, Event}; use crate::layout; use crate::overlay; -use crate::{Clipboard, Element, Event, Layout, Point, Rectangle, Size}; +use crate::{Clipboard, Element, Layout, Point, Rectangle, Size}; use std::hash::Hasher; @@ -169,9 +170,10 @@ where /// /// // Initialize our event storage /// let mut events = Vec::new(); + /// let mut messages = Vec::new(); /// /// loop { - /// // Process system events... + /// // Obtain system events... /// /// let mut user_interface = UserInterface::build( /// counter.view(), @@ -180,32 +182,34 @@ where /// &mut renderer, /// ); /// - /// // Update the user interface - /// let messages = user_interface.update( - /// &events, - /// cursor_position, - /// None, - /// &renderer, - /// ); + /// for event in events.drain(..) { + /// // Update the user interface + /// let _event_status = user_interface.update( + /// event, + /// cursor_position, + /// None, + /// &renderer, + /// &mut messages + /// ); + /// } /// /// cache = user_interface.into_cache(); /// /// // Process the produced messages - /// for message in messages { + /// for message in messages.drain(..) { /// counter.update(message); /// } /// } /// ``` pub fn update( &mut self, - events: &[Event], + event: Event, cursor_position: Point, clipboard: Option<&dyn Clipboard>, renderer: &Renderer, - ) -> Vec { - let mut messages = Vec::new(); - - let base_cursor = if let Some(mut overlay) = + messages: &mut Vec, + ) -> event::Status { + let (base_cursor, overlay_status) = if let Some(mut overlay) = self.root.overlay(Layout::new(&self.base.layout)) { let layer = Self::overlay_layer( @@ -215,16 +219,14 @@ where renderer, ); - for event in events { - let _ = overlay.on_event( - event.clone(), - Layout::new(&layer.layout), - cursor_position, - &mut messages, - renderer, - clipboard, - ); - } + let event_status = overlay.on_event( + event.clone(), + Layout::new(&layer.layout), + cursor_position, + messages, + renderer, + clipboard, + ); let base_cursor = if layer.layout.bounds().contains(cursor_position) { @@ -236,23 +238,21 @@ where self.overlay = Some(layer); - base_cursor + (base_cursor, event_status) } else { - cursor_position + (cursor_position, event::Status::Ignored) }; - for event in events { - let _ = self.root.widget.on_event( - event.clone(), - Layout::new(&self.base.layout), - base_cursor, - &mut messages, - renderer, - clipboard, - ); - } + let event_status = self.root.widget.on_event( + event, + Layout::new(&self.base.layout), + base_cursor, + messages, + renderer, + clipboard, + ); - messages + event_status.merge(overlay_status) } /// Draws the [`UserInterface`] with the provided [`Renderer`]. @@ -293,9 +293,10 @@ where /// let mut window_size = Size::new(1024.0, 768.0); /// let mut cursor_position = Point::default(); /// let mut events = Vec::new(); + /// let mut messages = Vec::new(); /// /// loop { - /// // Process system events... + /// // Obtain system events... /// /// let mut user_interface = UserInterface::build( /// counter.view(), @@ -304,19 +305,23 @@ where /// &mut renderer, /// ); /// - /// let messages = user_interface.update( - /// &events, - /// cursor_position, - /// None, - /// &renderer, - /// ); + /// for event in events.drain(..) { + /// // Update the user interface + /// let _event_status = user_interface.update( + /// event, + /// cursor_position, + /// None, + /// &renderer, + /// &mut messages + /// ); + /// } /// /// // Draw the user interface /// let mouse_cursor = user_interface.draw(&mut renderer, cursor_position); /// /// cache = user_interface.into_cache(); /// - /// for message in messages { + /// for message in messages.drain(..) { /// counter.update(message); /// } /// diff --git a/winit/src/application.rs b/winit/src/application.rs index c1d86471..5f51a0cb 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -241,30 +241,23 @@ async fn run_instance( user_interface.draw(&mut renderer, state.cursor_position()); let mut mouse_interaction = mouse::Interaction::default(); - let mut events = Vec::new(); - let mut external_messages = Vec::new(); + let mut messages = Vec::new(); + let mut is_clean = true; debug.startup_finished(); while let Some(event) = receiver.next().await { match event { + event::Event::NewEvents(_) => { + debug.event_processing_started(); + } event::Event::MainEventsCleared => { - if events.is_empty() && external_messages.is_empty() { + debug.event_processing_finished(); + + if is_clean && messages.is_empty() { continue; } - debug.event_processing_started(); - let mut messages = user_interface.update( - &events, - state.cursor_position(), - clipboard.as_ref().map(|c| c as _), - &mut renderer, - ); - - messages.extend(external_messages.drain(..)); - events.clear(); - debug.event_processing_finished(); - if !messages.is_empty() { let cache = ManuallyDrop::into_inner(user_interface).into_cache(); @@ -274,7 +267,7 @@ async fn run_instance( &mut application, &mut runtime, &mut debug, - messages, + &mut messages, ); // Update window @@ -295,9 +288,10 @@ async fn run_instance( debug.draw_finished(); window.request_redraw(); + is_clean = true; } event::Event::UserEvent(message) => { - external_messages.push(message); + messages.push(message); } event::Event::RedrawRequested(_) => { debug.render_started(); @@ -365,8 +359,17 @@ async fn run_instance( state.scale_factor(), state.modifiers(), ) { - events.push(event.clone()); + let _ = user_interface.update( + event.clone(), + state.cursor_position(), + clipboard.as_ref().map(|c| c as _), + &mut renderer, + &mut messages, + ); + runtime.broadcast(event); + + is_clean = false; } } _ => {} @@ -437,9 +440,9 @@ pub fn update( application: &mut A, runtime: &mut Runtime, A::Message>, debug: &mut Debug, - messages: Vec, + messages: &mut Vec, ) { - for message in messages { + for message in messages.drain(..) { debug.log_message(&message); debug.update_started();