From c1a35a29a84eb1a501b4bd55594a6cf313556da6 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 29 Sep 2023 14:34:40 -0600 Subject: [PATCH] WIP --- crates/gpui3/src/app.rs | 95 +++++++++++++---------------- crates/gpui3/src/gpui3.rs | 4 +- crates/gpui3/src/window.rs | 52 ++++++++++------ crates/storybook2/src/storybook2.rs | 7 --- 4 files changed, 78 insertions(+), 80 deletions(-) diff --git a/crates/gpui3/src/app.rs b/crates/gpui3/src/app.rs index 2ac703d8a3..39603f96f0 100644 --- a/crates/gpui3/src/app.rs +++ b/crates/gpui3/src/app.rs @@ -8,8 +8,8 @@ pub use model_context::*; use refineable::Refineable; use crate::{ - current_platform, run_on_main, spawn_on_main, Context, LayoutId, MainThreadOnly, Platform, - PlatformDispatcher, Reference, RootView, TextStyle, TextStyleRefinement, TextSystem, Window, + current_platform, run_on_main, spawn_on_main, Context, LayoutId, MainThread, MainThreadOnly, + Platform, PlatformDispatcher, RootView, TextStyle, TextStyleRefinement, TextSystem, Window, WindowContext, WindowHandle, WindowId, }; use anyhow::{anyhow, Result}; @@ -20,6 +20,7 @@ use slotmap::SlotMap; use smallvec::SmallVec; use std::{ any::{type_name, Any, TypeId}, + marker::PhantomData, ops::{Deref, DerefMut}, sync::{Arc, Weak}, }; @@ -45,8 +46,10 @@ impl App { let unit_entity = entities.redeem(entities.reserve(), ()); Self(Arc::new_cyclic(|this| { Mutex::new(AppContext { + thread: PhantomData, this: this.clone(), - platform: MainThreadOnly::new(platform, dispatcher), + platform: MainThreadOnly::new(platform, dispatcher.clone()), + dispatcher, text_system, pending_updates: 0, text_style_stack: Vec::new(), @@ -74,9 +77,11 @@ impl App { } } -type Handlers = SmallVec<[Arc bool + Send + Sync + 'static>; 2]>; +type Handlers = + SmallVec<[Arc) -> bool + Send + Sync + 'static>; 2]>; -pub struct AppContext { +pub struct AppContext { + thread: PhantomData, this: Weak>, platform: MainThreadOnly, dispatcher: Arc, @@ -88,11 +93,25 @@ pub struct AppContext { pub(crate) entities: EntityMap, pub(crate) windows: SlotMap>, pub(crate) pending_effects: VecDeque, - pub(crate) observers: HashMap, + pub(crate) observers: HashMap>, pub(crate) layout_id_buffer: Vec, // We recycle this memory across layout requests. } -impl AppContext { +impl Deref for AppContext { + type Target = AppContext<()>; + + fn deref(&self) -> &Self::Target { + self + } +} + +impl DerefMut for AppContext { + fn deref_mut(&mut self) -> &mut Self::Target { + self + } +} + +impl AppContext { pub fn text_system(&self) -> &Arc { &self.text_system } @@ -103,7 +122,7 @@ impl AppContext { pub fn run_on_main( &self, - f: impl FnOnce(&mut MainThreadContext) -> R + Send + 'static, + f: impl FnOnce(&mut AppContext) -> R + Send + 'static, ) -> impl Future where R: Send + 'static, @@ -111,14 +130,14 @@ impl AppContext { let this = self.this.upgrade().unwrap(); run_on_main(self.dispatcher.clone(), move || { let cx = &mut *this.lock(); - let platform = cx.platform.borrow_on_main_thread().clone(); - cx.update(|cx| f(&mut MainThreadContext::mutable(cx, platform.as_ref()))) + let main_thread_cx: &mut AppContext = unsafe { std::mem::transmute(cx) }; + main_thread_cx.update(|cx| f(cx)) }) } pub fn spawn_on_main( &self, - f: impl FnOnce(&mut MainThreadContext) -> F + Send + 'static, + f: impl FnOnce(&mut AppContext) -> F + Send + 'static, ) -> impl Future where F: Future + 'static, @@ -128,21 +147,14 @@ impl AppContext { spawn_on_main(self.dispatcher.clone(), move || { let cx = &mut *this.lock(); let platform = cx.platform.borrow_on_main_thread().clone(); - cx.update(|cx| f(&mut MainThreadContext::mutable(cx, platform.as_ref()))) + // todo!() + // cx.update(|cx| f(&mut MainThreadContext::mutable(cx, platform.as_ref()))) + + future::ready(()) }) // self.platform.read(move |platform| { } - pub fn open_window( - &mut self, - options: crate::WindowOptions, - build_root_view: impl FnOnce(&mut WindowContext) -> RootView + Send + 'static, - ) -> impl Future> { - let id = self.windows.insert(None); - let handle = WindowHandle::new(id); - self.spawn_on_main(move |cx| future::ready(cx.open_window(options, build_root_view))) - } - pub fn text_style(&self) -> TextStyle { let mut style = TextStyle::default(); for refinement in &self.text_style_stack { @@ -194,7 +206,7 @@ impl AppContext { pub(crate) fn update_window( &mut self, id: WindowId, - update: impl FnOnce(&mut WindowContext) -> R, + update: impl FnOnce(&mut WindowContext) -> R, ) -> Result { self.update(|cx| { let mut window = cx @@ -289,21 +301,13 @@ impl Context for AppContext { } } -pub struct MainThreadContext<'a> { - app: Reference<'a, AppContext>, - platform: &'a dyn Platform, -} - -impl<'a> MainThreadContext<'a> { - fn mutable(cx: &'a mut AppContext, platform: &'a dyn Platform) -> Self { - Self { - app: Reference::Mutable(cx), - platform, - } +impl AppContext { + fn platform(&self) -> &dyn Platform { + self.platform.borrow_on_main_thread() } pub fn activate(&mut self, ignoring_other_apps: bool) { - self.platform.activate(ignoring_other_apps); + self.platform().activate(ignoring_other_apps); } pub fn open_window( @@ -313,29 +317,14 @@ impl<'a> MainThreadContext<'a> { ) -> WindowHandle { let id = self.windows.insert(None); let handle = WindowHandle::new(id); - let cx = &mut *self.app; - let mut window = Window::new(handle.into(), options, self.platform, cx); - let root_view = build_root_view(&mut WindowContext::mutable(cx, &mut window)); + let mut window = Window::new(handle.into(), options, self.platform(), self); + let root_view = build_root_view(&mut WindowContext::mutable(self, &mut window)); window.root_view.replace(root_view.into_any()); - cx.windows.get_mut(id).unwrap().replace(window); + self.windows.get_mut(id).unwrap().replace(window); handle } } -impl<'a> Deref for MainThreadContext<'a> { - type Target = AppContext; - - fn deref(&self) -> &Self::Target { - &*self.app - } -} - -impl<'a> DerefMut for MainThreadContext<'a> { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut *self.app - } -} - pub(crate) enum Effect { Notify(EntityId), } diff --git a/crates/gpui3/src/gpui3.rs b/crates/gpui3/src/gpui3.rs index 60341b3f2b..401c69fc71 100644 --- a/crates/gpui3/src/gpui3.rs +++ b/crates/gpui3/src/gpui3.rs @@ -154,6 +154,8 @@ impl<'a, T> DerefMut for Reference<'a, T> { } } +pub struct MainThread; + pub(crate) struct MainThreadOnly { dispatcher: Arc, value: Arc, @@ -175,7 +177,7 @@ impl MainThreadOnly { Self { dispatcher, value } } - pub(crate) fn borrow_on_main_thread(&self) -> &Arc { + pub(crate) fn borrow_on_main_thread(&self) -> &T { assert!(self.dispatcher.is_main_thread()); &self.value } diff --git a/crates/gpui3/src/window.rs b/crates/gpui3/src/window.rs index 1e773ca4d2..6309cbc54e 100644 --- a/crates/gpui3/src/window.rs +++ b/crates/gpui3/src/window.rs @@ -1,11 +1,11 @@ use crate::{ px, AnyView, AppContext, AvailableSpace, Bounds, Context, Effect, Element, EntityId, Handle, - LayoutId, MainThreadOnly, Pixels, Platform, PlatformWindow, Point, Reference, Scene, Size, - StackContext, Style, TaffyLayoutEngine, WeakHandle, WindowOptions, + LayoutId, MainThread, MainThreadOnly, Pixels, Platform, PlatformWindow, Point, Reference, + Scene, Size, StackContext, Style, TaffyLayoutEngine, WeakHandle, WindowOptions, }; use anyhow::Result; use derive_more::{Deref, DerefMut}; -use std::{any::TypeId, future, marker::PhantomData, sync::Arc}; +use std::{any::TypeId, marker::PhantomData, sync::Arc}; use util::ResultExt; pub struct AnyWindow {} @@ -27,7 +27,7 @@ impl Window { handle: AnyWindowHandle, options: WindowOptions, platform: &dyn Platform, - cx: &mut AppContext, + cx: &mut AppContext, ) -> Self { let platform_window = platform.open_window(handle, options); let mouse_position = platform_window.mouse_position(); @@ -63,16 +63,18 @@ impl Window { } #[derive(Deref, DerefMut)] -pub struct WindowContext<'a, 'b> { +pub struct WindowContext<'a, 'b, Thread = ()> { + thread: PhantomData, #[deref] #[deref_mut] - app: Reference<'a, AppContext>, + app: Reference<'a, AppContext>, window: Reference<'b, Window>, } -impl<'a, 'w> WindowContext<'a, 'w> { - pub(crate) fn mutable(app: &'a mut AppContext, window: &'w mut Window) -> Self { +impl<'a, 'w, Thread> WindowContext<'a, 'w, Thread> { + pub(crate) fn mutable(app: &'a mut AppContext, window: &'w mut Window) -> Self { Self { + thread: PhantomData, app: Reference::Mutable(app), window: Reference::Mutable(window), } @@ -93,12 +95,13 @@ impl<'a, 'w> WindowContext<'a, 'w> { let scene = cx.window.scene.take(); dbg!(&scene); - self.run_on_main(|cx| { - cx.window - .platform_window - .borrow_on_main_thread() - .draw(scene); - }); + // todo! + // self.run_on_main(|cx| { + // cx.window + // .platform_window + // .borrow_on_main_thread() + // .draw(scene); + // }); Ok(()) }) @@ -148,7 +151,14 @@ impl<'a, 'w> WindowContext<'a, 'w> { } } -impl Context for WindowContext<'_, '_> { +impl WindowContext<'_, '_, MainThread> { + // todo!("implement other methods that use platform window") + fn platform_window(&self) -> &dyn PlatformWindow { + self.window.platform_window.borrow_on_main_thread().as_ref() + } +} + +impl Context for WindowContext<'_, '_, Thread> { type EntityContext<'a, 'w, T: Send + Sync + 'static> = ViewContext<'a, 'w, T>; type Result = T; @@ -180,7 +190,7 @@ impl Context for WindowContext<'_, '_> { } } -impl StackContext for ViewContext<'_, '_, S> { +impl StackContext for ViewContext<'_, '_, S, Thread> { fn app(&mut self) -> &mut AppContext { &mut *self.app } @@ -207,20 +217,22 @@ impl StackContext for ViewContext<'_, '_, S> { } #[derive(Deref, DerefMut)] -pub struct ViewContext<'a, 'w, S> { +pub struct ViewContext<'a, 'w, S, Thread = ()> { #[deref] #[deref_mut] window_cx: WindowContext<'a, 'w>, entity_type: PhantomData, entity_id: EntityId, + thread: PhantomData, } -impl<'a, 'w, S: Send + Sync + 'static> ViewContext<'a, 'w, S> { +impl<'a, 'w, S: Send + Sync + 'static, Thread> ViewContext<'a, 'w, S, Thread> { fn mutable(app: &'a mut AppContext, window: &'w mut Window, entity_id: EntityId) -> Self { Self { window_cx: WindowContext::mutable(app, window), entity_id, entity_type: PhantomData, + thread: PhantomData, } } @@ -272,7 +284,7 @@ impl<'a, 'w, S: Send + Sync + 'static> ViewContext<'a, 'w, S> { } } -impl<'a, 'w, S: 'static> Context for ViewContext<'a, 'w, S> { +impl<'a, 'w, S: 'static, Thread> Context for ViewContext<'a, 'w, S, Thread> { type EntityContext<'b, 'c, U: Send + Sync + 'static> = ViewContext<'b, 'c, U>; type Result = U; @@ -292,6 +304,8 @@ impl<'a, 'w, S: 'static> Context for ViewContext<'a, 'w, S> { } } +impl ViewContext<'_, '_, S, MainThread> {} + // #[derive(Clone, Copy, Eq, PartialEq, Hash)] slotmap::new_key_type! { pub struct WindowId; } diff --git a/crates/storybook2/src/storybook2.rs b/crates/storybook2/src/storybook2.rs index 3b70bfd3af..bc927b78fa 100644 --- a/crates/storybook2/src/storybook2.rs +++ b/crates/storybook2/src/storybook2.rs @@ -1,7 +1,5 @@ #![allow(dead_code, unused_variables)] -use std::future; - use log::LevelFilter; use simplelog::SimpleLogger; @@ -20,11 +18,6 @@ fn main() { gpui3::App::production().run(|cx| { let window = cx.open_window(Default::default(), |cx| workspace(cx)); - - cx.spawn_on_main(move |platform, _| { - platform.activate(true); - future::ready(()) - }); }); }