Pass a handle to the current view model when spawning
Most of the time, we'll want a way to get a reference back to the current view or model, so this facilitates that common case.
This commit is contained in:
parent
fa6bd1f926
commit
a3be5595dd
6 changed files with 41 additions and 44 deletions
|
@ -1654,11 +1654,12 @@ impl<'a, T: Entity> ModelContext<'a, T> {
|
||||||
|
|
||||||
pub fn spawn<F, Fut, S>(&self, f: F) -> Task<S>
|
pub fn spawn<F, Fut, S>(&self, f: F) -> Task<S>
|
||||||
where
|
where
|
||||||
F: FnOnce(AsyncAppContext) -> Fut,
|
F: FnOnce(ModelHandle<T>, AsyncAppContext) -> Fut,
|
||||||
Fut: 'static + Future<Output = S>,
|
Fut: 'static + Future<Output = S>,
|
||||||
S: 'static,
|
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<F, Fut, S>(&self, f: F) -> Task<S>
|
pub fn spawn<F, Fut, S>(&self, f: F) -> Task<S>
|
||||||
where
|
where
|
||||||
F: FnOnce(AsyncAppContext) -> Fut,
|
F: FnOnce(ViewHandle<T>, AsyncAppContext) -> Fut,
|
||||||
Fut: 'static + Future<Output = S>,
|
Fut: 'static + Future<Output = S>,
|
||||||
S: 'static,
|
S: 'static,
|
||||||
{
|
{
|
||||||
self.app.spawn(f)
|
let handle = self.handle();
|
||||||
|
self.app.spawn(|ctx| f(handle, ctx))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -477,9 +477,8 @@ impl Buffer {
|
||||||
let snapshot = self.snapshot();
|
let snapshot = self.snapshot();
|
||||||
let version = self.version.clone();
|
let version = self.version.clone();
|
||||||
let file = self.file.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()) {
|
if let Some(file) = new_file.as_ref().or(file.as_ref()) {
|
||||||
let result = ctx.read(|ctx| file.save(snapshot, ctx.as_ref())).await;
|
let result = ctx.read(|ctx| file.save(snapshot, ctx.as_ref())).await;
|
||||||
if result.is_ok() {
|
if result.is_ok() {
|
||||||
|
|
|
@ -2347,10 +2347,9 @@ impl BufferView {
|
||||||
ctx.notify();
|
ctx.notify();
|
||||||
|
|
||||||
let epoch = self.next_blink_epoch();
|
let epoch = self.next_blink_epoch();
|
||||||
let handle = ctx.handle();
|
ctx.spawn(|this, mut ctx| async move {
|
||||||
ctx.spawn(|mut ctx| async move {
|
|
||||||
Timer::after(CURSOR_BLINK_INTERVAL).await;
|
Timer::after(CURSOR_BLINK_INTERVAL).await;
|
||||||
handle.update(&mut ctx, |this, ctx| {
|
this.update(&mut ctx, |this, ctx| {
|
||||||
this.resume_cursor_blinking(epoch, ctx);
|
this.resume_cursor_blinking(epoch, ctx);
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -2370,10 +2369,9 @@ impl BufferView {
|
||||||
ctx.notify();
|
ctx.notify();
|
||||||
|
|
||||||
let epoch = self.next_blink_epoch();
|
let epoch = self.next_blink_epoch();
|
||||||
let handle = ctx.handle();
|
ctx.spawn(|this, mut ctx| async move {
|
||||||
ctx.spawn(|mut ctx| async move {
|
|
||||||
Timer::after(CURSOR_BLINK_INTERVAL).await;
|
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();
|
.detach();
|
||||||
}
|
}
|
||||||
|
|
|
@ -415,10 +415,9 @@ impl FileFinder {
|
||||||
(search_id, did_cancel, query, matches)
|
(search_id, did_cancel, query, matches)
|
||||||
});
|
});
|
||||||
|
|
||||||
let handle = ctx.handle();
|
ctx.spawn(|this, mut ctx| async move {
|
||||||
ctx.spawn(|mut ctx| async move {
|
|
||||||
let matches = background_task.await;
|
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();
|
.detach();
|
||||||
|
|
||||||
|
|
|
@ -359,13 +359,12 @@ impl Workspace {
|
||||||
.cloned()
|
.cloned()
|
||||||
.zip(entries.into_iter())
|
.zip(entries.into_iter())
|
||||||
.map(|(abs_path, file)| {
|
.map(|(abs_path, file)| {
|
||||||
let handle = ctx.handle();
|
|
||||||
let is_file = bg.spawn(async move { abs_path.is_file() });
|
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;
|
let is_file = is_file.await;
|
||||||
handle.update(&mut ctx, |me, ctx| {
|
this.update(&mut ctx, |this, ctx| {
|
||||||
if is_file {
|
if is_file {
|
||||||
me.open_entry(file.entry_id(), ctx)
|
this.open_entry(file.entry_id(), ctx)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -513,8 +512,7 @@ impl Workspace {
|
||||||
|
|
||||||
let mut watch = self.loading_items.get(&entry).unwrap().clone();
|
let mut watch = self.loading_items.get(&entry).unwrap().clone();
|
||||||
|
|
||||||
let handle = ctx.handle();
|
Some(ctx.spawn(|this, mut ctx| async move {
|
||||||
Some(ctx.spawn(|mut ctx| async move {
|
|
||||||
let load_result = loop {
|
let load_result = loop {
|
||||||
if let Some(load_result) = watch.borrow().as_ref() {
|
if let Some(load_result) = watch.borrow().as_ref() {
|
||||||
break load_result.clone();
|
break load_result.clone();
|
||||||
|
@ -522,16 +520,16 @@ impl Workspace {
|
||||||
watch.next().await;
|
watch.next().await;
|
||||||
};
|
};
|
||||||
|
|
||||||
handle.update(&mut ctx, |me, ctx| {
|
this.update(&mut ctx, |this, ctx| {
|
||||||
me.loading_items.remove(&entry);
|
this.loading_items.remove(&entry);
|
||||||
match load_result {
|
match load_result {
|
||||||
Ok(item) => {
|
Ok(item) => {
|
||||||
let weak_item = item.downgrade();
|
let weak_item = item.downgrade();
|
||||||
let view = weak_item
|
let view = weak_item
|
||||||
.add_view(ctx.window_id(), settings, ctx.as_mut())
|
.add_view(ctx.window_id(), settings, ctx.as_mut())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
me.items.push(weak_item);
|
this.items.push(weak_item);
|
||||||
me.add_item_view(view, ctx);
|
this.add_item_view(view, ctx);
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
log::error!("error opening item: {}", error);
|
log::error!("error opening item: {}", error);
|
||||||
|
|
|
@ -98,20 +98,23 @@ impl Worktree {
|
||||||
scanner.run(event_stream)
|
scanner.run(event_stream)
|
||||||
});
|
});
|
||||||
|
|
||||||
let handle = ctx.handle().downgrade();
|
ctx.spawn(|this, mut ctx| {
|
||||||
ctx.spawn(|mut ctx| async move {
|
let this = this.downgrade();
|
||||||
while let Ok(scan_state) = scan_state_rx.recv().await {
|
async move {
|
||||||
let alive = ctx.update(|ctx| {
|
while let Ok(scan_state) = scan_state_rx.recv().await {
|
||||||
if let Some(handle) = handle.upgrade(&ctx) {
|
let alive = ctx.update(|ctx| {
|
||||||
handle.update(ctx, |this, ctx| this.observe_scan_state(scan_state, ctx));
|
if let Some(handle) = this.upgrade(&ctx) {
|
||||||
true
|
handle
|
||||||
} else {
|
.update(ctx, |this, ctx| this.observe_scan_state(scan_state, ctx));
|
||||||
false
|
true
|
||||||
}
|
} else {
|
||||||
});
|
false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if !alive {
|
if !alive {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -133,10 +136,9 @@ impl Worktree {
|
||||||
pub fn next_scan_complete(&self, ctx: &mut ModelContext<Self>) -> impl Future<Output = ()> {
|
pub fn next_scan_complete(&self, ctx: &mut ModelContext<Self>) -> impl Future<Output = ()> {
|
||||||
let scan_id = self.snapshot.scan_id;
|
let scan_id = self.snapshot.scan_id;
|
||||||
let mut scan_state = self.scan_state.1.clone();
|
let mut scan_state = self.scan_state.1.clone();
|
||||||
let handle = ctx.handle();
|
ctx.spawn(|this, ctx| async move {
|
||||||
ctx.spawn(|ctx| async move {
|
|
||||||
while let Some(scan_state) = scan_state.recv().await {
|
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
|
matches!(scan_state, ScanState::Idle) && this.snapshot.scan_id > scan_id
|
||||||
}) {
|
}) {
|
||||||
break;
|
break;
|
||||||
|
@ -155,9 +157,8 @@ impl Worktree {
|
||||||
ctx.notify();
|
ctx.notify();
|
||||||
|
|
||||||
if self.is_scanning() && !self.poll_scheduled {
|
if self.is_scanning() && !self.poll_scheduled {
|
||||||
let handle = ctx.handle();
|
ctx.spawn(|this, mut ctx| async move {
|
||||||
ctx.spawn(|mut ctx| async move {
|
this.update(&mut ctx, |this, ctx| {
|
||||||
handle.update(&mut ctx, |this, ctx| {
|
|
||||||
this.poll_scheduled = false;
|
this.poll_scheduled = false;
|
||||||
this.poll_entries(ctx);
|
this.poll_entries(ctx);
|
||||||
})
|
})
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue