Add AnyWeakViewHandle

Max Brunsfeld created

Change summary

crates/gpui/src/app.rs       | 57 ++++++++++++++++++++++++++++++++++++++
crates/gpui/src/presenter.rs |  4 ++
2 files changed, 61 insertions(+)

Detailed changes

crates/gpui/src/app.rs 🔗

@@ -93,6 +93,8 @@ pub trait UpgradeModelHandle {
 
 pub trait UpgradeViewHandle {
     fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>>;
+
+    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle>;
 }
 
 pub trait ReadView {
@@ -647,6 +649,10 @@ impl UpgradeViewHandle for AsyncAppContext {
     fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
         self.0.borrow_mut().upgrade_view_handle(handle)
     }
+
+    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
+        self.0.borrow_mut().upgrade_any_view_handle(handle)
+    }
 }
 
 impl ReadModelWith for AsyncAppContext {
@@ -2017,6 +2023,10 @@ impl UpgradeViewHandle for MutableAppContext {
     fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
         self.cx.upgrade_view_handle(handle)
     }
+
+    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
+        self.cx.upgrade_any_view_handle(handle)
+    }
 }
 
 impl ReadView for MutableAppContext {
@@ -2174,6 +2184,19 @@ impl UpgradeViewHandle for AppContext {
             None
         }
     }
+
+    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
+        if self.ref_counts.lock().is_entity_alive(handle.view_id) {
+            Some(AnyViewHandle::new(
+                handle.window_id,
+                handle.view_id,
+                handle.view_type,
+                self.ref_counts.clone(),
+            ))
+        } else {
+            None
+        }
+    }
 }
 
 impl ReadView for AppContext {
@@ -2931,6 +2954,10 @@ impl<V> UpgradeViewHandle for ViewContext<'_, V> {
     fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
         self.cx.upgrade_view_handle(handle)
     }
+
+    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
+        self.cx.upgrade_any_view_handle(handle)
+    }
 }
 
 impl<V: View> UpdateModel for ViewContext<'_, V> {
@@ -3619,6 +3646,14 @@ impl AnyViewHandle {
             None
         }
     }
+
+    pub fn downgrade(&self) -> AnyWeakViewHandle {
+        AnyWeakViewHandle {
+            window_id: self.window_id,
+            view_id: self.view_id,
+            view_type: self.view_type,
+        }
+    }
 }
 
 impl Clone for AnyViewHandle {
@@ -3845,6 +3880,28 @@ impl<T> Hash for WeakViewHandle<T> {
     }
 }
 
+pub struct AnyWeakViewHandle {
+    window_id: usize,
+    view_id: usize,
+    view_type: TypeId,
+}
+
+impl AnyWeakViewHandle {
+    pub fn upgrade(&self, cx: &impl UpgradeViewHandle) -> Option<AnyViewHandle> {
+        cx.upgrade_any_view_handle(self)
+    }
+}
+
+impl<T: View> From<WeakViewHandle<T>> for AnyWeakViewHandle {
+    fn from(handle: WeakViewHandle<T>) -> Self {
+        AnyWeakViewHandle {
+            window_id: handle.window_id,
+            view_id: handle.view_id,
+            view_type: TypeId::of::<T>(),
+        }
+    }
+}
+
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
 pub struct ElementStateId {
     view_id: usize,

crates/gpui/src/presenter.rs 🔗

@@ -299,6 +299,10 @@ impl<'a> UpgradeViewHandle for LayoutContext<'a> {
     fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
         self.app.upgrade_view_handle(handle)
     }
+
+    fn upgrade_any_view_handle(&self, handle: &crate::AnyWeakViewHandle) -> Option<AnyViewHandle> {
+        self.app.upgrade_any_view_handle(handle)
+    }
 }
 
 impl<'a> ElementStateContext for LayoutContext<'a> {