This commit is contained in:
Antonio Scandurra 2023-11-01 18:34:51 +01:00
parent c3a8bab4d2
commit 337a79e35f
5 changed files with 56 additions and 72 deletions

View file

@ -504,16 +504,12 @@ impl AppContext {
/// Spawns the future returned by the given function on the thread pool. The closure will be invoked /// Spawns the future returned by the given function on the thread pool. The closure will be invoked
/// with AsyncAppContext, which allows the application state to be accessed across await points. /// with AsyncAppContext, which allows the application state to be accessed across await points.
pub fn spawn<Fut, R>(&self, f: impl FnOnce(AsyncAppContext) -> Fut + Send + 'static) -> Task<R> pub fn spawn<Fut, R>(&self, f: impl FnOnce(AsyncAppContext) -> Fut) -> Task<R>
where where
Fut: Future<Output = R> + Send + 'static, Fut: Future<Output = R> + Send + 'static,
R: Send + 'static, R: Send + 'static,
{ {
let cx = self.to_async(); self.executor.spawn(f(self.to_async()))
self.executor.spawn(async move {
let future = f(cx);
future.await
})
} }
/// Schedules the given function to be run at the end of the current effect cycle, allowing entities /// Schedules the given function to be run at the end of the current effect cycle, allowing entities

View file

@ -189,10 +189,7 @@ impl<'a, T: 'static> ModelContext<'a, T> {
result result
} }
pub fn spawn<Fut, R>( pub fn spawn<Fut, R>(&self, f: impl FnOnce(WeakModel<T>, AsyncAppContext) -> Fut) -> Task<R>
&self,
f: impl FnOnce(WeakModel<T>, AsyncAppContext) -> Fut + Send + 'static,
) -> Task<R>
where where
T: 'static, T: 'static,
Fut: Future<Output = R> + Send + 'static, Fut: Future<Output = R> + Send + 'static,

View file

@ -484,7 +484,7 @@ impl<'a> WindowContext<'a> {
/// use within your future. /// use within your future.
pub fn spawn<Fut, R>( pub fn spawn<Fut, R>(
&mut self, &mut self,
f: impl FnOnce(AnyWindowHandle, AsyncWindowContext) -> Fut + Send + 'static, f: impl FnOnce(AnyWindowHandle, AsyncWindowContext) -> Fut,
) -> Task<R> ) -> Task<R>
where where
R: Send + 'static, R: Send + 'static,
@ -493,8 +493,7 @@ impl<'a> WindowContext<'a> {
let window = self.window.handle; let window = self.window.handle;
self.app.spawn(move |app| { self.app.spawn(move |app| {
let cx = AsyncWindowContext::new(app, window); let cx = AsyncWindowContext::new(app, window);
let future = f(window, cx); f(window, cx)
async move { future.await }
}) })
} }
@ -1872,17 +1871,14 @@ impl<'a, V: 'static> ViewContext<'a, V> {
pub fn spawn<Fut, R>( pub fn spawn<Fut, R>(
&mut self, &mut self,
f: impl FnOnce(WeakView<V>, AsyncWindowContext) -> Fut + Send + 'static, f: impl FnOnce(WeakView<V>, AsyncWindowContext) -> Fut,
) -> Task<R> ) -> Task<R>
where where
R: Send + 'static, R: Send + 'static,
Fut: Future<Output = R> + Send + 'static, Fut: Future<Output = R> + Send + 'static,
{ {
let view = self.view().downgrade(); let view = self.view().downgrade();
self.window_cx.spawn(move |_, cx| { self.window_cx.spawn(move |_, cx| f(view, cx))
let result = f(view, cx);
async move { result.await }
})
} }
pub fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R pub fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R

View file

