Misc GPUI Entity<T> cleanups (#28996)

Found these while working on a `.rules` file which explains how GPUI
works.

Release Notes:

- N/A
This commit is contained in:
Michael Sloan 2025-04-17 17:29:19 -06:00 committed by GitHub
parent 676cc109a3
commit 7cf4926130
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 19 additions and 38 deletions

View file

@ -505,8 +505,8 @@ impl App {
self.new_observer(
entity_id,
Box::new(move |cx| {
if let Some(handle) = Entity::<W>::upgrade_from(&handle) {
on_notify(handle, cx)
if let Some(entity) = handle.upgrade() {
on_notify(entity, cx)
} else {
false
}
@ -550,15 +550,15 @@ impl App {
Evt: 'static,
{
let entity_id = entity.entity_id();
let entity = entity.downgrade();
let handle = entity.downgrade();
self.new_subscription(
entity_id,
(
TypeId::of::<Evt>(),
Box::new(move |event, cx| {
let event: &Evt = event.downcast_ref().expect("invalid event type");
if let Some(handle) = Entity::<T>::upgrade_from(&entity) {
on_event(handle, event, cx)
if let Some(entity) = handle.upgrade() {
on_event(entity, event, cx)
} else {
false
}

View file

@ -212,7 +212,7 @@ impl<'a, T: 'static> Context<'a, T> {
/// Convenience method for accessing view state in an event callback.
///
/// Many GPUI callbacks take the form of `Fn(&E, &mut Window, &mut AppContext)`,
/// Many GPUI callbacks take the form of `Fn(&E, &mut Window, &mut App)`,
/// but it's often useful to be able to access view state in these
/// callbacks. This method provides a convenient way to do so.
pub fn listener<E: ?Sized>(
@ -608,8 +608,8 @@ impl<'a, T: 'static> Context<'a, T> {
}
/// Schedule a future to be run asynchronously.
/// The given callback is invoked with a [`WeakEntity<V>`] to avoid leaking the view for a long-running process.
/// It's also given an [`AsyncWindowContext`], which can be used to access the state of the view across await points.
/// The given callback is invoked with a [`WeakEntity<V>`] to avoid leaking the entity for a long-running process.
/// It's also given an [`AsyncWindowContext`], which can be used to access the state of the entity across await points.
/// The returned future will be polled on the main thread.
#[track_caller]
pub fn spawn_in<AsyncFn, R>(&self, window: &Window, f: AsyncFn) -> Task<R>

View file

@ -409,17 +409,6 @@ impl<T: 'static> Entity<T> {
}
}
/// Upgrade the given weak pointer to a retaining pointer, if it still exists
pub fn upgrade_from(weak: &WeakEntity<T>) -> Option<Self>
where
Self: Sized,
{
Some(Entity {
any_entity: weak.any_entity.upgrade()?,
entity_type: weak.entity_type,
})
}
/// Convert this into a dynamically typed entity.
pub fn into_any(self) -> AnyEntity {
self.any_entity
@ -440,32 +429,22 @@ impl<T: 'static> Entity<T> {
}
/// Updates the entity referenced by this handle with the given function.
///
/// The update function receives a context appropriate for its environment.
/// When updating in an `App`, it receives a `Context`.
/// When updating in a `Window`, it receives a `Window` and a `Context`.
pub fn update<C, R>(
pub fn update<R, C: AppContext>(
&self,
cx: &mut C,
update: impl FnOnce(&mut T, &mut Context<T>) -> R,
) -> C::Result<R>
where
C: AppContext,
{
) -> C::Result<R> {
cx.update_entity(self, update)
}
/// Updates the entity referenced by this handle with the given function if
/// the referenced entity still exists, within a visual context that has a window.
/// Returns an error if the entity has been released.
pub fn update_in<C, R>(
pub fn update_in<R, C: VisualContext>(
&self,
cx: &mut C,
update: impl FnOnce(&mut T, &mut Window, &mut Context<T>) -> R,
) -> C::Result<R>
where
C: VisualContext,
{
) -> C::Result<R> {
cx.update_window_entity(self, update)
}
}
@ -669,8 +648,10 @@ impl<T> Clone for WeakEntity<T> {
impl<T: 'static> WeakEntity<T> {
/// Upgrade this weak entity reference into a strong entity reference
pub fn upgrade(&self) -> Option<Entity<T>> {
// Delegate to the trait implementation to keep behavior in one place.
Entity::upgrade_from(self)
Some(Entity {
any_entity: self.any_entity.upgrade()?,
entity_type: self.entity_type,
})
}
/// Updates the entity referenced by this handle with the given function if

View file

@ -1222,7 +1222,7 @@ impl Window {
Evt: 'static,
{
let entity_id = entity.entity_id();
let entity = entity.downgrade();
let handle = entity.downgrade();
let window_handle = self.handle;
cx.new_subscription(
entity_id,
@ -1231,9 +1231,9 @@ impl Window {
Box::new(move |event, cx| {
window_handle
.update(cx, |_, window, cx| {
if let Some(handle) = Entity::<Emitter>::upgrade_from(&entity) {
if let Some(entity) = handle.upgrade() {
let event = event.downcast_ref().expect("invalid event type");
on_event(handle, event, window, cx);
on_event(entity, event, window, cx);
true
} else {
false