diff --git a/crates/gpui2/src/app.rs b/crates/gpui2/src/app.rs index 3bc0c14f9a52cb1006ac7af803e8f4e9990ca525..8de3734c4c4ec6aecd21e0c70d5cd1f16f75c3c4 100644 --- a/crates/gpui2/src/app.rs +++ b/crates/gpui2/src/app.rs @@ -139,12 +139,18 @@ impl App { } type ActionBuilder = fn(json: Option) -> anyhow::Result>; -type FrameCallback = Box; +type FrameCallback = Box; type Handler = Box bool + 'static>; type Listener = Box bool + 'static>; type QuitHandler = Box LocalBoxFuture<'static, ()> + 'static>; type ReleaseListener = Box; +// struct FrameConsumer { +// next_frame_callbacks: Vec, +// task: Task<()>, +// display_linker +// } + pub struct AppContext { this: Weak, pub(crate) platform: Rc, @@ -154,6 +160,7 @@ pub struct AppContext { pending_updates: usize, pub(crate) active_drag: Option, pub(crate) next_frame_callbacks: HashMap>, + pub(crate) frame_consumers: HashMap>, pub(crate) background_executor: BackgroundExecutor, pub(crate) foreground_executor: ForegroundExecutor, pub(crate) svg_renderer: SvgRenderer, @@ -204,12 +211,14 @@ impl AppContext { Rc::new_cyclic(|this| AppCell { app: RefCell::new(AppContext { this: this.clone(), - text_system, platform, app_metadata, + text_system, flushing_effects: false, pending_updates: 0, - next_frame_callbacks: Default::default(), + active_drag: None, + next_frame_callbacks: HashMap::default(), + frame_consumers: HashMap::default(), background_executor: executor, foreground_executor, svg_renderer: SvgRenderer::new(asset_source.clone()), @@ -232,7 +241,6 @@ impl AppContext { quit_observers: SubscriberSet::new(), layout_id_buffer: Default::default(), propagate_event: true, - active_drag: None, }), }) } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 0202b7521eebc36735077e3199f0322e25a80e91..6034727d8245f64f1ae0c6ab9688672e14b6bf88 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -12,7 +12,10 @@ use crate::{ use anyhow::{anyhow, Result}; use collections::HashMap; use derive_more::{Deref, DerefMut}; -use futures::channel::oneshot; +use futures::{ + channel::{mpsc, oneshot}, + StreamExt, +}; use parking_lot::RwLock; use slotmap::SlotMap; use smallvec::SmallVec; @@ -411,6 +414,31 @@ impl<'a> WindowContext<'a> { let f = Box::new(f); let display_id = self.window.display_id; + self.next_frame_callbacks + .entry(display_id) + .or_default() + .push(f); + + self.frame_consumers.entry(display_id).or_insert_with(|| { + let (tx, rx) = mpsc::unbounded::<()>(); + + self.spawn(|cx| async move { + while rx.next().await.is_some() { + let _ = cx.update(|_, cx| { + for callback in cx + .app + .next_frame_callbacks + .get_mut(&display_id) + .unwrap() + .drain(..) + { + callback(cx); + } + }); + } + }) + }); + if let Some(callbacks) = self.next_frame_callbacks.get_mut(&display_id) { callbacks.push(f); // If there was already a callback, it means that we already scheduled a frame.