Checkpoint

Nathan Sobo created

Change summary

crates/gpui3/src/elements/img.rs |  9 +++-
crates/gpui3/src/gpui3.rs        |  3 -
crates/gpui3/src/window.rs       | 53 ++++++++++++++++++++++++++-------
3 files changed, 49 insertions(+), 16 deletions(-)

Detailed changes

crates/gpui3/src/elements/img.rs 🔗

@@ -76,10 +76,13 @@ impl<S: 'static> Element for Img<S> {
                 cx.paint_image(bounds, corner_radii, order, data, self.grayscale)?;
             } else {
                 log::warn!("image not loaded yet");
+                cx.spawn(|cx| async move {
+                    if image_future.await.log_err().is_some() {
+                        // this.update(&mut cx, |_, cx| cx.notify()).ok();
+                    }
+                })
+                .detach()
                 // cx.spawn(|this, mut cx| async move {
-                //     if image_future.await.log_err().is_some() {
-                //         this.update(&mut cx, |_, cx| cx.notify()).ok();
-                //     }
                 // })
                 // .detach();
             }

crates/gpui3/src/gpui3.rs 🔗

@@ -27,8 +27,6 @@ pub use elements::*;
 pub use executor::*;
 pub use geometry::*;
 pub use gpui3_macros::*;
-pub use svg_renderer::*;
-
 pub use platform::*;
 pub use refineable::*;
 pub use scene::*;
@@ -44,6 +42,7 @@ use std::{
 pub use style::*;
 pub use style_helpers::*;
 pub use styled::*;
+pub use svg_renderer::*;
 use taffy::TaffyLayoutEngine;
 pub use taffy::{AvailableSpace, LayoutId};
 pub use text_system::*;

crates/gpui3/src/window.rs 🔗

@@ -1,10 +1,10 @@
 use crate::{
-    image_cache::RenderImageParams, px, AnyView, AppContext, AsyncContext, AvailableSpace,
-    BorrowAppContext, Bounds, Context, Corners, DevicePixels, Effect, Element, EntityId, FontId,
-    GlyphId, Handle, Hsla, ImageData, IsZero, LayerId, LayoutId, MainThread, MainThreadOnly,
-    MonochromeSprite, Pixels, PlatformAtlas, PlatformWindow, Point, PolychromeSprite, Reference,
-    RenderGlyphParams, RenderSvgParams, ScaledPixels, Scene, SharedString, Size, Style,
-    TaffyLayoutEngine, Task, WeakHandle, WindowOptions, SUBPIXEL_VARIANTS,
+    image_cache::RenderImageParams, px, AnyView, AppContext, AvailableSpace, BorrowAppContext,
+    Bounds, Context, Corners, DevicePixels, Effect, Element, EntityId, FontId, GlyphId, Handle,
+    Hsla, ImageData, IsZero, LayerId, LayoutId, MainThread, MainThreadOnly, MonochromeSprite,
+    Pixels, PlatformAtlas, PlatformWindow, Point, PolychromeSprite, Reference, RenderGlyphParams,
+    RenderSvgParams, ScaledPixels, Scene, SharedString, Size, Style, TaffyLayoutEngine, Task,
+    WeakHandle, WindowOptions, SUBPIXEL_VARIANTS,
 };
 use anyhow::Result;
 use smallvec::SmallVec;
@@ -112,7 +112,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
         self.window.dirty = true;
     }
 
-    fn run_on_main<R>(
+    pub fn run_on_main<R>(
         &mut self,
         f: impl FnOnce(&mut MainThread<WindowContext<'_, '_>>) -> R + Send + 'static,
     ) -> Task<Result<R>>
@@ -129,6 +129,36 @@ impl<'a, 'w> WindowContext<'a, 'w> {
         }
     }
 
+    pub fn spawn<Fut, R>(
+        &mut self,
+        f: impl FnOnce(&mut WindowContext<'_, '_>) -> Fut + Send + 'static,
+    ) -> Task<Result<R>>
+    where
+        R: Send + 'static,
+        Fut: Future<Output = R> + Send + 'static,
+    {
+        let id = self.window.handle.id;
+        self.app.spawn(move |cx| {
+            let future = cx.update_window(id, f);
+            async move { Ok(future?.await) }
+        })
+    }
+
+    pub fn try_spawn<Fut, R>(
+        &mut self,
+        f: impl FnOnce(&mut WindowContext<'_, '_>) -> Fut + Send + 'static,
+    ) -> Task<Result<R>>
+    where
+        R: Send + 'static,
+        Fut: Future<Output = Result<R>> + Send + 'static,
+    {
+        let id = self.window.handle.id;
+        self.app.spawn(move |cx| {
+            let future = cx.update_window(id, f);
+            async move { future?.await }
+        })
+    }
+
     pub fn request_layout(
         &mut self,
         style: Style,
@@ -606,13 +636,14 @@ impl<'a, 'w, S: Send + Sync + 'static> ViewContext<'a, 'w, S> {
         f: impl FnOnce(&mut S, &mut ViewContext<'_, '_, S>) -> Fut + Send + 'static,
     ) -> Task<Result<R>>
     where
+        R: Send + 'static,
         Fut: Future<Output = R> + Send + 'static,
     {
         let handle = self.handle();
-        todo!()
-        // self.window_cx.spawn(|cx| {
-        //     f
-        // })
+        self.window_cx.try_spawn(move |cx| {
+            let result = handle.update(cx, f);
+            async move { Ok(result?.await) }
+        })
     }
 
     pub(crate) fn erase_state<R>(&mut self, f: impl FnOnce(&mut ViewContext<()>) -> R) -> R {