This commit is contained in:
Antonio Scandurra 2023-10-22 13:15:29 +02:00
parent f4135e6bcf
commit 5423012368
6 changed files with 162 additions and 232 deletions

View file

@ -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(

View file

@ -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 {

View file

@ -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))
}
}

View file

@ -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
}
}

View file

@ -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 {

View file

@ -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> {