Detailed changes
@@ -67,8 +67,8 @@ impl ActiveCall {
incoming_call: watch::channel(),
_subscriptions: vec![
- client.add_request_handler(cx.weak_handle(), Self::handle_incoming_call),
- client.add_message_handler(cx.weak_handle(), Self::handle_call_canceled),
+ client.add_request_handler(cx.weak_model(), Self::handle_incoming_call),
+ client.add_message_handler(cx.weak_model(), Self::handle_call_canceled),
],
client,
user_store,
@@ -122,9 +122,9 @@ impl UserStore {
let (mut current_user_tx, current_user_rx) = watch::channel();
let (update_contacts_tx, mut update_contacts_rx) = mpsc::unbounded();
let rpc_subscriptions = vec![
- client.add_message_handler(cx.weak_handle(), Self::handle_update_contacts),
- client.add_message_handler(cx.weak_handle(), Self::handle_update_invite_info),
- client.add_message_handler(cx.weak_handle(), Self::handle_show_contacts),
+ client.add_message_handler(cx.weak_model(), Self::handle_update_contacts),
+ client.add_message_handler(cx.weak_model(), Self::handle_update_invite_info),
+ client.add_message_handler(cx.weak_model(), Self::handle_show_contacts),
];
Self {
users: Default::default(),
@@ -7,8 +7,8 @@ use async_tar::Archive;
use collections::{HashMap, HashSet};
use futures::{channel::oneshot, future::Shared, Future, FutureExt, TryFutureExt};
use gpui2::{
- AppContext, AsyncAppContext, Context, EntityId, EventEmitter, Model, ModelContext, Task,
- WeakModel,
+ AppContext, AsyncAppContext, Context, Entity, EntityId, EventEmitter, Model, ModelContext,
+ Task, WeakModel,
};
use language2::{
language_settings::{all_language_settings, language_settings},
@@ -726,7 +726,7 @@ impl Context for AppContext {
/// Update the entity referenced by the given model. The function is passed a mutable reference to the
/// entity along with a `ModelContext` for the entity.
- fn update_entity<T: 'static, R>(
+ fn update_model<T: 'static, R>(
&mut self,
model: &Model<T>,
update: impl FnOnce(&mut T, &mut Self::ModelContext<'_, T>) -> R,
@@ -32,7 +32,7 @@ impl Context for AsyncAppContext {
Ok(lock.build_model(build_model))
}
- fn update_entity<T: 'static, R>(
+ fn update_model<T: 'static, R>(
&mut self,
handle: &Model<T>,
update: impl FnOnce(&mut T, &mut Self::ModelContext<'_, T>) -> R,
@@ -42,7 +42,7 @@ impl Context for AsyncAppContext {
.upgrade()
.ok_or_else(|| anyhow!("app was released"))?;
let mut lock = app.lock(); // Need this to compile
- Ok(lock.update_entity(handle, update))
+ Ok(lock.update_model(handle, update))
}
}
@@ -230,13 +230,13 @@ impl Context for AsyncWindowContext {
.update_window(self.window, |cx| cx.build_model(build_model))
}
- fn update_entity<T: 'static, R>(
+ fn update_model<T: 'static, R>(
&mut self,
handle: &Model<T>,
update: impl FnOnce(&mut T, &mut Self::ModelContext<'_, T>) -> R,
) -> Result<R> {
self.app
- .update_window(self.window, |cx| cx.update_entity(handle, update))
+ .update_window(self.window, |cx| cx.update_model(handle, update))
}
}
@@ -1,4 +1,4 @@
-use crate::{AnyBox, AppContext, Context};
+use crate::{private::Sealed, AnyBox, AppContext, Context, Entity};
use anyhow::{anyhow, Result};
use derive_more::{Deref, DerefMut};
use parking_lot::{RwLock, RwLockUpgradableReadGuard};
@@ -253,6 +253,32 @@ pub struct Model<T> {
unsafe impl<T> Send for Model<T> {}
unsafe impl<T> Sync for Model<T> {}
+impl<T> Sealed for Model<T> {}
+
+impl<T: 'static> Entity<T> for Model<T> {
+ type Weak = WeakModel<T>;
+
+ fn entity_id(&self) -> EntityId {
+ self.any_model.entity_id
+ }
+
+ fn downgrade(&self) -> Self::Weak {
+ WeakModel {
+ any_model: self.any_model.downgrade(),
+ entity_type: self.entity_type,
+ }
+ }
+
+ fn upgrade_from(weak: &Self::Weak) -> Option<Self>
+ where
+ Self: Sized,
+ {
+ Some(Model {
+ any_model: weak.any_model.upgrade()?,
+ entity_type: weak.entity_type,
+ })
+ }
+}
impl<T: 'static> Model<T> {
fn new(id: EntityId, entity_map: Weak<RwLock<EntityRefCounts>>) -> Self
@@ -265,11 +291,12 @@ impl<T: 'static> Model<T> {
}
}
+ /// Downgrade the this to a weak model reference
pub fn downgrade(&self) -> WeakModel<T> {
- WeakModel {
- any_model: self.any_model.downgrade(),
- entity_type: self.entity_type,
- }
+ // Delegate to the trait implementation to keep behavior in one place.
+ // This method was included to improve method resolution in the presence of
+ // the Model's deref
+ Entity::downgrade(self)
}
/// Convert this into a dynamically typed model.
@@ -294,7 +321,7 @@ impl<T: 'static> Model<T> {
where
C: Context,
{
- cx.update_entity(self, update)
+ cx.update_model(self, update)
}
}
@@ -334,7 +361,7 @@ impl<T> Eq for Model<T> {}
impl<T> PartialEq<WeakModel<T>> for Model<T> {
fn eq(&self, other: &WeakModel<T>) -> bool {
- self.entity_id() == other.entity_id()
+ self.any_model.entity_id() == other.entity_id()
}
}
@@ -415,11 +442,10 @@ impl<T> Clone for WeakModel<T> {
}
impl<T: 'static> WeakModel<T> {
+ /// Upgrade this weak model reference into a strong model reference
pub fn upgrade(&self) -> Option<Model<T>> {
- Some(Model {
- any_model: self.any_model.upgrade()?,
- entity_type: self.entity_type,
- })
+ // Delegate to the trait implementation to keep behavior in one place.
+ Model::upgrade_from(self)
}
/// Update the entity referenced by this model with the given function if
@@ -441,7 +467,7 @@ impl<T: 'static> WeakModel<T> {
crate::Flatten::flatten(
self.upgrade()
.ok_or_else(|| anyhow!("entity release"))
- .map(|this| cx.update_entity(&this, update)),
+ .map(|this| cx.update_model(&this, update)),
)
}
}
@@ -462,6 +488,6 @@ impl<T> Eq for WeakModel<T> {}
impl<T> PartialEq<Model<T>> for WeakModel<T> {
fn eq(&self, other: &Model<T>) -> bool {
- self.entity_id() == other.entity_id()
+ self.entity_id() == other.any_model.entity_id()
}
}
@@ -1,6 +1,6 @@
use crate::{
- AppContext, AsyncAppContext, Context, Effect, EntityId, EventEmitter, MainThread, Model,
- Reference, Subscription, Task, WeakModel,
+ AppContext, AsyncAppContext, Context, Effect, Entity, EntityId, EventEmitter, MainThread,
+ Model, Reference, Subscription, Task, WeakModel,
};
use derive_more::{Deref, DerefMut};
use futures::FutureExt;
@@ -31,29 +31,32 @@ impl<'a, T: 'static> ModelContext<'a, T> {
}
pub fn handle(&self) -> Model<T> {
- self.weak_handle()
+ self.weak_model()
.upgrade()
.expect("The entity must be alive if we have a model context")
}
- pub fn weak_handle(&self) -> WeakModel<T> {
+ pub fn weak_model(&self) -> WeakModel<T> {
self.model_state.clone()
}
- pub fn observe<T2: 'static>(
+ pub fn observe<T2, E>(
&mut self,
- handle: &Model<T2>,
- mut on_notify: impl FnMut(&mut T, Model<T2>, &mut ModelContext<'_, T>) + Send + 'static,
+ entity: &E,
+ mut on_notify: impl FnMut(&mut T, E, &mut ModelContext<'_, T>) + Send + 'static,
) -> Subscription
where
T: 'static + Send,
+ T2: 'static,
+ E: Entity<T2>,
{
- let this = self.weak_handle();
- let handle = handle.downgrade();
+ let this = self.weak_model();
+ let entity_id = entity.entity_id();
+ let handle = entity.downgrade();
self.app.observers.insert(
- handle.entity_id,
+ entity_id,
Box::new(move |cx| {
- if let Some((this, handle)) = this.upgrade().zip(handle.upgrade()) {
+ if let Some((this, handle)) = this.upgrade().zip(E::upgrade_from(&handle)) {
this.update(cx, |this, cx| on_notify(this, handle, cx));
true
} else {
@@ -63,21 +66,24 @@ impl<'a, T: 'static> ModelContext<'a, T> {
)
}
- pub fn subscribe<E: 'static + EventEmitter>(
+ pub fn subscribe<T2, E>(
&mut self,
- handle: &Model<E>,
- mut on_event: impl FnMut(&mut T, Model<E>, &E::Event, &mut ModelContext<'_, T>) + Send + 'static,
+ entity: &E,
+ mut on_event: impl FnMut(&mut T, E, &T2::Event, &mut ModelContext<'_, T>) + Send + 'static,
) -> Subscription
where
T: 'static + Send,
+ T2: 'static + EventEmitter,
+ E: Entity<T2>,
{
- let this = self.weak_handle();
- let handle = handle.downgrade();
+ let this = self.weak_model();
+ let entity_id = entity.entity_id();
+ let entity = entity.downgrade();
self.app.event_listeners.insert(
- handle.entity_id,
+ entity_id,
Box::new(move |event, cx| {
- let event: &E::Event = event.downcast_ref().expect("invalid event type");
- if let Some((this, handle)) = this.upgrade().zip(handle.upgrade()) {
+ let event: &T2::Event = event.downcast_ref().expect("invalid event type");
+ if let Some((this, handle)) = this.upgrade().zip(E::upgrade_from(&entity)) {
this.update(cx, |this, cx| on_event(this, handle, event, cx));
true
} else {
@@ -103,17 +109,20 @@ impl<'a, T: 'static> ModelContext<'a, T> {
)
}
- pub fn observe_release<E: 'static>(
+ pub fn observe_release<T2, E>(
&mut self,
- handle: &Model<E>,
- mut on_release: impl FnMut(&mut T, &mut E, &mut ModelContext<'_, T>) + Send + 'static,
+ entity: &E,
+ mut on_release: impl FnMut(&mut T, &mut T2, &mut ModelContext<'_, T>) + Send + 'static,
) -> Subscription
where
T: Any + Send,
+ T2: 'static,
+ E: Entity<T2>,
{
- let this = self.weak_handle();
+ let entity_id = entity.entity_id();
+ let this = self.weak_model();
self.app.release_listeners.insert(
- handle.entity_id,
+ entity_id,
Box::new(move |entity, cx| {
let entity = entity.downcast_mut().expect("invalid entity type");
if let Some(this) = this.upgrade() {
@@ -130,7 +139,7 @@ impl<'a, T: 'static> ModelContext<'a, T> {
where
T: 'static + Send,
{
- let handle = self.weak_handle();
+ let handle = self.weak_model();
self.global_observers.insert(
TypeId::of::<G>(),
Box::new(move |cx| handle.update(cx, |view, cx| f(view, cx)).is_ok()),
@@ -145,7 +154,7 @@ impl<'a, T: 'static> ModelContext<'a, T> {
Fut: 'static + Future<Output = ()> + Send,
T: 'static + Send,
{
- let handle = self.weak_handle();
+ let handle = self.weak_model();
self.app.quit_observers.insert(
(),
Box::new(move |cx| {
@@ -191,7 +200,7 @@ impl<'a, T: 'static> ModelContext<'a, T> {
Fut: Future<Output = R> + Send + 'static,
R: Send + 'static,
{
- let this = self.weak_handle();
+ let this = self.weak_model();
self.app.spawn(|cx| f(this, cx))
}
@@ -203,7 +212,7 @@ impl<'a, T: 'static> ModelContext<'a, T> {
Fut: Future<Output = R> + 'static,
R: Send + 'static,
{
- let this = self.weak_handle();
+ let this = self.weak_model();
self.app.spawn_on_main(|cx| f(this, cx))
}
}
@@ -235,12 +244,12 @@ impl<'a, T> Context for ModelContext<'a, T> {
self.app.build_model(build_model)
}
- fn update_entity<U: 'static, R>(
+ fn update_model<U: 'static, R>(
&mut self,
handle: &Model<U>,
update: impl FnOnce(&mut U, &mut Self::ModelContext<'_, U>) -> R,
) -> R {
- self.app.update_entity(handle, update)
+ self.app.update_model(handle, update)
}
}
@@ -26,13 +26,13 @@ impl Context for TestAppContext {
lock.build_model(build_model)
}
- fn update_entity<T: 'static, R>(
+ fn update_model<T: 'static, R>(
&mut self,
handle: &Model<T>,
update: impl FnOnce(&mut T, &mut Self::ModelContext<'_, T>) -> R,
) -> Self::Result<R> {
let mut lock = self.app.lock();
- lock.update_entity(handle, update)
+ lock.update_model(handle, update)
}
}
@@ -24,6 +24,12 @@ mod util;
mod view;
mod window;
+mod private {
+ /// A mechanism for restricting implementations of a trait to only those in GPUI.
+ /// See: https://predr.ag/blog/definitive-guide-to-sealed-traits-in-rust/
+ pub trait Sealed {}
+}
+
pub use action::*;
pub use anyhow::Result;
pub use app::*;
@@ -39,6 +45,7 @@ pub use image_cache::*;
pub use interactive::*;
pub use keymap::*;
pub use platform::*;
+use private::Sealed;
pub use refineable::*;
pub use scene::*;
pub use serde;
@@ -80,7 +87,7 @@ pub trait Context {
where
T: 'static + Send;
- fn update_entity<T: 'static, R>(
+ fn update_model<T: 'static, R>(
&mut self,
handle: &Model<T>,
update: impl FnOnce(&mut T, &mut Self::ModelContext<'_, T>) -> R,
@@ -104,6 +111,16 @@ pub trait VisualContext: Context {
) -> Self::Result<R>;
}
+pub trait Entity<T>: Sealed {
+ type Weak: 'static + Send;
+
+ fn entity_id(&self) -> EntityId;
+ fn downgrade(&self) -> Self::Weak;
+ fn upgrade_from(weak: &Self::Weak) -> Option<Self>
+ where
+ Self: Sized;
+}
+
pub enum GlobalKey {
Numeric(usize),
View(EntityId),
@@ -149,12 +166,12 @@ impl<C: Context> Context for MainThread<C> {
})
}
- fn update_entity<T: 'static, R>(
+ fn update_model<T: 'static, R>(
&mut self,
handle: &Model<T>,
update: impl FnOnce(&mut T, &mut Self::ModelContext<'_, T>) -> R,
) -> Self::Result<R> {
- self.0.update_entity(handle, |entity, cx| {
+ self.0.update_model(handle, |entity, cx| {
let cx = unsafe {
mem::transmute::<
&mut C::ModelContext<'_, T>,
@@ -1,7 +1,7 @@
use crate::{
- AnyBox, AnyElement, AnyModel, AppContext, AvailableSpace, BorrowWindow, Bounds, Component,
- Element, ElementId, EntityId, LayoutId, Model, Pixels, Size, ViewContext, VisualContext,
- WeakModel, WindowContext,
+ private::Sealed, AnyBox, AnyElement, AnyModel, AppContext, AvailableSpace, BorrowWindow,
+ Bounds, Component, Element, ElementId, Entity, EntityId, LayoutId, Model, Pixels, Size,
+ ViewContext, VisualContext, WeakModel, WindowContext,
};
use anyhow::{Context, Result};
use std::{any::TypeId, marker::PhantomData, sync::Arc};
@@ -16,19 +16,42 @@ pub struct View<V> {
pub(crate) model: Model<V>,
}
+impl<V> Sealed for View<V> {}
+
impl<V: Render> View<V> {
pub fn into_any(self) -> AnyView {
AnyView(Arc::new(self))
}
}
-impl<V: 'static> View<V> {
- pub fn downgrade(&self) -> WeakView<V> {
+impl<V: 'static> Entity<V> for View<V> {
+ type Weak = WeakView<V>;
+
+ fn entity_id(&self) -> EntityId {
+ self.model.entity_id
+ }
+
+ fn downgrade(&self) -> Self::Weak {
WeakView {
model: self.model.downgrade(),
}
}
+ fn upgrade_from(weak: &Self::Weak) -> Option<Self>
+ where
+ Self: Sized,
+ {
+ let model = weak.model.upgrade()?;
+ Some(View { model })
+ }
+}
+
+impl<V: 'static> View<V> {
+ /// Convert this strong view reference into a weak view reference.
+ pub fn downgrade(&self) -> WeakView<V> {
+ Entity::downgrade(self)
+ }
+
pub fn update<C, R>(
&self,
cx: &mut C,
@@ -111,8 +134,7 @@ pub struct WeakView<V> {
impl<V: 'static> WeakView<V> {
pub fn upgrade(&self) -> Option<View<V>> {
- let model = self.model.upgrade()?;
- Some(View { model })
+ Entity::upgrade_from(self)
}
pub fn update<R>(
@@ -200,7 +222,7 @@ where
}
fn entity_id(&self) -> EntityId {
- self.model.entity_id
+ Entity::entity_id(self)
}
fn model(&self) -> AnyModel {
@@ -208,7 +230,7 @@ where
}
fn initialize(&self, cx: &mut WindowContext) -> AnyBox {
- cx.with_element_id(self.entity_id(), |_global_id, cx| {
+ cx.with_element_id(ViewObject::entity_id(self), |_global_id, cx| {
self.update(cx, |state, cx| {
let mut any_element = Box::new(AnyElement::new(state.render(cx)));
any_element.initialize(state, cx);
@@ -218,7 +240,7 @@ where
}
fn layout(&self, element: &mut AnyBox, cx: &mut WindowContext) -> LayoutId {
- cx.with_element_id(self.entity_id(), |_global_id, cx| {
+ cx.with_element_id(ViewObject::entity_id(self), |_global_id, cx| {
self.update(cx, |state, cx| {
let element = element.downcast_mut::<AnyElement<V>>().unwrap();
element.layout(state, cx)
@@ -227,7 +249,7 @@ where
}
fn paint(&self, _: Bounds<Pixels>, element: &mut AnyBox, cx: &mut WindowContext) {
- cx.with_element_id(self.entity_id(), |_global_id, cx| {
+ cx.with_element_id(ViewObject::entity_id(self), |_global_id, cx| {
self.update(cx, |state, cx| {
let element = element.downcast_mut::<AnyElement<V>>().unwrap();
element.paint(state, cx);
@@ -1,8 +1,8 @@
use crate::{
px, size, Action, AnyBox, AnyDrag, AnyView, AppContext, AsyncWindowContext, AvailableSpace,
Bounds, BoxShadow, Context, Corners, DevicePixels, DispatchContext, DisplayId, Edges, Effect,
- EntityId, EventEmitter, FileDropEvent, FocusEvent, FontId, GlobalElementId, GlyphId, Hsla,
- ImageData, InputEvent, IsZero, KeyListener, KeyMatch, KeyMatcher, Keystroke, LayoutId,
+ Entity, EntityId, EventEmitter, FileDropEvent, FocusEvent, FontId, GlobalElementId, GlyphId,
+ Hsla, ImageData, InputEvent, IsZero, KeyListener, KeyMatch, KeyMatcher, Keystroke, LayoutId,
MainThread, MainThreadOnly, Model, ModelContext, Modifiers, MonochromeSprite, MouseButton,
MouseDownEvent, MouseMoveEvent, MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformWindow,
Point, PolychromeSprite, Quad, Reference, RenderGlyphParams, RenderImageParams,
@@ -1253,7 +1253,7 @@ impl Context for WindowContext<'_, '_> {
self.entities.insert(slot, model)
}
- fn update_entity<T: 'static, R>(
+ fn update_model<T: 'static, R>(
&mut self,
model: &Model<T>,
update: impl FnOnce(&mut T, &mut Self::ModelContext<'_, T>) -> R,
@@ -1568,23 +1568,25 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
self.window_cx.on_next_frame(move |cx| view.update(cx, f));
}
- pub fn observe<E>(
+ pub fn observe<V2, E>(
&mut self,
- handle: &Model<E>,
- mut on_notify: impl FnMut(&mut V, Model<E>, &mut ViewContext<'_, '_, V>) + Send + 'static,
+ entity: &E,
+ mut on_notify: impl FnMut(&mut V, E, &mut ViewContext<'_, '_, V>) + Send + 'static,
) -> Subscription
where
- E: 'static,
+ V2: 'static,
V: Any + Send,
+ E: Entity<V2>,
{
let view = self.view();
- let handle = handle.downgrade();
+ let entity_id = entity.entity_id();
+ let entity = entity.downgrade();
let window_handle = self.window.handle;
self.app.observers.insert(
- handle.entity_id,
+ entity_id,
Box::new(move |cx| {
cx.update_window(window_handle.id, |cx| {
- if let Some(handle) = handle.upgrade() {
+ if let Some(handle) = E::upgrade_from(&entity) {
view.update(cx, |this, cx| on_notify(this, handle, cx))
.is_ok()
} else {
@@ -1596,21 +1598,24 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
)
}
- pub fn subscribe<E: EventEmitter>(
+ pub fn subscribe<V2, E>(
&mut self,
- handle: &Model<E>,
- mut on_event: impl FnMut(&mut V, Model<E>, &E::Event, &mut ViewContext<'_, '_, V>)
- + Send
- + 'static,
- ) -> Subscription {
+ entity: &E,
+ mut on_event: impl FnMut(&mut V, E, &V2::Event, &mut ViewContext<'_, '_, V>) + Send + 'static,
+ ) -> Subscription
+ where
+ V2: EventEmitter,
+ E: Entity<V2>,
+ {
let view = self.view();
- let handle = handle.downgrade();
+ let entity_id = entity.entity_id();
+ let handle = entity.downgrade();
let window_handle = self.window.handle;
self.app.event_listeners.insert(
- handle.entity_id,
+ entity_id,
Box::new(move |event, cx| {
cx.update_window(window_handle.id, |cx| {
- if let Some(handle) = handle.upgrade() {
+ if let Some(handle) = E::upgrade_from(&handle) {
let event = event.downcast_ref().expect("invalid event type");
view.update(cx, |this, cx| on_event(this, handle, event, cx))
.is_ok()
@@ -1638,18 +1643,21 @@ impl<'a, 'w, V: 'static> ViewContext<'a, 'w, V> {
)
}
- pub fn observe_release<T: 'static>(
+ pub fn observe_release<V2, E>(
&mut self,
- handle: &Model<T>,
- mut on_release: impl FnMut(&mut V, &mut T, &mut ViewContext<'_, '_, V>) + Send + 'static,
+ entity: &E,
+ mut on_release: impl FnMut(&mut V, &mut V2, &mut ViewContext<'_, '_, V>) + Send + 'static,
) -> Subscription
where
V: Any + Send,
+ V2: 'static,
+ E: Entity<V2>,
{
let view = self.view();
+ let entity_id = entity.entity_id();
let window_handle = self.window.handle;
self.app.release_listeners.insert(
- handle.entity_id,
+ entity_id,
Box::new(move |entity, cx| {
let entity = entity.downcast_mut().expect("invalid entity type");
let _ = cx.update_window(window_handle.id, |cx| {
@@ -1864,12 +1872,12 @@ impl<'a, 'w, V> Context for ViewContext<'a, 'w, V> {
self.window_cx.build_model(build_model)
}
- fn update_entity<T: 'static, R>(
+ fn update_model<T: 'static, R>(
&mut self,
model: &Model<T>,
update: impl FnOnce(&mut T, &mut Self::ModelContext<'_, T>) -> R,
) -> R {
- self.window_cx.update_entity(model, update)
+ self.window_cx.update_model(model, update)
}
}
@@ -26,8 +26,8 @@ use futures::{
};
use globset::{Glob, GlobSet, GlobSetBuilder};
use gpui2::{
- AnyModel, AppContext, AsyncAppContext, Context, EventEmitter, Executor, Model, ModelContext,
- Task, WeakModel,
+ AnyModel, AppContext, AsyncAppContext, Context, Entity, EventEmitter, Executor, Model,
+ ModelContext, Task, WeakModel,
};
use itertools::Itertools;
use language2::{
@@ -2491,7 +2491,7 @@ impl Project {
delay
} else {
if first_insertion {
- let this = cx.weak_handle();
+ let this = cx.weak_model();
cx.defer(move |cx| {
if let Some(this) = this.upgrade() {
this.update(cx, |this, cx| {
@@ -8650,7 +8650,7 @@ fn subscribe_for_copilot_events(
// Another event wants to re-add the server that was already added and subscribed to, avoid doing it again.
if !copilot_server.has_notification_handler::<copilot2::request::LogMessage>() {
let new_server_id = copilot_server.server_id();
- let weak_project = cx.weak_handle();
+ let weak_project = cx.weak_model();
let copilot_log_subscription = copilot_server
.on_notification::<copilot2::request::LogMessage, _>(
move |params, mut cx| {
@@ -1,5 +1,5 @@
use crate::Project;
-use gpui2::{AnyWindowHandle, Context, Model, ModelContext, WeakModel};
+use gpui2::{AnyWindowHandle, Context, Entity, Model, ModelContext, WeakModel};
use settings2::Settings;
use std::path::{Path, PathBuf};
use terminal2::{