Compiling checkpoint

Nathan Sobo created

Change summary

crates/gpui/playground/src/adapter.rs | 43 +++++++++++++++++++--------
crates/gpui/playground/src/element.rs | 44 +++++++++++++++++++++++++---
crates/gpui/playground/src/frame.rs   |  9 +++++
3 files changed, 77 insertions(+), 19 deletions(-)

Detailed changes

crates/gpui/playground/src/adapter.rs 🔗

@@ -4,22 +4,26 @@ use util::ResultExt;
 
 use crate::element::AnyElement;
 
-struct Adapter<V>(AnyElement<V>);
+#[derive(Clone)]
+pub struct Adapter<V> {
+    view: V,
+    element: AnyElement<V>,
+}
 
-impl<V: 'static> gpui::Element<V> for Adapter<V> {
+impl<V: 'static> gpui::Element<Adapter<V>> for Adapter<V> {
     type LayoutState = ();
     type PaintState = ();
 
     fn layout(
         &mut self,
         constraint: gpui::SizeConstraint,
-        view: &mut V,
-        legacy_cx: &mut gpui::LayoutContext<V>,
+        view: &mut Self,
+        legacy_cx: &mut gpui::LayoutContext<Self>,
     ) -> (gpui::geometry::vector::Vector2F, Self::LayoutState) {
         legacy_cx.push_layout_engine();
         let node = self
-            .0
-            .layout(view, &mut LayoutContext { legacy_cx })
+            .element
+            .layout(&mut self.view, &mut LayoutContext { legacy_cx })
             .log_err();
 
         if let Some(node) = node {
@@ -37,11 +41,11 @@ impl<V: 'static> gpui::Element<V> for Adapter<V> {
         bounds: RectF,
         visible_bounds: RectF,
         layout: &mut (),
-        view: &mut V,
-        legacy_cx: &mut gpui::PaintContext<V>,
+        adapter: &mut Self,
+        legacy_cx: &mut gpui::PaintContext<Self>,
     ) -> Self::PaintState {
         let mut cx = PaintContext { legacy_cx, scene };
-        self.0.paint(view, &mut cx).log_err();
+        self.element.paint(&mut adapter.view, &mut cx).log_err();
     }
 
     fn rect_for_text_range(
@@ -51,8 +55,8 @@ impl<V: 'static> gpui::Element<V> for Adapter<V> {
         visible_bounds: RectF,
         layout: &Self::LayoutState,
         paint: &Self::PaintState,
-        view: &V,
-        cx: &gpui::ViewContext<V>,
+        view: &Adapter<V>,
+        cx: &gpui::ViewContext<Adapter<V>>,
     ) -> Option<RectF> {
         todo!()
     }
@@ -62,9 +66,22 @@ impl<V: 'static> gpui::Element<V> for Adapter<V> {
         bounds: RectF,
         layout: &Self::LayoutState,
         paint: &Self::PaintState,
-        view: &V,
-        cx: &gpui::ViewContext<V>,
+        view: &Adapter<V>,
+        cx: &gpui::ViewContext<Adapter<V>>,
     ) -> gpui::serde_json::Value {
         todo!()
     }
 }
+
+impl<V: 'static> gpui::Entity for Adapter<V> {
+    type Event = ();
+}
+
+impl<V: 'static> gpui::View for Adapter<V>
+where
+    V: Clone,
+{
+    fn render(&mut self, cx: &mut gpui::ViewContext<'_, '_, Self>) -> gpui::AnyElement<Self> {
+        gpui::Element::into_any(self.clone())
+    }
+}

crates/gpui/playground/src/element.rs 🔗

@@ -1,4 +1,7 @@
-use crate::style::{DefinedLength, Display, Overflow, Position, Style};
+use crate::{
+    adapter::Adapter,
+    style::{DefinedLength, Display, Overflow, Position, Style},
+};
 use anyhow::Result;
 use derive_more::{Deref, DerefMut};
 use gpui::{Layout, LayoutContext as LegacyLayoutContext, PaintContext as LegacyPaintContext};
@@ -7,18 +10,18 @@ pub use taffy::tree::NodeId;
 
 #[derive(Deref, DerefMut)]
 pub struct LayoutContext<'a, 'b, 'c, 'd, V> {
-    pub(crate) legacy_cx: &'d mut LegacyLayoutContext<'a, 'b, 'c, V>,
+    pub(crate) legacy_cx: &'d mut LegacyLayoutContext<'a, 'b, 'c, Adapter<V>>,
 }
 
 #[derive(Deref, DerefMut)]
 pub struct PaintContext<'a, 'b, 'c, 'd, V> {
     #[deref]
     #[deref_mut]
-    pub(crate) legacy_cx: &'d mut LegacyPaintContext<'a, 'b, 'c, V>,
+    pub(crate) legacy_cx: &'d mut LegacyPaintContext<'a, 'b, 'c, Adapter<V>>,
     pub(crate) scene: &'d mut gpui::SceneBuilder,
 }
 
-pub trait Element<V> {
+pub trait Element<V: 'static>: 'static + Clone {
     fn style_mut(&mut self) -> &mut Style;
     fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>) -> Result<NodeId>;
     fn paint(&mut self, layout: Layout, view: &mut V, cx: &mut PaintContext<V>) -> Result<()>;
@@ -29,7 +32,7 @@ pub trait Element<V> {
         Self: 'static + Sized,
     {
         AnyElement {
-            element: Box::new(self) as Box<dyn Element<V>>,
+            element: Box::new(self) as Box<dyn ElementObject<V>>,
             layout_node_id: None,
         }
     }
@@ -196,8 +199,28 @@ pub trait Element<V> {
     }
 }
 
+pub trait ElementObject<V> {
+    fn clone_object(&self) -> Box<dyn ElementObject<V>>;
+    fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>) -> Result<NodeId>;
+    fn paint(&mut self, layout: Layout, view: &mut V, cx: &mut PaintContext<V>) -> Result<()>;
+}
+
+impl<V: 'static, E: Element<V>> ElementObject<V> for E {
+    fn clone_object(&self) -> Box<dyn ElementObject<V>> {
+        Box::new(Clone::clone(self))
+    }
+
+    fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>) -> Result<NodeId> {
+        self.layout(view, cx)
+    }
+
+    fn paint(&mut self, layout: Layout, view: &mut V, cx: &mut PaintContext<V>) -> Result<()> {
+        self.paint(layout, view, cx)
+    }
+}
+
 pub struct AnyElement<V> {
-    element: Box<dyn Element<V>>,
+    element: Box<dyn ElementObject<V>>,
     layout_node_id: Option<NodeId>,
 }
 
@@ -218,3 +241,12 @@ impl<V> AnyElement<V> {
         self.element.paint(layout, view, cx)
     }
 }
+
+impl<V> Clone for AnyElement<V> {
+    fn clone(&self) -> Self {
+        Self {
+            element: self.element.clone_object(),
+            layout_node_id: self.layout_node_id,
+        }
+    }
+}

crates/gpui/playground/src/frame.rs 🔗

@@ -43,3 +43,12 @@ impl<V: 'static> Element<V> for Frame<V> {
         Ok(())
     }
 }
+
+impl<V> Clone for Frame<V> {
+    fn clone(&self) -> Self {
+        Self {
+            style: self.style.clone(),
+            children: self.children.clone(),
+        }
+    }
+}