From 54230123680aa91e19177d23b8128cfa396f64de Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Sun, 22 Oct 2023 13:15:29 +0200 Subject: [PATCH] WIP --- crates/client2/src/client2.rs | 32 ++++---- crates/gpui2/src/app.rs | 74 ++++++++++------- crates/gpui2/src/app/async_context.rs | 113 ++++++++++++++------------ crates/gpui2/src/app/model_context.rs | 50 +++--------- crates/gpui2/src/gpui2.rs | 50 ------------ crates/gpui2/src/window.rs | 75 ++++++----------- 6 files changed, 162 insertions(+), 232 deletions(-) diff --git a/crates/client2/src/client2.rs b/crates/client2/src/client2.rs index 2fcd3d40a064297c0e0be6ffae8d0536bbdb46fa..e39058fe0d85bb1ab2c216dd5ad75711e9b1ce72 100644 --- a/crates/client2/src/client2.rs +++ b/crates/client2/src/client2.rs @@ -810,7 +810,7 @@ impl Client { let mut read_from_keychain = false; let mut credentials = self.state.read().credentials.clone(); if credentials.is_none() && try_keychain { - credentials = read_credentials_from_keychain(cx); + credentials = read_credentials_from_keychain(cx).await; read_from_keychain = credentials.is_some(); } if credentials.is_none() { @@ -893,9 +893,10 @@ impl Client { ) -> Result<()> { let executor = cx.executor()?; log::info!("add connection to peer"); - let (connection_id, handle_io, mut incoming) = self - .peer - .add_connection(conn, move |duration| executor.timer(duration)); + let (connection_id, handle_io, mut incoming) = self.peer.add_connection(conn, { + let executor = executor.clone(); + move |duration| executor.timer(duration) + }); let handle_io = executor.spawn(handle_io); let peer_id = async { @@ -1041,13 +1042,14 @@ impl Client { credentials: &Credentials, cx: &AsyncAppContext, ) -> Task> { - let use_preview_server = cx.read(|cx| { - if cx.has_global::() { - *cx.global::() != ReleaseChannel::Stable - } else { - false - } - }); + let executor = match cx.executor() { + Ok(executor) => executor, + Err(error) => return Task::ready(Err(error)), + }; + + let use_preview_server = cx + .try_read_global(|channel: &ReleaseChannel, _| channel != ReleaseChannel::Stable) + .unwrap_or(false); let request = Request::builder() .header( @@ -1057,7 +1059,7 @@ impl Client { .header("x-zed-protocol-version", rpc::PROTOCOL_VERSION); let http = self.http.clone(); - cx.background().spawn(async move { + executor.spawn(async move { let mut rpc_url = Self::get_rpc_url(http, use_preview_server).await?; let rpc_host = rpc_url .host_str() @@ -1098,11 +1100,8 @@ impl Client { self: &Arc, cx: &AsyncAppContext, ) -> Task> { - let platform = cx.platform(); - let executor = cx.background(); let http = self.http.clone(); - - executor.clone().spawn(async move { + cx.spawn(|cx| async move { // Generate a pair of asymmetric encryption keys. The public key will be used by the // zed server to encrypt the user's access token, so that it can'be intercepted by // any other app running on the user's device. @@ -1189,6 +1188,7 @@ impl Client { access_token, }) }) + .unwrap_or_else(|error| Task::ready(Err(error))) } async fn authenticate_as_admin( diff --git a/crates/gpui2/src/app.rs b/crates/gpui2/src/app.rs index 043b4897ff37c26463790e97249b1cbdd7195c99..869e0f31094299278300714ab47163a98901f020 100644 --- a/crates/gpui2/src/app.rs +++ b/crates/gpui2/src/app.rs @@ -184,6 +184,10 @@ pub struct AppContext { } impl AppContext { + pub fn refresh(&mut self) { + self.push_effect(Effect::Refresh); + } + pub(crate) fn update(&mut self, update: impl FnOnce(&mut Self) -> R) -> R { self.pending_updates += 1; let result = update(self); @@ -443,15 +447,28 @@ impl AppContext { style } + pub fn has_global(&self) -> bool { + self.global_stacks_by_type + .get(&TypeId::of::()) + .map_or(false, |stack| !stack.is_empty()) + } + pub fn global(&self) -> &G { self.global_stacks_by_type .get(&TypeId::of::()) .and_then(|stack| stack.last()) - .and_then(|any_state| any_state.downcast_ref::()) + .map(|any_state| any_state.downcast_ref::().unwrap()) .ok_or_else(|| anyhow!("no state of type {} exists", type_name::())) .unwrap() } + pub fn try_global(&self) -> Option<&G> { + self.global_stacks_by_type + .get(&TypeId::of::()) + .and_then(|stack| stack.last()) + .map(|any_state| any_state.downcast_ref::().unwrap()) + } + pub fn global_mut(&mut self) -> &mut G { self.global_stacks_by_type .get_mut(&TypeId::of::()) @@ -485,6 +502,24 @@ impl AppContext { } } + pub fn update_global(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R + where + G: 'static + Send + Sync, + { + let mut global = self + .global_stacks_by_type + .get_mut(&TypeId::of::()) + .and_then(|stack| stack.pop()) + .ok_or_else(|| anyhow!("no state of type {} exists", type_name::())) + .unwrap(); + let result = f(global.downcast_mut().unwrap(), self); + self.global_stacks_by_type + .get_mut(&TypeId::of::()) + .unwrap() + .push(global); + result + } + pub(crate) fn push_global(&mut self, global: T) { self.global_stacks_by_type .entry(TypeId::of::()) @@ -551,14 +586,9 @@ impl AppContext { } impl Context for AppContext { - type BorrowedContext<'a, 'w> = Self; type EntityContext<'a, 'w, T: Send + Sync + 'static> = ModelContext<'a, T>; type Result = T; - fn refresh(&mut self) { - self.push_effect(Effect::Refresh); - } - fn entity( &mut self, build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T, @@ -582,28 +612,6 @@ impl Context for AppContext { result }) } - - fn read_global(&self, read: impl FnOnce(&G, &Self) -> R) -> R { - read(self.global(), self) - } - - fn update_global(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R - where - G: 'static + Send + Sync, - { - let mut global = self - .global_stacks_by_type - .get_mut(&TypeId::of::()) - .and_then(|stack| stack.pop()) - .ok_or_else(|| anyhow!("no state of type {} exists", type_name::())) - .unwrap(); - let result = f(global.downcast_mut().unwrap(), self); - self.global_stacks_by_type - .get_mut(&TypeId::of::()) - .unwrap() - .push(global); - result - } } impl MainThread { @@ -662,6 +670,16 @@ impl MainThread { handle }) } + + pub fn update_global( + &mut self, + update: impl FnOnce(&mut G, &mut MainThread) -> R, + ) -> R { + self.0.update_global(|global, cx| { + let cx = unsafe { mem::transmute::<&mut AppContext, &mut MainThread>(cx) }; + update(global, cx) + }) + } } pub(crate) enum Effect { diff --git a/crates/gpui2/src/app/async_context.rs b/crates/gpui2/src/app/async_context.rs index 72ca3689635ac6838e1d70ee889eafb815de9a8d..e0da6a63da2fca25a871d1eea6f97fc106726395 100644 --- a/crates/gpui2/src/app/async_context.rs +++ b/crates/gpui2/src/app/async_context.rs @@ -11,20 +11,9 @@ use std::{future::Future, sync::Weak}; pub struct AsyncAppContext(pub(crate) Weak>); impl Context for AsyncAppContext { - type BorrowedContext<'a, 'w> = AppContext; type EntityContext<'a, 'w, T: 'static + Send + Sync> = ModelContext<'a, T>; type Result = Result; - fn refresh(&mut self) -> Self::Result<()> { - let app = self - .0 - .upgrade() - .ok_or_else(|| anyhow!("app was released"))?; - let mut lock = app.lock(); // Need this to compile - lock.refresh(); - Ok(()) - } - fn entity( &mut self, build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T, @@ -49,33 +38,19 @@ impl Context for AsyncAppContext { let mut lock = app.lock(); // Need this to compile Ok(lock.update_entity(handle, update)) } +} - fn read_global( - &self, - read: impl FnOnce(&G, &Self::BorrowedContext<'_, '_>) -> R, - ) -> Self::Result { - let app = self - .0 - .upgrade() - .ok_or_else(|| anyhow!("app was released"))?; - let lock = app.lock(); // Need this to compile - Ok(lock.read_global(read)) - } - - fn update_global( - &mut self, - update: impl FnOnce(&mut G, &mut Self::BorrowedContext<'_, '_>) -> R, - ) -> Self::Result { +impl AsyncAppContext { + pub fn refresh(&mut self) -> Result<()> { let app = self .0 .upgrade() .ok_or_else(|| anyhow!("app was released"))?; let mut lock = app.lock(); // Need this to compile - Ok(lock.update_global(update)) + lock.refresh(); + Ok(()) } -} -impl AsyncAppContext { pub fn executor(&self) -> Result { let app = self .0 @@ -141,6 +116,48 @@ impl AsyncAppContext { let mut app_context = app.lock(); Ok(app_context.run_on_main(f)) } + + pub fn has_global(&self) -> Result { + let app = self + .0 + .upgrade() + .ok_or_else(|| anyhow!("app was released"))?; + let lock = app.lock(); // Need this to compile + Ok(lock.has_global::()) + } + + pub fn read_global( + &self, + read: impl FnOnce(&G, &AppContext) -> R, + ) -> Result { + let app = self + .0 + .upgrade() + .ok_or_else(|| anyhow!("app was released"))?; + let lock = app.lock(); // Need this to compile + Ok(read(lock.global(), &lock)) + } + + pub fn try_read_global( + &self, + read: impl FnOnce(&G, &AppContext) -> R, + ) -> Option { + let app = self.0.upgrade()?; + let lock = app.lock(); // Need this to compile + Some(read(lock.try_global()?, &lock)) + } + + pub fn update_global( + &mut self, + update: impl FnOnce(&mut G, &mut AppContext) -> R, + ) -> Result { + let app = self + .0 + .upgrade() + .ok_or_else(|| anyhow!("app was released"))?; + let mut lock = app.lock(); // Need this to compile + Ok(lock.update_global(update)) + } } #[derive(Clone, Deref, DerefMut)] @@ -165,17 +182,28 @@ impl AsyncWindowContext { .update_window(self.window, |cx| cx.on_next_frame(f)) .ok(); } + + pub fn read_global( + &self, + read: impl FnOnce(&G, &WindowContext) -> R, + ) -> Result { + self.app + .read_window(self.window, |cx| read(cx.global(), cx)) + } + + pub fn update_global( + &mut self, + update: impl FnOnce(&mut G, &mut WindowContext) -> R, + ) -> Result { + self.app + .update_window(self.window, |cx| cx.update_global(update)) + } } impl Context for AsyncWindowContext { - type BorrowedContext<'a, 'w> = WindowContext<'a, 'w>; type EntityContext<'a, 'w, T: 'static + Send + Sync> = ViewContext<'a, 'w, T>; type Result = Result; - fn refresh(&mut self) -> Self::Result<()> { - self.app.refresh() - } - fn entity( &mut self, build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, R>) -> R, @@ -192,19 +220,4 @@ impl Context for AsyncWindowContext { self.app .update_window(self.window, |cx| cx.update_entity(handle, update)) } - - fn read_global( - &self, - read: impl FnOnce(&G, &Self::BorrowedContext<'_, '_>) -> R, - ) -> Result { - self.app.read_window(self.window, |cx| cx.read_global(read)) - } - - fn update_global( - &mut self, - update: impl FnOnce(&mut G, &mut Self::BorrowedContext<'_, '_>) -> R, - ) -> Result { - self.app - .update_window(self.window, |cx| cx.update_global(update)) - } } diff --git a/crates/gpui2/src/app/model_context.rs b/crates/gpui2/src/app/model_context.rs index 65ac1fd03e6365a7f068cbfa710a211d76ddd7bd..d931488145507f2d848519a1b52798bf21051f4f 100644 --- a/crates/gpui2/src/app/model_context.rs +++ b/crates/gpui2/src/app/model_context.rs @@ -19,24 +19,6 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> { } } - // todo! - // fn update(&mut self, update: impl FnOnce(&mut T, &mut Self) -> R) -> R { - // let mut entity = self - // .app - // .entities - // .get_mut(self.entity_id) - // .unwrap() - // .take() - // .unwrap(); - // let result = update(entity.downcast_mut::().unwrap(), self); - // self.app - // .entities - // .get_mut(self.entity_id) - // .unwrap() - // .replace(entity); - // result - // } - pub fn handle(&self) -> WeakHandle { self.app.entities.weak_handle(self.entity_id) } @@ -120,6 +102,16 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> { emitter: self.entity_id, }); } + + pub fn update_global(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R + where + G: 'static + Send + Sync, + { + let mut global = self.app.pop_global::(); + let result = f(global.as_mut(), self); + self.app.push_global(global); + result + } } impl<'a, T: EventEmitter + Send + Sync + 'static> ModelContext<'a, T> { @@ -132,14 +124,9 @@ impl<'a, T: EventEmitter + Send + Sync + 'static> ModelContext<'a, T> { } impl<'a, T: 'static> Context for ModelContext<'a, T> { - type BorrowedContext<'b, 'c> = ModelContext<'b, T>; type EntityContext<'b, 'c, U: Send + Sync + 'static> = ModelContext<'b, U>; type Result = U; - fn refresh(&mut self) { - self.app.refresh(); - } - fn entity( &mut self, build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, U>) -> U, @@ -154,21 +141,4 @@ impl<'a, T: 'static> Context for ModelContext<'a, T> { ) -> R { self.app.update_entity(handle, update) } - - fn read_global( - &self, - read: impl FnOnce(&G, &Self::BorrowedContext<'_, '_>) -> R, - ) -> R { - read(self.app.global(), self) - } - - fn update_global(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R - where - G: 'static + Send + Sync, - { - let mut global = self.app.pop_global::(); - let result = f(global.as_mut(), self); - self.app.push_global(global); - result - } } diff --git a/crates/gpui2/src/gpui2.rs b/crates/gpui2/src/gpui2.rs index d25c563d34f44e9d0c4c629942214871f9a1a174..701f1c0f83e0efdf55db3b60e02f02b3da364e6d 100644 --- a/crates/gpui2/src/gpui2.rs +++ b/crates/gpui2/src/gpui2.rs @@ -66,12 +66,9 @@ use taffy::TaffyLayoutEngine; type AnyBox = Box; pub trait Context { - type BorrowedContext<'a, 'w>: Context; type EntityContext<'a, 'w, T: 'static + Send + Sync>; type Result; - fn refresh(&mut self) -> Self::Result<()>; - fn entity( &mut self, build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T, @@ -82,18 +79,6 @@ pub trait Context { handle: &Handle, update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R, ) -> Self::Result; - - fn read_global( - &self, - read: impl FnOnce(&G, &Self::BorrowedContext<'_, '_>) -> R, - ) -> Self::Result; - - fn update_global( - &mut self, - f: impl FnOnce(&mut G, &mut Self::BorrowedContext<'_, '_>) -> R, - ) -> Self::Result - where - G: 'static + Send + Sync; } pub enum GlobalKey { @@ -120,14 +105,9 @@ impl DerefMut for MainThread { } impl Context for MainThread { - type BorrowedContext<'a, 'w> = MainThread>; type EntityContext<'a, 'w, T: 'static + Send + Sync> = MainThread>; type Result = C::Result; - fn refresh(&mut self) -> Self::Result<()> { - self.0.refresh() - } - fn entity( &mut self, build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T, @@ -158,36 +138,6 @@ impl Context for MainThread { update(entity, cx) }) } - - fn read_global( - &self, - read: impl FnOnce(&G, &Self::BorrowedContext<'_, '_>) -> R, - ) -> Self::Result { - self.0.read_global(|global, cx| { - let cx = unsafe { - mem::transmute::< - &C::BorrowedContext<'_, '_>, - &MainThread>, - >(cx) - }; - read(global, cx) - }) - } - - fn update_global( - &mut self, - update: impl FnOnce(&mut G, &mut Self::BorrowedContext<'_, '_>) -> R, - ) -> Self::Result { - self.0.update_global(|global, cx| { - let cx = unsafe { - mem::transmute::< - &mut C::BorrowedContext<'_, '_>, - &mut MainThread>, - >(cx) - }; - update(global, cx) - }) - } } pub trait BorrowAppContext { diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 94e8d5a91648a76488ee225d3d763b344fc4e467..fc281c537e27f862c5314413b200d4d289f07808 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -1,13 +1,13 @@ use crate::{ px, size, Action, AnyBox, AnyView, AppContext, AsyncWindowContext, AvailableSpace, BorrowAppContext, Bounds, BoxShadow, Context, Corners, DevicePixels, DispatchContext, - DisplayId, Edges, Effect, Element, EntityId, EventEmitter, Executor, FocusEvent, FontId, - GlobalElementId, GlyphId, Handle, Hsla, ImageData, InputEvent, IsZero, KeyListener, KeyMatch, - KeyMatcher, Keystroke, LayoutId, MainThread, MainThreadOnly, MonochromeSprite, MouseMoveEvent, - Path, Pixels, Platform, PlatformAtlas, PlatformWindow, Point, PolychromeSprite, Quad, - Reference, RenderGlyphParams, RenderImageParams, RenderSvgParams, ScaledPixels, SceneBuilder, - Shadow, SharedString, Size, Style, Subscription, TaffyLayoutEngine, Task, Underline, - UnderlineStyle, WeakHandle, WindowOptions, SUBPIXEL_VARIANTS, + DisplayId, Edges, Effect, Element, EntityId, EventEmitter, FocusEvent, FontId, GlobalElementId, + GlyphId, Handle, Hsla, ImageData, InputEvent, IsZero, KeyListener, KeyMatch, KeyMatcher, + Keystroke, LayoutId, MainThread, MainThreadOnly, MonochromeSprite, MouseMoveEvent, Path, + Pixels, Platform, PlatformAtlas, PlatformWindow, Point, PolychromeSprite, Quad, Reference, + RenderGlyphParams, RenderImageParams, RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, + SharedString, Size, Style, Subscription, TaffyLayoutEngine, Task, Underline, UnderlineStyle, + WeakHandle, WindowOptions, SUBPIXEL_VARIANTS, }; use anyhow::Result; use collections::HashMap; @@ -426,6 +426,16 @@ impl<'a, 'w> WindowContext<'a, 'w> { }) } + pub fn update_global(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R + where + G: 'static + Send + Sync, + { + let mut global = self.app.pop_global::(); + let result = f(global.as_mut(), self); + self.app.push_global(global); + result + } + pub fn request_layout( &mut self, style: &Style, @@ -1093,14 +1103,9 @@ impl<'a, 'w> MainThread> { } impl Context for WindowContext<'_, '_> { - type BorrowedContext<'a, 'w> = WindowContext<'a, 'w>; type EntityContext<'a, 'w, T: 'static + Send + Sync> = ViewContext<'a, 'w, T>; type Result = T; - fn refresh(&mut self) { - self.app.refresh(); - } - fn entity( &mut self, build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T, @@ -1127,20 +1132,6 @@ impl Context for WindowContext<'_, '_> { self.entities.end_lease(entity); result } - - fn read_global(&self, read: impl FnOnce(&G, &Self) -> R) -> R { - read(self.app.global(), self) - } - - fn update_global(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R - where - G: 'static + Send + Sync, - { - let mut global = self.app.pop_global::(); - let result = f(global.as_mut(), self); - self.app.push_global(global); - result - } } impl<'a, 'w> std::ops::Deref for WindowContext<'a, 'w> { @@ -1561,6 +1552,16 @@ impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> { }) } + pub fn update_global(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R + where + G: 'static + Send + Sync, + { + let mut global = self.app.pop_global::(); + let result = f(global.as_mut(), self); + self.app.push_global(global); + result + } + pub fn on_mouse_event( &mut self, handler: impl Fn(&mut V, &Event, DispatchPhase, &mut ViewContext) + Send + Sync + 'static, @@ -1587,14 +1588,9 @@ impl<'a, 'w, V> Context for ViewContext<'a, 'w, V> where V: 'static + Send + Sync, { - type BorrowedContext<'b, 'c> = ViewContext<'b, 'c, V>; type EntityContext<'b, 'c, U: 'static + Send + Sync> = ViewContext<'b, 'c, U>; type Result = U; - fn refresh(&mut self) { - self.app.refresh(); - } - fn entity( &mut self, build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T2>) -> T2, @@ -1609,23 +1605,6 @@ where ) -> R { self.window_cx.update_entity(handle, update) } - - fn read_global( - &self, - read: impl FnOnce(&G, &Self::BorrowedContext<'_, '_>) -> R, - ) -> R { - read(self.global(), self) - } - - fn update_global(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R - where - G: 'static + Send + Sync, - { - let mut global = self.app.pop_global::(); - let result = f(global.as_mut(), self); - self.app.push_global(global); - result - } } impl<'a, 'w, S: 'static> std::ops::Deref for ViewContext<'a, 'w, S> {