From aed8df96ff5dc596b63de469f9e5fddfc8928c67 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sun, 2 Apr 2023 15:42:03 -0600 Subject: [PATCH] Wrap AnyWeak handles with their typed counterparts --- crates/client/src/client.rs | 12 +- crates/gpui/src/app.rs | 179 +++++++++++------------------ crates/project/src/project.rs | 4 +- crates/workspace/src/searchable.rs | 6 +- 4 files changed, 82 insertions(+), 119 deletions(-) diff --git a/crates/client/src/client.rs b/crates/client/src/client.rs index bb39b06699..2c8c9aadbe 100644 --- a/crates/client/src/client.rs +++ b/crates/client/src/client.rs @@ -293,7 +293,7 @@ impl PendingEntitySubscription { state .entities_by_type_and_remote_id - .insert(id, WeakSubscriber::Model(model.downgrade().into())); + .insert(id, WeakSubscriber::Model(model.downgrade().into_any())); drop(state); for message in messages { self.client.handle_message(message, cx); @@ -457,10 +457,10 @@ impl Client { cx: &mut ViewContext, ) -> Subscription { let id = (TypeId::of::(), remote_id); - self.state - .write() - .entities_by_type_and_remote_id - .insert(id, WeakSubscriber::View(cx.weak_handle().into())); + self.state.write().entities_by_type_and_remote_id.insert( + id, + WeakSubscriber::View((&cx.weak_handle() as &AnyWeakViewHandle).clone()), + ); Subscription::Entity { client: Arc::downgrade(self), id, @@ -504,7 +504,7 @@ impl Client { let mut state = self.state.write(); state .models_by_message_type - .insert(message_type_id, model.downgrade().into()); + .insert(message_type_id, model.downgrade().into_any()); let prev_handler = state.message_handlers.insert( message_type_id, diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 464bb071f3..77f3cd620b 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -2823,8 +2823,7 @@ impl AppContext { } } - pub fn is_child_focused(&self, view: impl Into) -> bool { - let view = view.into(); + pub fn is_child_focused(&self, view: &AnyViewHandle) -> bool { if let Some(focused_view_id) = self.focused_view_id(view.window_id) { self.ancestors(view.window_id, focused_view_id) .skip(1) // Skip self id @@ -4455,32 +4454,23 @@ pub enum EntityLocation { } pub struct ModelHandle { - model_id: usize, + any_handle: AnyModelHandle, model_type: PhantomData, - ref_counts: Arc>, +} - #[cfg(any(test, feature = "test-support"))] - handle_id: usize, +impl Deref for ModelHandle { + type Target = AnyModelHandle; + + fn deref(&self) -> &Self::Target { + &self.any_handle + } } impl ModelHandle { fn new(model_id: usize, ref_counts: &Arc>) -> Self { - ref_counts.lock().inc_model(model_id); - - #[cfg(any(test, feature = "test-support"))] - let handle_id = ref_counts - .lock() - .leak_detector - .lock() - .handle_created(Some(type_name::()), model_id); - Self { - model_id, + any_handle: AnyModelHandle::new(model_id, TypeId::of::(), ref_counts.clone()), model_type: PhantomData, - ref_counts: ref_counts.clone(), - - #[cfg(any(test, feature = "test-support"))] - handle_id, } } @@ -4564,19 +4554,6 @@ impl Debug for ModelHandle { unsafe impl Send for ModelHandle {} unsafe impl Sync for ModelHandle {} -impl Drop for ModelHandle { - fn drop(&mut self) { - let mut ref_counts = self.ref_counts.lock(); - ref_counts.dec_model(self.model_id); - - #[cfg(any(test, feature = "test-support"))] - ref_counts - .leak_detector - .lock() - .handle_dropped(self.model_id, self.handle_id); - } -} - impl Handle for ModelHandle { type Weak = WeakModelHandle; @@ -4601,10 +4578,24 @@ impl Handle for ModelHandle { } pub struct WeakModelHandle { - model_id: usize, + any_handle: AnyWeakModelHandle, model_type: PhantomData, } +impl WeakModelHandle { + pub fn into_any(self) -> AnyWeakModelHandle { + self.any_handle + } +} + +impl Deref for WeakModelHandle { + type Target = AnyWeakModelHandle; + + fn deref(&self) -> &Self::Target { + &self.any_handle + } +} + impl WeakHandle for WeakModelHandle { fn id(&self) -> usize { self.model_id @@ -4617,7 +4608,10 @@ unsafe impl Sync for WeakModelHandle {} impl WeakModelHandle { fn new(model_id: usize) -> Self { Self { - model_id, + any_handle: AnyWeakModelHandle { + model_id, + model_type: TypeId::of::(), + }, model_type: PhantomData, } } @@ -4658,7 +4652,7 @@ impl PartialEq> for WeakModelHandle { impl Clone for WeakModelHandle { fn clone(&self) -> Self { Self { - model_id: self.model_id, + any_handle: self.any_handle.clone(), model_type: PhantomData, } } @@ -4681,23 +4675,13 @@ impl Deref for ViewHandle { impl ViewHandle { fn new(window_id: usize, view_id: usize, ref_counts: &Arc>) -> Self { - ref_counts.lock().inc_view(window_id, view_id); - #[cfg(any(test, feature = "test-support"))] - let handle_id = ref_counts - .lock() - .leak_detector - .lock() - .handle_created(Some(type_name::()), view_id); - Self { - any_handle: AnyViewHandle { + any_handle: AnyViewHandle::new( window_id, view_id, - view_type: TypeId::of::(), - ref_counts: ref_counts.clone(), - #[cfg(any(test, feature = "test-support"))] - handle_id, - }, + TypeId::of::(), + ref_counts.clone(), + ), view_type: PhantomData, } } @@ -4918,12 +4902,6 @@ impl Clone for AnyViewHandle { } } -impl From<&AnyViewHandle> for AnyViewHandle { - fn from(handle: &AnyViewHandle) -> Self { - handle.clone() - } -} - impl From> for AnyViewHandle { fn from(handle: ViewHandle) -> Self { handle.any_handle @@ -4982,19 +4960,10 @@ impl AnyModelHandle { pub fn downcast(self) -> Option> { if self.is::() { - let result = Some(ModelHandle { - model_id: self.model_id, + Some(ModelHandle { + any_handle: self, model_type: PhantomData, - ref_counts: self.ref_counts.clone(), - - #[cfg(any(test, feature = "test-support"))] - handle_id: self.handle_id, - }); - unsafe { - Arc::decrement_strong_count(Arc::as_ptr(&self.ref_counts)); - } - std::mem::forget(self); - result + }) } else { None } @@ -5016,16 +4985,6 @@ impl AnyModelHandle { } } -impl From> for AnyModelHandle { - fn from(handle: ModelHandle) -> Self { - Self::new( - handle.model_id, - TypeId::of::(), - handle.ref_counts.clone(), - ) - } -} - impl Clone for AnyModelHandle { fn clone(&self) -> Self { Self::new(self.model_id, self.model_type, self.ref_counts.clone()) @@ -5045,7 +5004,7 @@ impl Drop for AnyModelHandle { } } -#[derive(Hash, PartialEq, Eq, Debug)] +#[derive(Hash, PartialEq, Eq, Debug, Clone, Copy)] pub struct AnyWeakModelHandle { model_id: usize, model_type: TypeId, @@ -5063,10 +5022,10 @@ impl AnyWeakModelHandle { TypeId::of::() == self.model_type } - pub fn downcast(&self) -> Option> { + pub fn downcast(self) -> Option> { if self.is::() { let result = Some(WeakModelHandle { - model_id: self.model_id, + any_handle: self, model_type: PhantomData, }); @@ -5077,19 +5036,9 @@ impl AnyWeakModelHandle { } } -impl From> for AnyWeakModelHandle { - fn from(handle: WeakModelHandle) -> Self { - AnyWeakModelHandle { - model_id: handle.model_id, - model_type: TypeId::of::(), - } - } -} - #[derive(Debug, Copy)] pub struct WeakViewHandle { - window_id: usize, - view_id: usize, + any_handle: AnyWeakViewHandle, view_type: PhantomData, } @@ -5102,8 +5051,11 @@ impl WeakHandle for WeakViewHandle { impl WeakViewHandle { fn new(window_id: usize, view_id: usize) -> Self { Self { - window_id, - view_id, + any_handle: AnyWeakViewHandle { + window_id, + view_id, + view_type: TypeId::of::(), + }, view_type: PhantomData, } } @@ -5116,16 +5068,27 @@ impl WeakViewHandle { self.window_id } + pub fn into_any(self) -> AnyWeakViewHandle { + self.any_handle + } + pub fn upgrade(&self, cx: &impl UpgradeViewHandle) -> Option> { cx.upgrade_view_handle(self) } } +impl Deref for WeakViewHandle { + type Target = AnyWeakViewHandle; + + fn deref(&self) -> &Self::Target { + &self.any_handle + } +} + impl Clone for WeakViewHandle { fn clone(&self) -> Self { Self { - window_id: self.window_id, - view_id: self.view_id, + any_handle: self.any_handle.clone(), view_type: PhantomData, } } @@ -5141,11 +5104,11 @@ impl Eq for WeakViewHandle {} impl Hash for WeakViewHandle { fn hash(&self, state: &mut H) { - self.window_id.hash(state); - self.view_id.hash(state); + self.any_handle.hash(state); } } +#[derive(Debug, Clone, Copy)] pub struct AnyWeakViewHandle { window_id: usize, view_id: usize, @@ -5162,13 +5125,11 @@ impl AnyWeakViewHandle { } } -impl From> for AnyWeakViewHandle { - fn from(handle: WeakViewHandle) -> Self { - AnyWeakViewHandle { - window_id: handle.window_id, - view_id: handle.view_id, - view_type: TypeId::of::(), - } +impl Hash for AnyWeakViewHandle { + fn hash(&self, state: &mut H) { + self.window_id.hash(state); + self.view_id.hash(state); + self.view_type.hash(state); } } @@ -6340,8 +6301,8 @@ mod tests { cx.focus(&view_1); cx.focus(&view_2); }); - assert!(cx.is_child_focused(view_1.clone())); - assert!(!cx.is_child_focused(view_2.clone())); + assert!(cx.is_child_focused(&view_1)); + assert!(!cx.is_child_focused(&view_2)); assert_eq!( mem::take(&mut *view_events.lock()), [ @@ -6366,8 +6327,8 @@ mod tests { ); view_1.update(cx, |_, cx| cx.focus(&view_1)); - assert!(!cx.is_child_focused(view_1.clone())); - assert!(!cx.is_child_focused(view_2.clone())); + assert!(!cx.is_child_focused(&view_1)); + assert!(!cx.is_child_focused(&view_2)); assert_eq!( mem::take(&mut *view_events.lock()), ["view 2 blurred", "view 1 focused"], diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 4d6f42cd0e..b0a9784ba9 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -1231,7 +1231,9 @@ impl Project { File::from_dyn(buffer.file()).and_then(|file| file.project_entry_id(cx)) }) .ok_or_else(|| anyhow!("no project entry"))?; - Ok((project_entry_id, buffer.into())) + + let buffer: &AnyModelHandle = &buffer; + Ok((project_entry_id, buffer.clone())) }) } diff --git a/crates/workspace/src/searchable.rs b/crates/workspace/src/searchable.rs index b072d78a12..ae78ca0eb8 100644 --- a/crates/workspace/src/searchable.rs +++ b/crates/workspace/src/searchable.rs @@ -234,7 +234,7 @@ impl Eq for Box {} pub trait WeakSearchableItemHandle: WeakItemHandle { fn upgrade(&self, cx: &AppContext) -> Option>; - fn to_any(self) -> AnyWeakViewHandle; + fn into_any(self) -> AnyWeakViewHandle; } impl WeakSearchableItemHandle for WeakViewHandle { @@ -242,8 +242,8 @@ impl WeakSearchableItemHandle for WeakViewHandle { Some(Box::new(self.upgrade(cx)?)) } - fn to_any(self) -> AnyWeakViewHandle { - self.into() + fn into_any(self) -> AnyWeakViewHandle { + self.into_any() } }