From 80688689aa4b15bc23824df899974a9094a77b07 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 28 Jul 2022 02:46:51 +0200 Subject: Draft widget operations --- winit/src/application.rs | 118 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 91 insertions(+), 27 deletions(-) (limited to 'winit') diff --git a/winit/src/application.rs b/winit/src/application.rs index 99402cf5..a27adf3a 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -7,6 +7,7 @@ use crate::clipboard::{self, Clipboard}; use crate::conversion; use crate::mouse; use crate::renderer; +use crate::widget::operation; use crate::{ Command, Debug, Error, Executor, Mode, Proxy, Runtime, Settings, Size, Subscription, @@ -131,9 +132,9 @@ where debug.startup_started(); let event_loop = EventLoop::with_user_event(); - let mut proxy = event_loop.create_proxy(); + let proxy = event_loop.create_proxy(); - let mut runtime = { + let runtime = { let proxy = Proxy::new(event_loop.create_proxy()); let executor = E::new().map_err(Error::ExecutorCreationFailed)?; @@ -146,8 +147,6 @@ where runtime.enter(|| A::new(flags)) }; - let subscription = application.subscription(); - let builder = settings.window.into_builder( &application.title(), application.mode(), @@ -176,20 +175,8 @@ where .expect("Append canvas to HTML body"); } - let mut clipboard = Clipboard::connect(&window); - let (compositor, renderer) = C::new(compositor_settings, Some(&window))?; - run_command( - init_command, - &mut runtime, - &mut clipboard, - &mut proxy, - &window, - || compositor.fetch_information(), - ); - runtime.track(subscription); - let (mut sender, receiver) = mpsc::unbounded(); let mut instance = Box::pin(run_instance::( @@ -197,10 +184,10 @@ where compositor, renderer, runtime, - clipboard, proxy, debug, receiver, + init_command, window, settings.exit_on_close_request, )); @@ -247,10 +234,10 @@ async fn run_instance( mut compositor: C, mut renderer: A::Renderer, mut runtime: Runtime, A::Message>, - mut clipboard: Clipboard, mut proxy: winit::event_loop::EventLoopProxy, mut debug: Debug, mut receiver: mpsc::UnboundedReceiver>, + init_command: Command, window: winit::window::Window, exit_on_close_request: bool, ) where @@ -262,6 +249,8 @@ async fn run_instance( use iced_futures::futures::stream::StreamExt; use winit::event; + let mut clipboard = Clipboard::connect(&window); + let mut cache = user_interface::Cache::default(); let mut surface = compositor.create_surface(&window); let mut state = State::new(&application, &window); @@ -275,9 +264,24 @@ async fn run_instance( physical_size.height, ); + run_command( + &application, + &mut cache, + &state, + &mut renderer, + init_command, + &mut runtime, + &mut clipboard, + &mut proxy, + &mut debug, + &window, + || compositor.fetch_information(), + ); + runtime.track(application.subscription()); + let mut user_interface = ManuallyDrop::new(build_user_interface( &mut application, - user_interface::Cache::default(), + cache, &mut renderer, state.logical_size(), &mut debug, @@ -318,12 +322,15 @@ async fn run_instance( user_interface::State::Outdated, ) { - let cache = + let mut cache = ManuallyDrop::into_inner(user_interface).into_cache(); // Update application update( &mut application, + &mut cache, + &state, + &mut renderer, &mut runtime, &mut clipboard, &mut proxy, @@ -515,7 +522,7 @@ pub fn requests_exit( /// Builds a [`UserInterface`] for the provided [`Application`], logging /// [`struct@Debug`] information accordingly. pub fn build_user_interface<'a, A: Application>( - application: &'a mut A, + application: &'a A, cache: user_interface::Cache, renderer: &mut A::Renderer, size: Size, @@ -539,6 +546,9 @@ where /// resulting [`Command`], and tracking its [`Subscription`]. pub fn update( application: &mut A, + cache: &mut user_interface::Cache, + state: &State, + renderer: &mut A::Renderer, runtime: &mut Runtime, A::Message>, clipboard: &mut Clipboard, proxy: &mut winit::event_loop::EventLoopProxy, @@ -556,7 +566,19 @@ pub fn update( let command = runtime.enter(|| application.update(message)); debug.update_finished(); - run_command(command, runtime, clipboard, proxy, window, graphics_info); + run_command( + application, + cache, + state, + renderer, + command, + runtime, + clipboard, + proxy, + debug, + window, + graphics_info, + ); } let subscription = application.subscription(); @@ -564,14 +586,23 @@ pub fn update( } /// Runs the actions of a [`Command`]. -pub fn run_command( - command: Command, - runtime: &mut Runtime, Message>, +pub fn run_command( + application: &A, + cache: &mut user_interface::Cache, + state: &State, + renderer: &mut A::Renderer, + command: Command, + runtime: &mut Runtime, A::Message>, clipboard: &mut Clipboard, - proxy: &mut winit::event_loop::EventLoopProxy, + proxy: &mut winit::event_loop::EventLoopProxy, + debug: &mut Debug, window: &winit::window::Window, _graphics_info: impl FnOnce() -> compositor::Information + Copy, -) { +) where + A: Application, + E: Executor, + ::Theme: StyleSheet, +{ use iced_native::command; use iced_native::system; use iced_native::window; @@ -627,6 +658,39 @@ pub fn run_command( } } }, + command::Action::Widget(action) => { + let mut current_cache = + std::mem::replace(cache, user_interface::Cache::default()); + + let mut current_operation = Some(action.into_operation()); + + while let Some(mut operation) = current_operation.take() { + let mut user_interface = build_user_interface( + application, + current_cache, + renderer, + state.logical_size(), + debug, + ); + + user_interface.operate(renderer, operation.as_mut()); + current_cache = user_interface.into_cache(); + + match operation.finish() { + operation::Outcome::None => {} + operation::Outcome::Some(message) => { + proxy + .send_event(message) + .expect("Send message to event loop"); + } + operation::Outcome::Chain(next) => { + current_operation = Some(next); + } + } + } + + *cache = current_cache; + } } } } -- cgit From 6dac049db5824e3af06bc16df0fdf51f8809aeb4 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 28 Jul 2022 04:00:06 +0200 Subject: Fix `clippy` lints :tada: --- winit/src/application.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'winit') diff --git a/winit/src/application.rs b/winit/src/application.rs index a27adf3a..3d58da0f 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -280,7 +280,7 @@ async fn run_instance( runtime.track(application.subscription()); let mut user_interface = ManuallyDrop::new(build_user_interface( - &mut application, + &application, cache, &mut renderer, state.logical_size(), @@ -346,7 +346,7 @@ async fn run_instance( let should_exit = application.should_exit(); user_interface = ManuallyDrop::new(build_user_interface( - &mut application, + &application, cache, &mut renderer, state.logical_size(), @@ -659,9 +659,7 @@ pub fn run_command( } }, command::Action::Widget(action) => { - let mut current_cache = - std::mem::replace(cache, user_interface::Cache::default()); - + let mut current_cache = std::mem::take(cache); let mut current_operation = Some(action.into_operation()); while let Some(mut operation) = current_operation.take() { -- cgit From 54ad92ce913629d1d1f623f4b14d51244554a59c Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 2 Aug 2022 17:34:04 +0200 Subject: Build `UserInterface` only once on `Outcome::Chain` --- winit/src/application.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'winit') diff --git a/winit/src/application.rs b/winit/src/application.rs index 3d58da0f..3a5c3dac 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -662,17 +662,16 @@ pub fn run_command( let mut current_cache = std::mem::take(cache); let mut current_operation = Some(action.into_operation()); - while let Some(mut operation) = current_operation.take() { - let mut user_interface = build_user_interface( - application, - current_cache, - renderer, - state.logical_size(), - debug, - ); + let mut user_interface = build_user_interface( + application, + current_cache, + renderer, + state.logical_size(), + debug, + ); + while let Some(mut operation) = current_operation.take() { user_interface.operate(renderer, operation.as_mut()); - current_cache = user_interface.into_cache(); match operation.finish() { operation::Outcome::None => {} @@ -687,6 +686,7 @@ pub fn run_command( } } + current_cache = user_interface.into_cache(); *cache = current_cache; } } -- cgit