@ -7,7 +7,9 @@ use db2::sqlez::{
bindable::{Bind, Column, StaticColumnCount}, bindable::{Bind, Column, StaticColumnCount},
statement::Statement, statement::Statement,
}; };
use gpui2::{AsyncWindowContext, Model, Task, View, WeakView, WindowBounds}; use gpui2::{
AsyncAppContext, AsyncWindowContext, Model, Task, View, WeakView, WindowBounds, WindowHandle,
};
use project2::Project; use project2::Project;
use std::{ use std::{
path::{Path, PathBuf}, path::{Path, PathBuf},
@ -153,8 +155,8 @@ impl SerializedPaneGroup {
self, self,
project: &Model<Project>, project: &Model<Project>,
workspace_id: WorkspaceId, workspace_id: WorkspaceId,
workspace: &WeakView<Workspace>, workspace: WindowHandle<Workspace>,
cx: &mut AsyncWindowContext, cx: &mut AsyncAppContext,
) -> Option<(Member, Option<View<Pane>>, Vec<Option<Box<dyn ItemHandle>>>)> { ) -> Option<(Member, Option<View<Pane>>, Vec<Option<Box<dyn ItemHandle>>>)> {
match self { match self {
SerializedPaneGroup::Group { SerializedPaneGroup::Group {
@ -231,8 +233,8 @@ impl SerializedPane {
project: &Model<Project>, project: &Model<Project>,
pane: &WeakView<Pane>, pane: &WeakView<Pane>,
workspace_id: WorkspaceId, workspace_id: WorkspaceId,
workspace: &WeakView<Workspace>, workspace: WindowHandle<Workspace>,
cx: &mut AsyncWindowContext, cx: &mut AsyncAppContext,
) -> Result<Vec<Option<Box<dyn ItemHandle>>>> { ) -> Result<Vec<Option<Box<dyn ItemHandle>>>> {
let mut items = Vec::new(); let mut items = Vec::new();
let mut active_item_index = None; let mut active_item_index = None;
@ -241,7 +243,7 @@ impl SerializedPane {
let item_handle = pane let item_handle = pane
.update(cx, |_, cx| { .update(cx, |_, cx| {
if let Some(deserializer) = cx.global::<ItemDeserializers>().get(&item.kind) { if let Some(deserializer) = cx.global::<ItemDeserializers>().get(&item.kind) {
deserializer(project, workspace.clone(), workspace_id, item.item_id, cx) deserializer(project, workspace, workspace_id, item.item_id, cx)
} else { } else {
Task::ready(Err(anyhow::anyhow!( Task::ready(Err(anyhow::anyhow!(
"Deserializer does not exist for item kind: {}", "Deserializer does not exist for item kind: {}",

View file

@ -29,9 +29,9 @@ use futures::{
}; };
use gpui2::{ use gpui2::{
div, point, size, AnyModel, AnyView, AppContext, AsyncAppContext, AsyncWindowContext, Bounds, div, point, size, AnyModel, AnyView, AppContext, AsyncAppContext, AsyncWindowContext, Bounds,
Context, Div, EventEmitter, GlobalPixels, MainThread, Model, ModelContext, Point, Render, Size, Context, Div, Entity, EventEmitter, GlobalPixels, MainThread, Model, ModelContext, Point,
Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowBounds, WindowContext, Render, Size, Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowBounds,
WindowHandle, WindowOptions, WindowContext, WindowHandle, WindowOptions,
}; };
use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ProjectItem}; use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ProjectItem};
use language2::LanguageRegistry; use language2::LanguageRegistry;
@ -399,7 +399,7 @@ type ItemDeserializers = HashMap<
Arc<str>, Arc<str>,
fn( fn(
Model<Project>, Model<Project>,
WeakView<Workspace>, WindowHandle<Workspace>,
WorkspaceId, WorkspaceId,
ItemId, ItemId,
&mut ViewContext<Pane>, &mut ViewContext<Pane>,
@ -891,19 +891,22 @@ impl Workspace {
window.update(&mut cx, |_, cx| cx.activate_window()); window.update(&mut cx, |_, cx| cx.activate_window());
let workspace = workspace.downgrade(); notify_if_database_failed(window, &mut cx);
notify_if_database_failed(&workspace, &mut cx); let opened_items = window
let opened_items = open_items( .update(&mut cx, |_workspace, cx| {
serialized_workspace, let workspace = cx.view().downgrade();
&workspace, open_items(
project_paths, serialized_workspace,
app_state, &workspace,
cx, project_paths,
) app_state,
.await cx,
.unwrap_or_default(); )
})
.await
.unwrap_or_default();
(workspace, opened_items) (window, opened_items)
}) })
} }
@ -2945,7 +2948,7 @@ impl Workspace {
) -> Result<()> { ) -> Result<()> {
let this = this.upgrade().context("workspace dropped")?; let this = this.upgrade().context("workspace dropped")?;
let item_builders = cx.update(|cx| { let item_builders = cx.update(|_, cx| {
cx.default_global::<FollowableItemBuilders>() cx.default_global::<FollowableItemBuilders>()
.values() .values()
.map(|b| b.0) .map(|b| b.0)
@ -2964,7 +2967,7 @@ impl Workspace {
Err(anyhow!("missing view variant"))?; Err(anyhow!("missing view variant"))?;
} }
for build_item in &item_builders { for build_item in &item_builders {
let task = cx.update(|cx| { let task = cx.update(|_, cx| {
build_item(pane.clone(), this.clone(), id, &mut variant, cx) build_item(pane.clone(), this.clone(), id, &mut variant, cx)
})?; })?;
if let Some(task) = task { if let Some(task) = task {
@ -3364,12 +3367,11 @@ impl Workspace {
} }
pub(crate) fn load_workspace( pub(crate) fn load_workspace(
workspace: WeakView<Workspace>,
serialized_workspace: SerializedWorkspace, serialized_workspace: SerializedWorkspace,
paths_to_open: Vec<Option<ProjectPath>>, paths_to_open: Vec<Option<ProjectPath>>,
cx: &mut WindowContext, cx: &mut ViewContext<Workspace>,
) -> Task<Result<Vec<Option<Box<dyn ItemHandle>>>>> { ) -> Task<Result<Vec<Option<Box<dyn ItemHandle>>>>> {
cx.spawn(|_, mut cx| async move { cx.spawn(|workspace, mut cx| async move {
let (project, old_center_pane) = workspace.update(&mut cx, |workspace, _| { let (project, old_center_pane) = workspace.update(&mut cx, |workspace, _| {
( (
workspace.project().clone(), workspace.project().clone(),
@ -3382,7 +3384,7 @@ impl Workspace {
// Traverse the splits tree and add to things // Traverse the splits tree and add to things
if let Some((group, active_pane, items)) = serialized_workspace if let Some((group, active_pane, items)) = serialized_workspace
.center_group .center_group
.deserialize(&project, serialized_workspace.id, &workspace, &mut cx) .deserialize(&project, serialized_workspace.id, workspace, &mut cx)
.await .await
{ {
center_items = Some(items); center_items = Some(items);
@ -3558,36 +3560,28 @@ fn window_bounds_env_override(cx: &MainThread<AsyncAppContext>) -> Option<Window
async fn open_items( async fn open_items(
serialized_workspace: Option<SerializedWorkspace>, serialized_workspace: Option<SerializedWorkspace>,
workspace: &WeakView<Workspace>,
mut project_paths_to_open: Vec<(PathBuf, Option<ProjectPath>)>, mut project_paths_to_open: Vec<(PathBuf, Option<ProjectPath>)>,
app_state: Arc<AppState>, app_state: Arc<AppState>,
mut cx: MainThread<AsyncAppContext>, mut cx: &mut MainThread<ViewContext<'_, Workspace>>,
) -> Result<Vec<Option<Result<Box<dyn ItemHandle>>>>> { ) -> Result<Vec<Option<Result<Box<dyn ItemHandle>>>>> {
let mut opened_items = Vec::with_capacity(project_paths_to_open.len()); let mut opened_items = Vec::with_capacity(project_paths_to_open.len());
if let Some(serialized_workspace) = serialized_workspace { if let Some(serialized_workspace) = serialized_workspace {
let workspace = workspace.clone(); let restored_items = Workspace::load_workspace(
let restored_items = cx serialized_workspace,
.update(|cx| { project_paths_to_open
Workspace::load_workspace(
workspace,
serialized_workspace,
project_paths_to_open
.iter()
.map(|(_, project_path)| project_path)
.cloned()
.collect(),
cx,
)
})?
.await?;
let restored_project_paths = cx.update(|cx| {
restored_items
.iter() .iter()
.filter_map(|item| item.as_ref()?.project_path(cx)) .map(|(_, project_path)| project_path)
.collect::<HashSet<_>>() .cloned()
})?; .collect(),
cx,
)
.await?;
let restored_project_paths = restored_items
.iter()
.filter_map(|item| item.as_ref()?.project_path(cx))
.collect::<HashSet<_>>();
for restored_item in restored_items { for restored_item in restored_items {
opened_items.push(restored_item.map(Ok)); opened_items.push(restored_item.map(Ok));
@ -3614,8 +3608,7 @@ async fn open_items(
.into_iter() .into_iter()
.enumerate() .enumerate()
.map(|(i, (abs_path, project_path))| { .map(|(i, (abs_path, project_path))| {
let workspace = workspace.clone(); cx.spawn(|workspace, mut cx| {
cx.spawn(|mut cx| {
let fs = app_state.fs.clone(); let fs = app_state.fs.clone();
async move { async move {
let file_project_path = project_path?; let file_project_path = project_path?;
@ -3728,7 +3721,7 @@ async fn open_items(
// }) // })
// .ok(); // .ok();
fn notify_if_database_failed(_workspace: &WeakView<Workspace>, _cx: &mut AsyncAppContext) { fn notify_if_database_failed(_workspace: WindowHandle<Workspace>, _cx: &mut AsyncAppContext) {
const REPORT_ISSUE_URL: &str ="https://github.com/zed-industries/community/issues/new?assignees=&labels=defect%2Ctriage&template=2_bug_report.yml"; const REPORT_ISSUE_URL: &str ="https://github.com/zed-industries/community/issues/new?assignees=&labels=defect%2Ctriage&template=2_bug_report.yml";
// todo!() // todo!()