Fix erorr in revert

Mikayla created

Change summary

crates/gpui/src/elements/component.rs | 39 +++++++++++++++++++---------
1 file changed, 26 insertions(+), 13 deletions(-)

Detailed changes

crates/gpui/src/elements/component.rs 🔗

@@ -105,22 +105,24 @@ impl<V: View> Component<V> for ElementAdapter<V> {
 }
 
 // Component -> Element
-pub struct ComponentAdapter<V, E> {
+pub struct ComponentAdapter<V: View, E> {
     component: Option<E>,
+    element: Option<AnyElement<V>>,
     phantom: PhantomData<V>,
 }
 
-impl<E, V> ComponentAdapter<V, E> {
+impl<E, V: View> ComponentAdapter<V, E> {
     pub fn new(e: E) -> Self {
         Self {
             component: Some(e),
+            element: None,
             phantom: PhantomData,
         }
     }
 }
 
 impl<V: View, C: Component<V> + 'static> Element<V> for ComponentAdapter<V, C> {
-    type LayoutState = AnyElement<V>;
+    type LayoutState = ();
 
     type PaintState = ();
 
@@ -130,10 +132,16 @@ impl<V: View, C: Component<V> + 'static> Element<V> for ComponentAdapter<V, C> {
         view: &mut V,
         cx: &mut LayoutContext<V>,
     ) -> (Vector2F, Self::LayoutState) {
-        let component = self.component.take().unwrap();
-        let mut element = component.render(view, cx.view_context());
-        let constraint = element.layout(constraint, view, cx);
-        (constraint, element)
+        if self.element.is_none() {
+            let element = self
+                .component
+                .take()
+                .expect("Component can only be rendered once")
+                .render(view, cx.view_context());
+            self.element = Some(element);
+        }
+        let constraint = self.element.as_mut().unwrap().layout(constraint, view, cx);
+        (constraint, ())
     }
 
     fn paint(
@@ -141,11 +149,14 @@ impl<V: View, C: Component<V> + 'static> Element<V> for ComponentAdapter<V, C> {
         scene: &mut SceneBuilder,
         bounds: RectF,
         visible_bounds: RectF,
-        layout: &mut Self::LayoutState,
+        _: &mut Self::LayoutState,
         view: &mut V,
         cx: &mut PaintContext<V>,
     ) -> Self::PaintState {
-        layout.paint(scene, bounds.origin(), visible_bounds, view, cx)
+        self.element
+            .as_mut()
+            .expect("Layout should always be called before paint")
+            .paint(scene, bounds.origin(), visible_bounds, view, cx)
     }
 
     fn rect_for_text_range(
@@ -153,25 +164,27 @@ impl<V: View, C: Component<V> + 'static> Element<V> for ComponentAdapter<V, C> {
         range_utf16: std::ops::Range<usize>,
         _: RectF,
         _: RectF,
-        element: &Self::LayoutState,
+        _: &Self::LayoutState,
         _: &Self::PaintState,
         view: &V,
         cx: &ViewContext<V>,
     ) -> Option<RectF> {
-        element.rect_for_text_range(range_utf16, view, cx)
+        self.element
+            .as_ref()
+            .and_then(|el| el.rect_for_text_range(range_utf16, view, cx))
     }
 
     fn debug(
         &self,
         _: RectF,
-        element: &Self::LayoutState,
+        _: &Self::LayoutState,
         _: &Self::PaintState,
         view: &V,
         cx: &ViewContext<V>,
     ) -> serde_json::Value {
         serde_json::json!({
             "type": "ComponentAdapter",
-            "child": element.debug(view, cx),
+            "child": self.element.as_ref().map(|el| el.debug(view, cx)),
         })
     }
 }