From 53b698adb66b025010c2a0c8ade2aeee26b3dce7 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 12 Sep 2023 20:40:05 -0600 Subject: [PATCH] Checkpoint --- crates/storybook/src/sketch.rs | 241 ++++++++++++--------------------- 1 file changed, 90 insertions(+), 151 deletions(-) diff --git a/crates/storybook/src/sketch.rs b/crates/storybook/src/sketch.rs index 2ead3ec6d530b66f0809c288a6f906221a975acd..13822ecf827c92c8427b332fb068eae8c80a92e8 100644 --- a/crates/storybook/src/sketch.rs +++ b/crates/storybook/src/sketch.rs @@ -1,95 +1,56 @@ use anyhow::{anyhow, Result}; +use derive_more::{Deref, DerefMut}; use gpui2::{Layout, LayoutId, Reference, Vector2F}; use std::{any::Any, collections::HashMap, marker::PhantomData, rc::Rc}; -pub trait Context { - type EntityContext<'a, 'b, T>; - - fn add_entity(&mut self, build_entity: F) -> Handle - where - F: FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T; - - fn update_entity(&mut self, handle: &Handle, update: F) -> R - where - F: FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R, - T: 'static; - - fn update_window(&mut self, window_id: WindowId, update: F) -> Result - where - F: FnOnce(&mut WindowContext) -> R; -} - pub struct AppContext { entity_count: usize, entities: HashMap>, + window_count: usize, windows: HashMap, } -impl Context for AppContext { - type EntityContext<'a, 'b, T> = ModelContext<'a, T>; - - fn add_entity(&mut self, build: F) -> Handle - where - F: FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T, - { - let id = EntityId::new(&mut self.entity_count); - let entity = build(&mut ModelContext::mutable(self, id)); - self.entities.insert(id, Box::new(entity)); - Handle { - id, - entity_type: PhantomData, - } - } - - fn update_entity(&mut self, handle: &Handle, update: F) -> R - where - F: FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R, - T: 'static, - { - let mut entity = self.entities.remove(&handle.id).unwrap(); - let result = update( - entity.downcast_mut().unwrap(), - &mut ModelContext::mutable(self, handle.id), - ); - self.entities.insert(handle.id, entity); - result - } - - fn update_window(&mut self, window_id: WindowId, update: F) -> Result - where - F: FnOnce(&mut WindowContext<'_, '_>) -> R, - { - let mut window = self - .windows - .remove(&window_id) - .ok_or_else(|| anyhow!("window closed"))?; - let result = update(&mut WindowContext::mutable(self, &mut window)); - self.windows.insert(window_id, window); - Ok(result) - } -} - impl AppContext { pub fn new() -> Self { unimplemented!() } - pub fn open_window(&self, root_element: E, state: S) -> WindowHandle { + pub fn open_window( + &self, + root_view: impl Fn(ViewContext) -> View, + ) -> WindowHandle { unimplemented!() } - pub fn add_entity(&mut self, entity: F) -> Handle - where - F: FnOnce(&mut ModelContext) -> T, - { + fn add_entity( + &mut self, + build_entity: impl FnOnce(&mut ModelContext) -> T, + ) -> Handle { let id = EntityId::new(&mut self.entity_count); - + let entity = build_entity(&mut ModelContext::mutable(self, id)); + self.entities.insert(id, Box::new(entity)); Handle { id, entity_type: PhantomData, } } + fn update_entity( + &mut self, + handle: &Handle, + update: impl FnOnce(&mut T, &mut ModelContext) -> R, + ) -> R { + let mut entity = self + .entities + .remove(&handle.id) + .unwrap() + .downcast::() + .unwrap(); + let result = update(&mut *entity, &mut ModelContext::mutable(self, handle.id)); + self.entities.insert(handle.id, Box::new(entity)); + result + } + fn update_window( &mut self, window_id: WindowId, @@ -99,9 +60,7 @@ impl AppContext { .windows .remove(&window_id) .ok_or_else(|| anyhow!("window not found"))?; - - let mut cx = WindowContext::mutable(self, &mut window); - let result = update(&mut cx); + let result = update(&mut WindowContext::mutable(self, &mut window)); self.windows.insert(window_id, window); Ok(result) } @@ -114,7 +73,7 @@ pub struct ModelContext<'a, T> { } impl<'a, T> ModelContext<'a, T> { - fn mutable(app: &mut AppContext, entity_id: EntityId) -> Self { + fn mutable(app: &'a mut AppContext, entity_id: EntityId) -> Self { Self { app: Reference::Mutable(app), entity_type: PhantomData, @@ -122,7 +81,7 @@ impl<'a, T> ModelContext<'a, T> { } } - fn immutable(app: &AppContext, entity_id: EntityId) -> Self { + fn immutable(app: &'a AppContext, entity_id: EntityId) -> Self { Self { app: Reference::Immutable(app), entity_type: PhantomData, @@ -140,8 +99,8 @@ pub struct WindowContext<'a, 'b> { window: Reference<'b, Window>, } -impl<'a, 'b> WindowContext<'a, 'b> { - fn mutable(app: &mut AppContext, window: &mut Window) -> Self { +impl<'a, 'w> WindowContext<'a, 'w> { + fn mutable(app: &'a mut AppContext, window: &'w mut Window) -> Self { Self { app: Reference::Mutable(app), window: Reference::Mutable(window), @@ -153,15 +112,13 @@ impl<'a, 'b> WindowContext<'a, 'b> { } } -impl<'a, 'b> Context for WindowContext<'a, 'b> { - type EntityContext<'c, 'd, T> = ViewContext<'c, 'd, T>; - - fn add_entity(&mut self, build_entity: F) -> Handle - where - F: FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T, - { +impl<'app, 'win> WindowContext<'app, 'win> { + fn add_entity( + &mut self, + build_entity: impl FnOnce(&mut ViewContext<'app, 'win, '_, T>) -> T, + ) -> Handle { let id = EntityId::new(&mut self.app_context().entity_count); - let mut cx = ViewContext::mutable(&mut self.app_context(), &mut self.window, id); + let mut cx = ViewContext::mutable(self, id); let entity = build_entity(&mut cx); self.app.entities.insert(id, Box::new(entity)); Handle { @@ -170,24 +127,25 @@ impl<'a, 'b> Context for WindowContext<'a, 'b> { } } - fn update_entity(&mut self, handle: &Handle, update: F) -> R - where - F: FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R, - T: 'static, - { + fn update_entity( + &mut self, + handle: &Handle, + update: impl FnOnce(&mut T, &mut ViewContext) -> R, + ) -> R { let mut entity = self.app.entities.remove(&handle.id).unwrap(); let result = update( entity.downcast_mut().unwrap(), - &mut ViewContext::mutable(&mut self.app, &mut self.window, handle.id), + &mut ViewContext::mutable(self, handle.id), ); self.app.entities.insert(handle.id, entity); result } - fn update_window(&mut self, window_id: WindowId, update: F) -> Result - where - F: FnOnce(&mut WindowContext) -> R, - { + fn update_window( + &mut self, + window_id: WindowId, + update: impl FnOnce(&mut WindowContext) -> R, + ) -> Result { if window_id == self.window.id { Ok(update(self)) } else { @@ -196,77 +154,48 @@ impl<'a, 'b> Context for WindowContext<'a, 'b> { } } -pub struct ViewContext<'a, 'b, T> { - app: Reference<'a, AppContext>, - window: Reference<'b, Window>, +#[derive(Deref, DerefMut)] +pub struct ViewContext<'a, 'b, 'c, T> { + #[deref] + #[deref_mut] + window_cx: Reference<'c, WindowContext<'a, 'b>>, entity_type: PhantomData, entity_id: EntityId, } -impl<'a, 'b, V> ViewContext<'a, 'b, V> { - fn mutable(app: &'a mut AppContext, window: &'b mut Window, entity_id: EntityId) -> Self { +impl<'a, 'b, 'c, V> ViewContext<'a, 'b, 'c, V> { + fn mutable(window_cx: &'c mut WindowContext<'a, 'b>, entity_id: EntityId) -> Self { Self { - app: Reference::Mutable(app), - window: Reference::Mutable(window), - entity_type: PhantomData, + window_cx: Reference::Mutable(window_cx), entity_id, + entity_type: PhantomData, } } - fn immutable(app: &'a AppContext, window: &'b Window, entity_id: EntityId) -> Self { + fn immutable(window_cx: &'c WindowContext<'a, 'b>, entity_id: EntityId) -> Self { Self { - app: Reference::Immutable(app), - window: Reference::Immutable(window), - entity_type: PhantomData, + window_cx: Reference::Immutable(window_cx), entity_id, - } - } - - fn window_context(&self) -> WindowContext { - WindowContext { - app: Reference::Immutable(&*self.app), - window: Reference::Immutable(&*self.window), - } - } - - fn window_context_mut(&mut self) -> WindowContext { - WindowContext { - app: Reference::Mutable(&mut *self.app), - window: Reference::Mutable(&mut *self.window), + entity_type: PhantomData, } } } -impl<'a, 'b, V> Context for ViewContext<'a, 'b, V> { - type EntityContext<'c, 'd, T> = ViewContext<'c, 'd, T>; - - fn add_entity(&mut self, build_entity: F) -> Handle - where - F: FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T, - { - self.window_context_mut().add_entity(build_entity) - } - - fn update_entity(&mut self, handle: &Handle, update: F) -> R - where - F: FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R, - T: 'static, - { - self.window_context_mut().update_entity(handle, update) - } +#[derive(Clone, Copy, Eq, PartialEq, Hash)] +pub struct WindowId(usize); - fn update_window(&mut self, window_id: WindowId, update: F) -> Result - where - F: FnOnce(&mut WindowContext<'_, '_>) -> R, - { - self.window_context_mut().update_window(window_id, update) +impl WindowId { + fn new(window_count: &mut usize) -> Self { + let id = *window_count; + *window_count += 1; + Self(id) } } -#[derive(Clone, Copy, Eq, PartialEq, Hash)] -pub struct WindowId(usize); - -pub struct WindowHandle(PhantomData); +pub struct WindowHandle { + id: WindowId, + state_type: PhantomData, +} #[derive(Clone, Copy, Eq, PartialEq, Hash)] pub struct EntityId(usize); @@ -284,11 +213,21 @@ pub struct Handle { entity_type: PhantomData, } -impl Handle { - fn update<'a, C: Context, R>( +trait Context { + type EntityContext; + + fn update_entity( + &mut self, + handle: &Handle, + update: impl FnOnce(&mut T, Self::EntityContext) -> R, + ) -> R; +} + +impl Handle { + fn update( &self, - cx: &'a mut C, - update: impl FnOnce(&mut T, &mut C::EntityContext<'_, '_, T>) -> R, + cx: &mut C, + update: impl FnOnce(&mut T, C::EntityContext) -> R, ) -> R { cx.update_entity(self, update) } @@ -419,7 +358,7 @@ pub fn view( render: impl 'static + Fn(&mut ChildState, &mut ViewContext) -> AnyElement, ) -> View { View { - render: Rc::new(move |cx| state.update(cx, |state, cx| render(state, cx))), + render: todo!(), // Rc::new(move |cx| state.update(cx, |state, cx| render(state, cx))), } } @@ -466,7 +405,7 @@ fn workspace( state: &mut Workspace, cx: &mut ViewContext, ) -> impl Element { - div().child(state.left_panel.render(&mut cx)) + div().child(state.left_panel.render(cx)) } pub struct CollabPanel { @@ -507,7 +446,7 @@ mod tests { #[test] fn test() { let mut cx = AppContext::new(); - let collab_panel = cx.add_entity(|cx| CollabPanel::new(cx)); + // let collab_panel = cx.add_entity(|cx| CollabPanel::new(cx)); // let // let mut workspace = Workspace {