mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-26 10:40:54 +00:00
Avoid reference cycle between Client
and its models
This commit is contained in:
parent
471ecae82c
commit
10a872a370
2 changed files with 24 additions and 8 deletions
|
@ -133,9 +133,8 @@ struct ClientState {
|
|||
entity_id_extractors: HashMap<TypeId, Box<dyn Send + Sync + Fn(&dyn AnyTypedEnvelope) -> u64>>,
|
||||
_maintain_connection: Option<Task<()>>,
|
||||
heartbeat_interval: Duration,
|
||||
|
||||
models_by_entity_type_and_remote_id: HashMap<(TypeId, u64), AnyWeakModelHandle>,
|
||||
models_by_message_type: HashMap<TypeId, AnyModelHandle>,
|
||||
models_by_message_type: HashMap<TypeId, AnyWeakModelHandle>,
|
||||
model_types_by_message_type: HashMap<TypeId, TypeId>,
|
||||
message_handlers: HashMap<
|
||||
TypeId,
|
||||
|
@ -348,18 +347,22 @@ impl Client {
|
|||
{
|
||||
let message_type_id = TypeId::of::<M>();
|
||||
|
||||
let client = self.clone();
|
||||
let client = Arc::downgrade(self);
|
||||
let mut state = self.state.write();
|
||||
state
|
||||
.models_by_message_type
|
||||
.insert(message_type_id, model.into());
|
||||
.insert(message_type_id, model.downgrade().into());
|
||||
|
||||
let prev_handler = state.message_handlers.insert(
|
||||
message_type_id,
|
||||
Arc::new(move |handle, envelope, cx| {
|
||||
let model = handle.downcast::<E>().unwrap();
|
||||
let envelope = envelope.into_any().downcast::<TypedEnvelope<M>>().unwrap();
|
||||
handler(model, *envelope, client.clone(), cx).boxed_local()
|
||||
if let Some(client) = client.upgrade() {
|
||||
handler(model, *envelope, client.clone(), cx).boxed_local()
|
||||
} else {
|
||||
async move { Ok(()) }.boxed_local()
|
||||
}
|
||||
}),
|
||||
);
|
||||
if prev_handler.is_some() {
|
||||
|
@ -385,7 +388,7 @@ impl Client {
|
|||
let model_type_id = TypeId::of::<E>();
|
||||
let message_type_id = TypeId::of::<M>();
|
||||
|
||||
let client = self.clone();
|
||||
let client = Arc::downgrade(self);
|
||||
let mut state = self.state.write();
|
||||
state
|
||||
.model_types_by_message_type
|
||||
|
@ -408,7 +411,11 @@ impl Client {
|
|||
Arc::new(move |handle, envelope, cx| {
|
||||
let model = handle.downcast::<E>().unwrap();
|
||||
let envelope = envelope.into_any().downcast::<TypedEnvelope<M>>().unwrap();
|
||||
handler(model, *envelope, client.clone(), cx).boxed_local()
|
||||
if let Some(client) = client.upgrade() {
|
||||
handler(model, *envelope, client.clone(), cx).boxed_local()
|
||||
} else {
|
||||
async move { Ok(()) }.boxed_local()
|
||||
}
|
||||
}),
|
||||
);
|
||||
if prev_handler.is_some() {
|
||||
|
@ -550,7 +557,7 @@ impl Client {
|
|||
let model = state
|
||||
.models_by_message_type
|
||||
.get(&payload_type_id)
|
||||
.cloned()
|
||||
.and_then(|model| model.upgrade(&cx))
|
||||
.or_else(|| {
|
||||
let model_type_id =
|
||||
*state.model_types_by_message_type.get(&payload_type_id)?;
|
||||
|
|
|
@ -3567,6 +3567,15 @@ impl AnyWeakModelHandle {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Entity> From<WeakModelHandle<T>> for AnyWeakModelHandle {
|
||||
fn from(handle: WeakModelHandle<T>) -> Self {
|
||||
AnyWeakModelHandle {
|
||||
model_id: handle.model_id,
|
||||
model_type: TypeId::of::<T>(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WeakViewHandle<T> {
|
||||
window_id: usize,
|
||||
view_id: usize,
|
||||
|
|
Loading…
Reference in a new issue