From 64e0e817c27d720dc954ee94de58ded35b3f9f9a Mon Sep 17 00:00:00 2001 From: Bingus Date: Wed, 15 Feb 2023 14:31:16 -0800 Subject: Widget operations for multi-window. --- winit/src/multi_window.rs | 117 ++++++++++++++++++++++++---------------------- 1 file changed, 62 insertions(+), 55 deletions(-) (limited to 'winit/src/multi_window.rs') diff --git a/winit/src/multi_window.rs b/winit/src/multi_window.rs index 430e6706..bd7e9d44 100644 --- a/winit/src/multi_window.rs +++ b/winit/src/multi_window.rs @@ -4,12 +4,12 @@ mod state; pub use state::State; use crate::clipboard::{self, Clipboard}; -use crate::conversion; use crate::mouse; use crate::renderer; use crate::settings; use crate::widget::operation; use crate::window; +use crate::{conversion, multi_window}; use crate::{ Command, Debug, Element, Error, Executor, Proxy, Renderer, Runtime, Settings, Size, Subscription, @@ -254,7 +254,7 @@ where ); #[cfg(feature = "trace")] - let run_instance = + let run_instance = run_instance.instrument(info_span!("Application", "LOOP")); run_instance @@ -335,7 +335,7 @@ async fn run_instance( let mut clipboard = Clipboard::connect(windows.values().next().expect("No window found")); - let mut cache = user_interface::Cache::default(); + let mut caches = HashMap::new(); let mut window_ids: HashMap<_, _> = windows .iter() .map(|(&id, window)| (window.id(), id)) @@ -368,26 +368,23 @@ async fn run_instance( let _ = states.insert(id, state); let _ = surfaces.insert(id, surface); let _ = interfaces.insert(id, user_interface); + let _ = caches.insert(id, user_interface::Cache::default()); } - { - // TODO(derezzedex) - let state = states.values().next().expect("No state found"); + run_command( + &application, + &mut caches, + &states, + &mut renderer, + init_command, + &mut runtime, + &mut clipboard, + &mut proxy, + &mut debug, + &windows, + || compositor.fetch_information(), + ); - run_command( - &application, - &mut cache, - state, - &mut renderer, - init_command, - &mut runtime, - &mut clipboard, - &mut proxy, - &mut debug, - &windows, - || compositor.fetch_information(), - ); - } runtime.track(application.subscription().map(Event::Application)); let mut mouse_interaction = mouse::Interaction::default(); @@ -455,8 +452,7 @@ async fn run_instance( user_interface::State::Outdated, ) { - let state = states.get_mut(&id).unwrap(); - let pure_states: HashMap<_, _> = + let user_interfaces: HashMap<_, _> = ManuallyDrop::into_inner(interfaces) .drain() .map( @@ -472,8 +468,8 @@ async fn run_instance( // Update application update( &mut application, - &mut cache, - state, + &mut caches, + &states, &mut renderer, &mut runtime, &mut clipboard, @@ -485,7 +481,7 @@ async fn run_instance( ); // Update window - state.synchronize( + states.get_mut(&id).unwrap().synchronize( &application, id, windows.get(&id).expect("No window found with ID."), @@ -498,7 +494,7 @@ async fn run_instance( &mut renderer, &mut debug, &states, - pure_states, + user_interfaces, )); if should_exit { @@ -579,6 +575,7 @@ async fn run_instance( let _ = interfaces.insert(id, user_interface); let _ = window_ids.insert(window.id(), id); let _ = windows.insert(id, window); + let _ = caches.insert(id, user_interface::Cache::default()); } Event::CloseWindow(id) => { if let Some(window) = windows.get(&id) { @@ -764,7 +761,10 @@ async fn run_instance( )); } } else { - log::error!("No window state found for id: {:?}", window_id); + log::error!( + "No window state found for id: {:?}", + window_id + ); } } else { log::error!("No window found with id: {:?}", window_id); @@ -840,8 +840,8 @@ where /// resulting [`Command`], and tracking its [`Subscription`]. pub fn update( application: &mut A, - cache: &mut user_interface::Cache, - state: &State, + caches: &mut HashMap, + states: &HashMap>, renderer: &mut A::Renderer, runtime: &mut Runtime>, Event>, clipboard: &mut Clipboard, @@ -851,6 +851,7 @@ pub fn update( windows: &HashMap, graphics_info: impl FnOnce() -> compositor::Information + Copy, ) where + A: Application + 'static, ::Theme: StyleSheet, { for message in messages.drain(..) { @@ -867,8 +868,8 @@ pub fn update( run_command( application, - cache, - state, + caches, + states, renderer, command, runtime, @@ -887,8 +888,8 @@ pub fn update( /// Runs the actions of a [`Command`]. pub fn run_command( application: &A, - cache: &mut user_interface::Cache, - state: &State, + caches: &mut HashMap, + states: &HashMap>, renderer: &mut A::Renderer, command: Command, runtime: &mut Runtime>, Event>, @@ -898,7 +899,7 @@ pub fn run_command( windows: &HashMap, _graphics_info: impl FnOnce() -> compositor::Information + Copy, ) where - A: Application, + A: Application + 'static, E: Executor, ::Theme: StyleSheet, { @@ -1024,36 +1025,42 @@ pub fn run_command( } }, command::Action::Widget(action) => { - let mut current_cache = std::mem::take(cache); + let mut current_caches = std::mem::take(caches); let mut current_operation = Some(action.into_operation()); - let mut user_interface = build_user_interface( + let mut user_interfaces = build_user_interfaces( application, - current_cache, renderer, - state.logical_size(), debug, - window::Id::MAIN, // TODO(derezzedex): run the operation on every widget tree + states, + current_caches, ); while let Some(mut operation) = current_operation.take() { - user_interface.operate(renderer, operation.as_mut()); - - match operation.finish() { - operation::Outcome::None => {} - operation::Outcome::Some(message) => { - proxy - .send_event(Event::Application(message)) - .expect("Send message to event loop"); - } - operation::Outcome::Chain(next) => { - current_operation = Some(next); + for user_interface in user_interfaces.values_mut() { + user_interface.operate(renderer, operation.as_mut()); + + match operation.finish() { + operation::Outcome::None => {} + operation::Outcome::Some(message) => { + proxy + .send_event(Event::Application(message)) + .expect("Send message to event loop"); + } + operation::Outcome::Chain(next) => { + current_operation = Some(next); + } } } } - current_cache = user_interface.into_cache(); - *cache = current_cache; + let user_interfaces: HashMap<_, _> = user_interfaces + .drain() + .map(|(id, interface)| (id, interface.into_cache())) + .collect(); + + current_caches = user_interfaces; + *caches = current_caches; } } } @@ -1065,7 +1072,7 @@ pub fn build_user_interfaces<'a, A>( renderer: &mut A::Renderer, debug: &mut Debug, states: &HashMap>, - mut pure_states: HashMap, + mut cached_user_interfaces: HashMap, ) -> HashMap< window::Id, UserInterface< @@ -1080,12 +1087,12 @@ where { let mut interfaces = HashMap::new(); - for (id, pure_state) in pure_states.drain() { + for (id, cache) in cached_user_interfaces.drain() { let state = &states.get(&id).unwrap(); let user_interface = build_user_interface( application, - pure_state, + cache, renderer, state.logical_size(), debug, -- cgit