Use a WeakViewHandle in Client for view message handlers

This commit is contained in:
Antonio Scandurra 2023-04-26 12:08:15 +02:00
parent 57beec6071
commit 689e878bd8
3 changed files with 32 additions and 19 deletions

View file

@ -18,8 +18,8 @@ use gpui::{
actions, actions,
platform::AppVersion, platform::AppVersion,
serde_json::{self, Value}, serde_json::{self, Value},
AnyModelHandle, AnyViewHandle, AnyWeakModelHandle, AnyWeakViewHandle, AppContext, AnyModelHandle, AnyWeakModelHandle, AnyWeakViewHandle, AppContext, AsyncAppContext, Entity,
AsyncAppContext, Entity, ModelHandle, Task, View, ViewContext, ViewHandle, ModelHandle, Task, View, ViewContext, WeakViewHandle,
}; };
use lazy_static::lazy_static; use lazy_static::lazy_static;
use parking_lot::RwLock; use parking_lot::RwLock;
@ -221,7 +221,7 @@ enum WeakSubscriber {
enum Subscriber { enum Subscriber {
Model(AnyModelHandle), Model(AnyModelHandle),
View(AnyViewHandle), View(AnyWeakViewHandle),
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -567,7 +567,7 @@ impl Client {
H: 'static H: 'static
+ Send + Send
+ Sync + Sync
+ Fn(ViewHandle<E>, TypedEnvelope<M>, Arc<Self>, AsyncAppContext) -> F, + Fn(WeakViewHandle<E>, TypedEnvelope<M>, Arc<Self>, AsyncAppContext) -> F,
F: 'static + Future<Output = Result<()>>, F: 'static + Future<Output = Result<()>>,
{ {
self.add_entity_message_handler::<M, E, _, _>(move |handle, message, client, cx| { self.add_entity_message_handler::<M, E, _, _>(move |handle, message, client, cx| {
@ -666,7 +666,7 @@ impl Client {
H: 'static H: 'static
+ Send + Send
+ Sync + Sync
+ Fn(ViewHandle<E>, TypedEnvelope<M>, Arc<Self>, AsyncAppContext) -> F, + Fn(WeakViewHandle<E>, TypedEnvelope<M>, Arc<Self>, AsyncAppContext) -> F,
F: 'static + Future<Output = Result<M::Response>>, F: 'static + Future<Output = Result<M::Response>>,
{ {
self.add_view_message_handler(move |entity, envelope, client, cx| { self.add_view_message_handler(move |entity, envelope, client, cx| {
@ -1273,7 +1273,15 @@ impl Client {
pending.push(message); pending.push(message);
return; return;
} }
Some(weak_subscriber @ _) => subscriber = weak_subscriber.upgrade(cx), Some(weak_subscriber @ _) => match weak_subscriber {
WeakSubscriber::Model(handle) => {
subscriber = handle.upgrade(cx).map(Subscriber::Model);
}
WeakSubscriber::View(handle) => {
subscriber = Some(Subscriber::View(handle.clone()));
}
WeakSubscriber::Pending(_) => {}
},
_ => {} _ => {}
} }
} }
@ -1357,16 +1365,6 @@ impl Client {
} }
} }
impl WeakSubscriber {
fn upgrade(&self, cx: &AsyncAppContext) -> Option<Subscriber> {
match self {
WeakSubscriber::Model(handle) => handle.upgrade(cx).map(Subscriber::Model),
WeakSubscriber::View(handle) => handle.upgrade(cx).map(Subscriber::View),
WeakSubscriber::Pending(_) => None,
}
}
}
fn read_credentials_from_keychain(cx: &AsyncAppContext) -> Option<Credentials> { fn read_credentials_from_keychain(cx: &AsyncAppContext) -> Option<Credentials> {
if IMPERSONATE_LOGIN.is_some() { if IMPERSONATE_LOGIN.is_some() {
return None; return None;

View file

@ -4156,9 +4156,24 @@ impl AnyWeakViewHandle {
self.view_id self.view_id
} }
fn is<T: 'static>(&self) -> bool {
TypeId::of::<T>() == self.view_type
}
pub fn upgrade(&self, cx: &impl BorrowAppContext) -> Option<AnyViewHandle> { pub fn upgrade(&self, cx: &impl BorrowAppContext) -> Option<AnyViewHandle> {
cx.read_with(|cx| cx.upgrade_any_view_handle(self)) cx.read_with(|cx| cx.upgrade_any_view_handle(self))
} }
pub fn downcast<T: View>(self) -> Option<WeakViewHandle<T>> {
if self.is::<T>() {
Some(WeakViewHandle {
any_handle: self,
view_type: PhantomData,
})
} else {
None
}
}
} }
impl Hash for AnyWeakViewHandle { impl Hash for AnyWeakViewHandle {

View file

@ -2219,7 +2219,7 @@ impl Workspace {
// RPC handlers // RPC handlers
async fn handle_follow( async fn handle_follow(
this: ViewHandle<Self>, this: WeakViewHandle<Self>,
envelope: TypedEnvelope<proto::Follow>, envelope: TypedEnvelope<proto::Follow>,
_: Arc<Client>, _: Arc<Client>,
mut cx: AsyncAppContext, mut cx: AsyncAppContext,
@ -2267,7 +2267,7 @@ impl Workspace {
} }
async fn handle_unfollow( async fn handle_unfollow(
this: ViewHandle<Self>, this: WeakViewHandle<Self>,
envelope: TypedEnvelope<proto::Unfollow>, envelope: TypedEnvelope<proto::Unfollow>,
_: Arc<Client>, _: Arc<Client>,
mut cx: AsyncAppContext, mut cx: AsyncAppContext,
@ -2282,7 +2282,7 @@ impl Workspace {
} }
async fn handle_update_followers( async fn handle_update_followers(
this: ViewHandle<Self>, this: WeakViewHandle<Self>,
envelope: TypedEnvelope<proto::UpdateFollowers>, envelope: TypedEnvelope<proto::UpdateFollowers>,
_: Arc<Client>, _: Arc<Client>,
cx: AsyncAppContext, cx: AsyncAppContext,