diff --git a/gpui/src/app.rs b/gpui/src/app.rs index 125f749c53e8729e97b1d495f204da7dd3094f4d..20560fe6fedacfc3db96bf78c421d3c21ac7a179 100644 --- a/gpui/src/app.rs +++ b/gpui/src/app.rs @@ -967,7 +967,7 @@ impl MutableAppContext { self.flush_effects(); } - fn spawn(&mut self, future: F) -> EntityTask> + fn spawn(&mut self, future: F) -> EntityTask where F: 'static + Future, T: 'static, @@ -978,9 +978,10 @@ impl MutableAppContext { let app = app.clone(); self.foreground.spawn(async move { let output = future.await; - app.borrow_mut() + *app.borrow_mut() .handle_future_output(task_id, Box::new(output)) - .map(|result| *result.downcast::().unwrap()) + .downcast::() + .unwrap() }) }; EntityTask::new( @@ -991,35 +992,33 @@ impl MutableAppContext { ) } - fn spawn_stream(&mut self, mut stream: F) -> EntityTask> + fn spawn_stream(&mut self, mut stream: F) -> EntityTask where F: 'static + Stream + Unpin, T: 'static, { let task_id = post_inc(&mut self.next_task_id); let app = self.weak_self.as_ref().unwrap().upgrade().unwrap(); - let task = { - let app = app.clone(); - self.foreground.spawn(async move { - loop { - match stream.next().await { - Some(item) => { - let mut app = app.borrow_mut(); - if app.handle_stream_item(task_id, Box::new(item)) { - break; - } - } - None => { + let task = self.foreground.spawn(async move { + loop { + match stream.next().await { + Some(item) => { + let mut app = app.borrow_mut(); + if app.handle_stream_item(task_id, Box::new(item)) { break; } } + None => { + break; + } } + } - app.borrow_mut() - .stream_completed(task_id) - .map(|result| *result.downcast::().unwrap()) - }) - }; + *app.borrow_mut() + .stream_completed(task_id) + .downcast::() + .unwrap() + }); EntityTask::new( task_id, @@ -1029,45 +1028,10 @@ impl MutableAppContext { ) } - fn handle_future_output( - &mut self, - task_id: usize, - output: Box, - ) -> Option> { + fn handle_future_output(&mut self, task_id: usize, output: Box) -> Box { self.pending_flushes += 1; let future_callback = self.future_handlers.borrow_mut().remove(&task_id).unwrap(); - - let mut result = None; - - match future_callback { - FutureHandler::Model { model_id, callback } => { - if let Some(mut model) = self.ctx.models.remove(&model_id) { - result = Some(callback(model.as_any_mut(), output, self, model_id)); - self.ctx.models.insert(model_id, model); - } - } - FutureHandler::View { - window_id, - view_id, - callback, - } => { - if let Some(mut view) = self - .ctx - .windows - .get_mut(&window_id) - .and_then(|w| w.views.remove(&view_id)) - { - result = Some(callback(view.as_mut(), output, self, window_id, view_id)); - self.ctx - .windows - .get_mut(&window_id) - .unwrap() - .views - .insert(view_id, view); - } - } - }; - + let result = future_callback(output, self); self.flush_effects(); self.task_done.notify_all(); result @@ -1077,95 +1041,18 @@ impl MutableAppContext { self.pending_flushes += 1; let mut handler = self.stream_handlers.borrow_mut().remove(&task_id).unwrap(); - let halt = match &mut handler { - StreamHandler::Model { - model_id, - item_callback, - .. - } => { - if let Some(mut model) = self.ctx.models.remove(&model_id) { - let halt = item_callback(model.as_any_mut(), output, self, *model_id); - self.ctx.models.insert(*model_id, model); - self.stream_handlers.borrow_mut().insert(task_id, handler); - halt - } else { - true - } - } - StreamHandler::View { - window_id, - view_id, - item_callback, - .. - } => { - if let Some(mut view) = self - .ctx - .windows - .get_mut(&window_id) - .and_then(|w| w.views.remove(&view_id)) - { - let halt = item_callback(view.as_mut(), output, self, *window_id, *view_id); - self.ctx - .windows - .get_mut(&window_id) - .unwrap() - .views - .insert(*view_id, view); - self.stream_handlers.borrow_mut().insert(task_id, handler); - halt - } else { - true - } - } - }; + let halt = (handler.item_callback)(output, self); + self.stream_handlers.borrow_mut().insert(task_id, handler); self.flush_effects(); halt } - fn stream_completed(&mut self, task_id: usize) -> Option> { + fn stream_completed(&mut self, task_id: usize) -> Box { self.pending_flushes += 1; - let stream_handler = self.stream_handlers.borrow_mut().remove(&task_id).unwrap(); - let result = match stream_handler { - StreamHandler::Model { - model_id, - done_callback, - .. - } => { - if let Some(mut model) = self.ctx.models.remove(&model_id) { - let result = done_callback(model.as_any_mut(), self, model_id); - self.ctx.models.insert(model_id, model); - Some(result) - } else { - None - } - } - StreamHandler::View { - window_id, - view_id, - done_callback, - .. - } => { - if let Some(mut view) = self - .ctx - .windows - .get_mut(&window_id) - .and_then(|w| w.views.remove(&view_id)) - { - let result = done_callback(view.as_mut(), self, window_id, view_id); - self.ctx - .windows - .get_mut(&window_id) - .unwrap() - .views - .insert(view_id, view); - Some(result) - } else { - None - } - } - }; + let handler = self.stream_handlers.borrow_mut().remove(&task_id).unwrap(); + let result = (handler.done_callback)(self); self.flush_effects(); self.task_done.notify_all(); @@ -1562,28 +1449,25 @@ impl<'a, T: Entity> ModelContext<'a, T> { }); } - pub fn spawn(&mut self, future: S, callback: F) -> EntityTask> + fn handle(&self) -> ModelHandle { + ModelHandle::new(self.model_id, &self.app.ctx.ref_counts) + } + + pub fn spawn(&mut self, future: S, callback: F) -> EntityTask where S: 'static + Future, F: 'static + FnOnce(&mut T, S::Output, &mut ModelContext) -> U, U: 'static, { + let handle = self.handle(); let task = self.app.spawn::(future); self.app.future_handlers.borrow_mut().insert( task.id, - FutureHandler::Model { - model_id: self.model_id, - callback: Box::new(move |model, output, app, model_id| { - let model = model.downcast_mut().unwrap(); - let output = *output.downcast().unwrap(); - Box::new(callback( - model, - output, - &mut ModelContext::new(app, model_id), - )) - }), - }, + Box::new(move |output, ctx| { + let output = *output.downcast().unwrap(); + handle.update(ctx, |model, ctx| Box::new(callback(model, output, ctx))) + }), ); task @@ -1594,32 +1478,32 @@ impl<'a, T: Entity> ModelContext<'a, T> { stream: S, mut item_callback: F, done_callback: G, - ) -> EntityTask> + ) -> EntityTask where S: 'static + Stream + Unpin, F: 'static + FnMut(&mut T, S::Item, &mut ModelContext), G: 'static + FnOnce(&mut T, &mut ModelContext) -> U, U: 'static + Any, { + let handle = self.handle(); let task = self.app.spawn_stream(stream); + self.app.stream_handlers.borrow_mut().insert( task.id, - StreamHandler::Model { - model_id: self.model_id, - item_callback: Box::new(move |model, output, app, model_id| { - let model = model.downcast_mut().unwrap(); - let output = *output.downcast().unwrap(); - let mut ctx = ModelContext::new(app, model_id); - item_callback(model, output, &mut ctx); - ctx.halt_stream + StreamHandler { + item_callback: { + let handle = handle.clone(); + Box::new(move |output, app| { + let output = *output.downcast().unwrap(); + handle.update(app, |model, ctx| { + item_callback(model, output, ctx); + ctx.halt_stream + }) + }) + }, + done_callback: Box::new(move |app| { + handle.update(app, |model, ctx| Box::new(done_callback(model, ctx))) }), - done_callback: Box::new( - move |model: &mut dyn Any, app: &mut MutableAppContext, model_id| { - let model = model.downcast_mut().unwrap(); - let mut ctx = ModelContext::new(app, model_id); - Box::new(done_callback(model, &mut ctx)) - }, - ), }, ); @@ -1664,8 +1548,8 @@ impl<'a, T: View> ViewContext<'a, T> { } } - pub fn handle(&self) -> WeakViewHandle { - WeakViewHandle::new(self.window_id, self.view_id) + pub fn handle(&self) -> ViewHandle { + ViewHandle::new(self.window_id, self.view_id, &self.app.ctx.ref_counts) } pub fn window_id(&self) -> usize { @@ -1822,29 +1706,21 @@ impl<'a, T: View> ViewContext<'a, T> { self.halt_stream = true; } - pub fn spawn(&mut self, future: S, callback: F) -> EntityTask> + pub fn spawn(&mut self, future: S, callback: F) -> EntityTask where S: 'static + Future, F: 'static + FnOnce(&mut T, S::Output, &mut ViewContext) -> U, U: 'static, { + let handle = self.handle(); let task = self.app.spawn(future); self.app.future_handlers.borrow_mut().insert( task.id, - FutureHandler::View { - window_id: self.window_id, - view_id: self.view_id, - callback: Box::new(move |view, output, app, window_id, view_id| { - let view = view.as_any_mut().downcast_mut().unwrap(); - let output = *output.downcast().unwrap(); - Box::new(callback( - view, - output, - &mut ViewContext::new(app, window_id, view_id), - )) - }), - }, + Box::new(move |output, app| { + let output = *output.downcast().unwrap(); + handle.update(app, |view, ctx| Box::new(callback(view, output, ctx))) + }), ); task @@ -1855,30 +1731,30 @@ impl<'a, T: View> ViewContext<'a, T> { stream: S, mut item_callback: F, done_callback: G, - ) -> EntityTask> + ) -> EntityTask where S: 'static + Stream + Unpin, F: 'static + FnMut(&mut T, S::Item, &mut ViewContext), G: 'static + FnOnce(&mut T, &mut ViewContext) -> U, U: 'static + Any, { + let handle = self.handle(); let task = self.app.spawn_stream(stream); self.app.stream_handlers.borrow_mut().insert( task.id, - StreamHandler::View { - window_id: self.window_id, - view_id: self.view_id, - item_callback: Box::new(move |view, output, app, window_id, view_id| { - let view = view.as_any_mut().downcast_mut().unwrap(); - let output = *output.downcast().unwrap(); - let mut ctx = ViewContext::new(app, window_id, view_id); - item_callback(view, output, &mut ctx); - ctx.halt_stream - }), - done_callback: Box::new(move |view, app, window_id, view_id| { - let view = view.as_any_mut().downcast_mut().unwrap(); - let mut ctx = ViewContext::new(app, window_id, view_id); - Box::new(done_callback(view, &mut ctx)) + StreamHandler { + item_callback: { + let handle = handle.clone(); + Box::new(move |output, app| { + let output = *output.downcast().unwrap(); + handle.update(app, |view, ctx| { + item_callback(view, output, ctx); + ctx.halt_stream + }) + }) + }, + done_callback: Box::new(move |app| { + handle.update(app, |view, ctx| Box::new(done_callback(view, ctx))) }), }, ); @@ -2076,7 +1952,7 @@ impl ViewHandle { } } - fn downgrade(&self) -> WeakViewHandle { + pub fn downgrade(&self) -> WeakViewHandle { WeakViewHandle::new(self.window_id, self.view_id) } @@ -2322,44 +2198,11 @@ enum Observation { }, } -enum FutureHandler { - Model { - model_id: usize, - callback: Box< - dyn FnOnce(&mut dyn Any, Box, &mut MutableAppContext, usize) -> Box, - >, - }, - View { - window_id: usize, - view_id: usize, - callback: Box< - dyn FnOnce( - &mut dyn AnyView, - Box, - &mut MutableAppContext, - usize, - usize, - ) -> Box, - >, - }, -} +type FutureHandler = Box, &mut MutableAppContext) -> Box>; -enum StreamHandler { - Model { - model_id: usize, - item_callback: - Box, &mut MutableAppContext, usize) -> bool>, - done_callback: Box Box>, - }, - View { - window_id: usize, - view_id: usize, - item_callback: Box< - dyn FnMut(&mut dyn AnyView, Box, &mut MutableAppContext, usize, usize) -> bool, - >, - done_callback: - Box Box>, - }, +struct StreamHandler { + item_callback: Box, &mut MutableAppContext) -> bool>, + done_callback: Box Box>, } #[must_use] diff --git a/zed/src/editor/buffer_view.rs b/zed/src/editor/buffer_view.rs index f744ee8a19bf6d53dd48b3b61626f407eff61d20..d0861fa92a8d88536232fc2a9ec7cfd8989f0eeb 100644 --- a/zed/src/editor/buffer_view.rs +++ b/zed/src/editor/buffer_view.rs @@ -138,7 +138,7 @@ impl BufferView { let buffer_ref = buffer.as_ref(ctx); Self { - handle: ctx.handle(), + handle: ctx.handle().downgrade(), buffer, display_map, selections: vec![Selection { diff --git a/zed/src/file_finder.rs b/zed/src/file_finder.rs index 354a0b464136f1ddddfb0c8345a4a744523dd082..296e910b6331bcb4bf1daf481b64ca38981fad62 100644 --- a/zed/src/file_finder.rs +++ b/zed/src/file_finder.rs @@ -275,7 +275,7 @@ impl FileFinder { settings.notify_view_on_change(ctx); Self { - handle: ctx.handle(), + handle: ctx.handle().downgrade(), settings, workspace, query_buffer,