diff --git a/gpui/src/app.rs b/gpui/src/app.rs index 3bcccef47c..4a99d712c7 100644 --- a/gpui/src/app.rs +++ b/gpui/src/app.rs @@ -1654,11 +1654,12 @@ impl<'a, T: Entity> ModelContext<'a, T> { pub fn spawn(&self, f: F) -> Task where - F: FnOnce(AsyncAppContext) -> Fut, + F: FnOnce(ModelHandle, AsyncAppContext) -> Fut, Fut: 'static + Future, S: 'static, { - self.app.spawn(f) + let handle = self.handle(); + self.app.spawn(|ctx| f(handle, ctx)) } } @@ -1909,11 +1910,12 @@ impl<'a, T: View> ViewContext<'a, T> { pub fn spawn(&self, f: F) -> Task where - F: FnOnce(AsyncAppContext) -> Fut, + F: FnOnce(ViewHandle, AsyncAppContext) -> Fut, Fut: 'static + Future, S: 'static, { - self.app.spawn(f) + let handle = self.handle(); + self.app.spawn(|ctx| f(handle, ctx)) } } diff --git a/zed/src/editor/buffer/mod.rs b/zed/src/editor/buffer/mod.rs index 5d039fdc99..2ad1574498 100644 --- a/zed/src/editor/buffer/mod.rs +++ b/zed/src/editor/buffer/mod.rs @@ -477,9 +477,8 @@ impl Buffer { let snapshot = self.snapshot(); let version = self.version.clone(); let file = self.file.clone(); - let handle = ctx.handle(); - ctx.spawn(|mut ctx| async move { + ctx.spawn(|handle, mut ctx| async move { if let Some(file) = new_file.as_ref().or(file.as_ref()) { let result = ctx.read(|ctx| file.save(snapshot, ctx.as_ref())).await; if result.is_ok() { diff --git a/zed/src/editor/buffer_view.rs b/zed/src/editor/buffer_view.rs index cc22d8dcc8..df8d447a4a 100644 --- a/zed/src/editor/buffer_view.rs +++ b/zed/src/editor/buffer_view.rs @@ -2347,10 +2347,9 @@ impl BufferView { ctx.notify(); let epoch = self.next_blink_epoch(); - let handle = ctx.handle(); - ctx.spawn(|mut ctx| async move { + ctx.spawn(|this, mut ctx| async move { Timer::after(CURSOR_BLINK_INTERVAL).await; - handle.update(&mut ctx, |this, ctx| { + this.update(&mut ctx, |this, ctx| { this.resume_cursor_blinking(epoch, ctx); }) }) @@ -2370,10 +2369,9 @@ impl BufferView { ctx.notify(); let epoch = self.next_blink_epoch(); - let handle = ctx.handle(); - ctx.spawn(|mut ctx| async move { + ctx.spawn(|this, mut ctx| async move { Timer::after(CURSOR_BLINK_INTERVAL).await; - handle.update(&mut ctx, |this, ctx| this.blink_cursors(epoch, ctx)); + this.update(&mut ctx, |this, ctx| this.blink_cursors(epoch, ctx)); }) .detach(); } diff --git a/zed/src/file_finder.rs b/zed/src/file_finder.rs index 0dc96e52fc..691bf4ae3f 100644 --- a/zed/src/file_finder.rs +++ b/zed/src/file_finder.rs @@ -415,10 +415,9 @@ impl FileFinder { (search_id, did_cancel, query, matches) }); - let handle = ctx.handle(); - ctx.spawn(|mut ctx| async move { + ctx.spawn(|this, mut ctx| async move { let matches = background_task.await; - handle.update(&mut ctx, |this, ctx| this.update_matches(matches, ctx)); + this.update(&mut ctx, |this, ctx| this.update_matches(matches, ctx)); }) .detach(); diff --git a/zed/src/workspace.rs b/zed/src/workspace.rs index 81e5b345ae..87f52e486a 100644 --- a/zed/src/workspace.rs +++ b/zed/src/workspace.rs @@ -359,13 +359,12 @@ impl Workspace { .cloned() .zip(entries.into_iter()) .map(|(abs_path, file)| { - let handle = ctx.handle(); let is_file = bg.spawn(async move { abs_path.is_file() }); - ctx.spawn(|mut ctx| async move { + ctx.spawn(|this, mut ctx| async move { let is_file = is_file.await; - handle.update(&mut ctx, |me, ctx| { + this.update(&mut ctx, |this, ctx| { if is_file { - me.open_entry(file.entry_id(), ctx) + this.open_entry(file.entry_id(), ctx) } else { None } @@ -513,8 +512,7 @@ impl Workspace { let mut watch = self.loading_items.get(&entry).unwrap().clone(); - let handle = ctx.handle(); - Some(ctx.spawn(|mut ctx| async move { + Some(ctx.spawn(|this, mut ctx| async move { let load_result = loop { if let Some(load_result) = watch.borrow().as_ref() { break load_result.clone(); @@ -522,16 +520,16 @@ impl Workspace { watch.next().await; }; - handle.update(&mut ctx, |me, ctx| { - me.loading_items.remove(&entry); + this.update(&mut ctx, |this, ctx| { + this.loading_items.remove(&entry); match load_result { Ok(item) => { let weak_item = item.downgrade(); let view = weak_item .add_view(ctx.window_id(), settings, ctx.as_mut()) .unwrap(); - me.items.push(weak_item); - me.add_item_view(view, ctx); + this.items.push(weak_item); + this.add_item_view(view, ctx); } Err(error) => { log::error!("error opening item: {}", error); diff --git a/zed/src/worktree.rs b/zed/src/worktree.rs index 55d8f91b99..80da089cf5 100644 --- a/zed/src/worktree.rs +++ b/zed/src/worktree.rs @@ -98,20 +98,23 @@ impl Worktree { scanner.run(event_stream) }); - let handle = ctx.handle().downgrade(); - ctx.spawn(|mut ctx| async move { - while let Ok(scan_state) = scan_state_rx.recv().await { - let alive = ctx.update(|ctx| { - if let Some(handle) = handle.upgrade(&ctx) { - handle.update(ctx, |this, ctx| this.observe_scan_state(scan_state, ctx)); - true - } else { - false - } - }); + ctx.spawn(|this, mut ctx| { + let this = this.downgrade(); + async move { + while let Ok(scan_state) = scan_state_rx.recv().await { + let alive = ctx.update(|ctx| { + if let Some(handle) = this.upgrade(&ctx) { + handle + .update(ctx, |this, ctx| this.observe_scan_state(scan_state, ctx)); + true + } else { + false + } + }); - if !alive { - break; + if !alive { + break; + } } } }) @@ -133,10 +136,9 @@ impl Worktree { pub fn next_scan_complete(&self, ctx: &mut ModelContext) -> impl Future { let scan_id = self.snapshot.scan_id; let mut scan_state = self.scan_state.1.clone(); - let handle = ctx.handle(); - ctx.spawn(|ctx| async move { + ctx.spawn(|this, ctx| async move { while let Some(scan_state) = scan_state.recv().await { - if handle.read_with(&ctx, |this, _| { + if this.read_with(&ctx, |this, _| { matches!(scan_state, ScanState::Idle) && this.snapshot.scan_id > scan_id }) { break; @@ -155,9 +157,8 @@ impl Worktree { ctx.notify(); if self.is_scanning() && !self.poll_scheduled { - let handle = ctx.handle(); - ctx.spawn(|mut ctx| async move { - handle.update(&mut ctx, |this, ctx| { + ctx.spawn(|this, mut ctx| async move { + this.update(&mut ctx, |this, ctx| { this.poll_scheduled = false; this.poll_entries(ctx); })