Checkpoint

Nathan Sobo created

Change summary

crates/gpui3/src/app.rs               |  1 -
crates/gpui3/src/app/async_context.rs |  6 +++++-
crates/gpui3/src/window.rs            | 17 +++++++++++++++++
3 files changed, 22 insertions(+), 2 deletions(-)

Detailed changes

crates/gpui3/src/app.rs 🔗

@@ -359,7 +359,6 @@ impl MainThread<AppContext> {
             let id = cx.windows.insert(None);
             let handle = WindowHandle::new(id);
             let mut window = Window::new(handle.into(), options, cx);
-            let display_id = window.display_id;
             let root_view = build_root_view(&mut WindowContext::mutable(cx, &mut window));
             window.root_view.replace(root_view.into_any());
             cx.windows.get_mut(id).unwrap().replace(window);

crates/gpui3/src/app/async_context.rs 🔗

@@ -60,9 +60,13 @@ pub struct AsyncWindowContext {
 }
 
 impl AsyncWindowContext {
-    pub fn new(app: AsyncAppContext, window: AnyWindowHandle) -> Self {
+    pub(crate) fn new(app: AsyncAppContext, window: AnyWindowHandle) -> Self {
         Self { app, window }
     }
+
+    pub fn update<R>(&self, update: impl FnOnce(&mut WindowContext) -> R) -> Result<R> {
+        self.app.update_window(self.window, update)
+    }
 }
 
 impl Context for AsyncWindowContext {

crates/gpui3/src/window.rs 🔗

@@ -143,6 +143,14 @@ impl<'a, 'w> WindowContext<'a, 'w> {
         AsyncWindowContext::new(self.app.to_async(), self.window.handle)
     }
 
+    pub fn on_next_frame(&mut self, f: impl FnOnce(&mut WindowContext) + Send + 'static) {
+        let cx = self.to_async();
+        let display_id = self.window.display_id;
+        self.display_linker.on_next_frame(display_id, move |_, _| {
+            cx.update(f).ok();
+        });
+    }
+
     pub fn spawn<Fut, R>(
         &mut self,
         f: impl FnOnce(AnyWindowHandle, AsyncWindowContext) -> Fut + Send + 'static,
@@ -581,6 +589,15 @@ impl<'a, 'w, S: Send + Sync + 'static> ViewContext<'a, 'w, S> {
         self.entities.weak_handle(self.entity_id)
     }
 
+    pub fn on_next_frame(&mut self, f: impl FnOnce(&mut S, &mut ViewContext<S>) + Send + 'static) {
+        let mut cx = self.to_async();
+        let entity = self.handle();
+        let display_id = self.window.display_id;
+        self.display_linker.on_next_frame(display_id, move |_, _| {
+            entity.update(&mut cx, f).ok();
+        });
+    }
+
     pub fn observe<E: Send + Sync + 'static>(
         &mut self,
         handle: &Handle<E>,