Detailed changes
@@ -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<Result<Connection, EstablishConnectionError>> {
- let use_preview_server = cx.read(|cx| {
- if cx.has_global::<ReleaseChannel>() {
- *cx.global::<ReleaseChannel>() != 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<Self>,
cx: &AsyncAppContext,
) -> Task<Result<Credentials>> {
- 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(
@@ -184,6 +184,10 @@ pub struct AppContext {
}
impl AppContext {
+ pub fn refresh(&mut self) {
+ self.push_effect(Effect::Refresh);
+ }
+
pub(crate) fn update<R>(&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<G: 'static>(&self) -> bool {
+ self.global_stacks_by_type
+ .get(&TypeId::of::<G>())
+ .map_or(false, |stack| !stack.is_empty())
+ }
+
pub fn global<G: 'static>(&self) -> &G {
self.global_stacks_by_type
.get(&TypeId::of::<G>())
.and_then(|stack| stack.last())
- .and_then(|any_state| any_state.downcast_ref::<G>())
+ .map(|any_state| any_state.downcast_ref::<G>().unwrap())
.ok_or_else(|| anyhow!("no state of type {} exists", type_name::<G>()))
.unwrap()
}
+ pub fn try_global<G: 'static>(&self) -> Option<&G> {
+ self.global_stacks_by_type
+ .get(&TypeId::of::<G>())
+ .and_then(|stack| stack.last())
+ .map(|any_state| any_state.downcast_ref::<G>().unwrap())
+ }
+
pub fn global_mut<G: 'static>(&mut self) -> &mut G {
self.global_stacks_by_type
.get_mut(&TypeId::of::<G>())
@@ -485,6 +502,24 @@ impl AppContext {
}
}
+ pub fn update_global<G, R>(&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::<G>())
+ .and_then(|stack| stack.pop())
+ .ok_or_else(|| anyhow!("no state of type {} exists", type_name::<G>()))
+ .unwrap();
+ let result = f(global.downcast_mut().unwrap(), self);
+ self.global_stacks_by_type
+ .get_mut(&TypeId::of::<G>())
+ .unwrap()
+ .push(global);
+ result
+ }
+
pub(crate) fn push_global<T: Send + Sync + 'static>(&mut self, global: T) {
self.global_stacks_by_type
.entry(TypeId::of::<T>())
@@ -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> = T;
- fn refresh(&mut self) {
- self.push_effect(Effect::Refresh);
- }
-
fn entity<T: Send + Sync + 'static>(
&mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
@@ -582,28 +612,6 @@ impl Context for AppContext {
result
})
}
-
- fn read_global<G: 'static + Send + Sync, R>(&self, read: impl FnOnce(&G, &Self) -> R) -> R {
- read(self.global(), self)
- }
-
- fn update_global<G, R>(&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::<G>())
- .and_then(|stack| stack.pop())
- .ok_or_else(|| anyhow!("no state of type {} exists", type_name::<G>()))
- .unwrap();
- let result = f(global.downcast_mut().unwrap(), self);
- self.global_stacks_by_type
- .get_mut(&TypeId::of::<G>())
- .unwrap()
- .push(global);
- result
- }
}
impl MainThread<AppContext> {
@@ -662,6 +670,16 @@ impl MainThread<AppContext> {
handle
})
}
+
+ pub fn update_global<G: 'static + Send + Sync, R>(
+ &mut self,
+ update: impl FnOnce(&mut G, &mut MainThread<AppContext>) -> R,
+ ) -> R {
+ self.0.update_global(|global, cx| {
+ let cx = unsafe { mem::transmute::<&mut AppContext, &mut MainThread<AppContext>>(cx) };
+ update(global, cx)
+ })
+ }
}
pub(crate) enum Effect {
@@ -11,20 +11,9 @@ use std::{future::Future, sync::Weak};
pub struct AsyncAppContext(pub(crate) Weak<Mutex<AppContext>>);
impl Context for AsyncAppContext {
- type BorrowedContext<'a, 'w> = AppContext;
type EntityContext<'a, 'w, T: 'static + Send + Sync> = ModelContext<'a, T>;
type Result<T> = Result<T>;
- 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<T: Send + Sync + 'static>(
&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<G: 'static + Send + Sync, R>(
- &self,
- read: impl FnOnce(&G, &Self::BorrowedContext<'_, '_>) -> R,
- ) -> Self::Result<R> {
- 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<G: 'static + Send + Sync, R>(
- &mut self,
- update: impl FnOnce(&mut G, &mut Self::BorrowedContext<'_, '_>) -> R,
- ) -> Self::Result<R> {
+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<Executor> {
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<G: 'static + Send + Sync>(&self) -> Result<bool> {
+ let app = self
+ .0
+ .upgrade()
+ .ok_or_else(|| anyhow!("app was released"))?;
+ let lock = app.lock(); // Need this to compile
+ Ok(lock.has_global::<G>())
+ }
+
+ pub fn read_global<G: 'static + Send + Sync, R>(
+ &self,
+ read: impl FnOnce(&G, &AppContext) -> R,
+ ) -> Result<R> {
+ 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<G: 'static + Send + Sync, R>(
+ &self,
+ read: impl FnOnce(&G, &AppContext) -> R,
+ ) -> Option<R> {
+ let app = self.0.upgrade()?;
+ let lock = app.lock(); // Need this to compile
+ Some(read(lock.try_global()?, &lock))
+ }
+
+ pub fn update_global<G: 'static + Send + Sync, R>(
+ &mut self,
+ update: impl FnOnce(&mut G, &mut AppContext) -> R,
+ ) -> Result<R> {
+ 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<G: 'static + Send + Sync, R>(
+ &self,
+ read: impl FnOnce(&G, &WindowContext) -> R,
+ ) -> Result<R> {
+ self.app
+ .read_window(self.window, |cx| read(cx.global(), cx))
+ }
+
+ pub fn update_global<G: 'static + Send + Sync, R>(
+ &mut self,
+ update: impl FnOnce(&mut G, &mut WindowContext) -> R,
+ ) -> Result<R> {
+ 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<T> = Result<T>;
- fn refresh(&mut self) -> Self::Result<()> {
- self.app.refresh()
- }
-
fn entity<R: Send + Sync + 'static>(
&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<G: 'static + Send + Sync, R>(
- &self,
- read: impl FnOnce(&G, &Self::BorrowedContext<'_, '_>) -> R,
- ) -> Result<R> {
- self.app.read_window(self.window, |cx| cx.read_global(read))
- }
-
- fn update_global<G: 'static + Send + Sync, R>(
- &mut self,
- update: impl FnOnce(&mut G, &mut Self::BorrowedContext<'_, '_>) -> R,
- ) -> Result<R> {
- self.app
- .update_window(self.window, |cx| cx.update_global(update))
- }
}
@@ -19,24 +19,6 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
}
}
- // todo!
- // fn update<R>(&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::<T>().unwrap(), self);
- // self.app
- // .entities
- // .get_mut(self.entity_id)
- // .unwrap()
- // .replace(entity);
- // result
- // }
-
pub fn handle(&self) -> WeakHandle<T> {
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<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
+ where
+ G: 'static + Send + Sync,
+ {
+ let mut global = self.app.pop_global::<G>();
+ 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> = U;
- fn refresh(&mut self) {
- self.app.refresh();
- }
-
fn entity<U: Send + Sync + 'static>(
&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<G: 'static + Send + Sync, R>(
- &self,
- read: impl FnOnce(&G, &Self::BorrowedContext<'_, '_>) -> R,
- ) -> R {
- read(self.app.global(), self)
- }
-
- fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
- where
- G: 'static + Send + Sync,
- {
- let mut global = self.app.pop_global::<G>();
- let result = f(global.as_mut(), self);
- self.app.push_global(global);
- result
- }
}
@@ -66,12 +66,9 @@ use taffy::TaffyLayoutEngine;
type AnyBox = Box<dyn Any + Send + Sync>;
pub trait Context {
- type BorrowedContext<'a, 'w>: Context;
type EntityContext<'a, 'w, T: 'static + Send + Sync>;
type Result<T>;
- fn refresh(&mut self) -> Self::Result<()>;
-
fn entity<T: Send + Sync + 'static>(
&mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
@@ -82,18 +79,6 @@ pub trait Context {
handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
) -> Self::Result<R>;
-
- fn read_global<G: 'static + Send + Sync, R>(
- &self,
- read: impl FnOnce(&G, &Self::BorrowedContext<'_, '_>) -> R,
- ) -> Self::Result<R>;
-
- fn update_global<G, R>(
- &mut self,
- f: impl FnOnce(&mut G, &mut Self::BorrowedContext<'_, '_>) -> R,
- ) -> Self::Result<R>
- where
- G: 'static + Send + Sync;
}
pub enum GlobalKey {
@@ -120,14 +105,9 @@ impl<T> DerefMut for MainThread<T> {
}
impl<C: Context> Context for MainThread<C> {
- type BorrowedContext<'a, 'w> = MainThread<C::BorrowedContext<'a, 'w>>;
type EntityContext<'a, 'w, T: 'static + Send + Sync> = MainThread<C::EntityContext<'a, 'w, T>>;
type Result<T> = C::Result<T>;
- fn refresh(&mut self) -> Self::Result<()> {
- self.0.refresh()
- }
-
fn entity<T: Send + Sync + 'static>(
&mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
@@ -158,36 +138,6 @@ impl<C: Context> Context for MainThread<C> {
update(entity, cx)
})
}
-
- fn read_global<G: 'static + Send + Sync, R>(
- &self,
- read: impl FnOnce(&G, &Self::BorrowedContext<'_, '_>) -> R,
- ) -> Self::Result<R> {
- self.0.read_global(|global, cx| {
- let cx = unsafe {
- mem::transmute::<
- &C::BorrowedContext<'_, '_>,
- &MainThread<C::BorrowedContext<'_, '_>>,
- >(cx)
- };
- read(global, cx)
- })
- }
-
- fn update_global<G: 'static + Send + Sync, R>(
- &mut self,
- update: impl FnOnce(&mut G, &mut Self::BorrowedContext<'_, '_>) -> R,
- ) -> Self::Result<R> {
- self.0.update_global(|global, cx| {
- let cx = unsafe {
- mem::transmute::<
- &mut C::BorrowedContext<'_, '_>,
- &mut MainThread<C::BorrowedContext<'_, '_>>,
- >(cx)
- };
- update(global, cx)
- })
- }
}
pub trait BorrowAppContext {
@@ -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<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
+ where
+ G: 'static + Send + Sync,
+ {
+ let mut global = self.app.pop_global::<G>();
+ 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<WindowContext<'a, 'w>> {
}
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> = T;
- fn refresh(&mut self) {
- self.app.refresh();
- }
-
fn entity<T: Send + Sync + 'static>(
&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<G: 'static + Send + Sync, R>(&self, read: impl FnOnce(&G, &Self) -> R) -> R {
- read(self.app.global(), self)
- }
-
- fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
- where
- G: 'static + Send + Sync,
- {
- let mut global = self.app.pop_global::<G>();
- 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<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
+ where
+ G: 'static + Send + Sync,
+ {
+ let mut global = self.app.pop_global::<G>();
+ let result = f(global.as_mut(), self);
+ self.app.push_global(global);
+ result
+ }
+
pub fn on_mouse_event<Event: 'static>(
&mut self,
handler: impl Fn(&mut V, &Event, DispatchPhase, &mut ViewContext<V>) + 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> = U;
- fn refresh(&mut self) {
- self.app.refresh();
- }
-
fn entity<T2: Send + Sync + 'static>(
&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<G: 'static + Send + Sync, R>(
- &self,
- read: impl FnOnce(&G, &Self::BorrowedContext<'_, '_>) -> R,
- ) -> R {
- read(self.global(), self)
- }
-
- fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
- where
- G: 'static + Send + Sync,
- {
- let mut global = self.app.pop_global::<G>();
- 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> {