Merge remote-tracking branch 'origin/main' into zed2-workspace

This commit is contained in:
Conrad Irwin 2023-11-02 13:16:24 -06:00
commit 269a72464d
128 changed files with 1718 additions and 1670 deletions

View file

@ -13,7 +13,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;
@ -443,42 +446,55 @@ impl<'a> WindowContext<'a> {
}
/// Schedule the given closure to be run directly after the current frame is rendered.
pub fn on_next_frame(&mut self, f: impl FnOnce(&mut WindowContext) + 'static) {
let f = Box::new(f);
pub fn on_next_frame(&mut self, callback: impl FnOnce(&mut WindowContext) + 'static) {
let handle = self.window.handle;
let display_id = self.window.display_id;
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.
if callbacks.len() > 1 {
return;
}
} else {
let mut async_cx = self.to_async();
self.next_frame_callbacks.insert(display_id, vec![f]);
if !self.frame_consumers.contains_key(&display_id) {
let (tx, mut rx) = mpsc::unbounded::<()>();
self.platform.set_display_link_output_callback(
display_id,
Box::new(move |_current_time, _output_time| {
let _ = async_cx.update(|_, cx| {
let callbacks = cx
Box::new(move |_current_time, _output_time| _ = tx.unbounded_send(())),
);
let consumer_task = self.app.spawn(|cx| async move {
while rx.next().await.is_some() {
cx.update(|cx| {
for callback in cx
.next_frame_callbacks
.get_mut(&display_id)
.unwrap()
.drain(..)
.collect::<Vec<_>>();
for callback in callbacks {
.collect::<SmallVec<[_; 32]>>()
{
callback(cx);
}
})
.ok();
if cx.next_frame_callbacks.get(&display_id).unwrap().is_empty() {
// Flush effects, then stop the display link if no new next_frame_callbacks have been added.
cx.update(|cx| {
if cx.next_frame_callbacks.is_empty() {
cx.platform.stop_display_link(display_id);
}
});
}),
);
})
.ok();
}
});
self.frame_consumers.insert(display_id, consumer_task);
}
self.platform.start_display_link(display_id);
if self.next_frame_callbacks.is_empty() {
self.platform.start_display_link(display_id);
}
self.next_frame_callbacks
.entry(display_id)
.or_default()
.push(Box::new(move |cx: &mut AppContext| {
cx.update_window(handle, |_root_view, cx| callback(cx)).ok();
}));
}
/// Spawn the future returned by the given closure on the application thread pool.