diff --git a/crates/storybook/src/gpui3/app.rs b/crates/storybook/src/gpui3/app.rs index 7506395f7a..9ab1e99a13 100644 --- a/crates/storybook/src/gpui3/app.rs +++ b/crates/storybook/src/gpui3/app.rs @@ -1,5 +1,6 @@ use anyhow::{anyhow, Result}; -use std::{any::Any, collections::HashMap, marker::PhantomData}; +use slotmap::SlotMap; +use std::{any::Any, marker::PhantomData}; use super::{ window::{Window, WindowHandle, WindowId}, @@ -7,10 +8,8 @@ use super::{ }; pub struct AppContext { - pub(crate) entity_count: usize, - pub(crate) entities: HashMap>, - pub(crate) window_count: usize, - pub(crate) windows: HashMap, + pub(crate) entities: SlotMap>>, + pub(crate) windows: SlotMap>, // We recycle this memory across layout requests. pub(crate) child_layout_buffer: Vec, } @@ -18,10 +17,8 @@ pub struct AppContext { impl AppContext { pub fn new() -> Self { AppContext { - entity_count: 0, - entities: HashMap::new(), - window_count: 0, - windows: HashMap::new(), + entities: SlotMap::with_key(), + windows: SlotMap::with_key(), child_layout_buffer: Default::default(), } } @@ -30,7 +27,9 @@ impl AppContext { &mut self, build_root_view: impl FnOnce(&mut WindowContext) -> View, ) -> WindowHandle { - let window = Window::new(&mut self.window_count); + // let window = self.windows.insert_with_key(|id| { + + // }); unimplemented!() } @@ -42,10 +41,18 @@ impl AppContext { ) -> Result { let mut window = self .windows - .remove(&window_id) - .ok_or_else(|| anyhow!("window not found"))?; + .get_mut(window_id) + .ok_or_else(|| anyhow!("window not found"))? + .take() + .unwrap(); + let result = update(&mut WindowContext::mutable(self, &mut window)); - self.windows.insert(window_id, window); + + self.windows + .get_mut(window_id) + .ok_or_else(|| anyhow!("window not found"))? + .replace(window); + Ok(result) } } @@ -57,10 +64,11 @@ impl Context for AppContext { &mut self, build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T, ) -> Handle { - let entity_id = EntityId::new(&mut self.entity_count); - let entity = build_entity(&mut ModelContext::mutable(self, entity_id)); - self.entities.insert(entity_id, Box::new(entity)); - Handle::new(entity_id) + let id = self.entities.insert(None); + let entity = Box::new(build_entity(&mut ModelContext::mutable(self, id))); + self.entities.get_mut(id).unwrap().replace(entity); + + Handle::new(id) } fn update_entity( @@ -70,12 +78,15 @@ impl Context for AppContext { ) -> R { let mut entity = self .entities - .remove(&handle.id) + .get_mut(handle.id) + .unwrap() + .take() .unwrap() .downcast::() .unwrap(); + let result = update(&mut *entity, &mut ModelContext::mutable(self, handle.id)); - self.entities.insert(handle.id, Box::new(entity)); + self.entities.get_mut(handle.id).unwrap().replace(entity); result } } @@ -104,9 +115,19 @@ impl<'a, T: 'static> ModelContext<'a, T> { } fn update(&mut self, update: impl FnOnce(&mut T, &mut Self) -> R) -> R { - let mut entity = self.app.entities.remove(&self.entity_id).unwrap(); + 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.insert(self.entity_id, Box::new(entity)); + self.app + .entities + .get_mut(self.entity_id) + .unwrap() + .replace(entity); result } } @@ -135,16 +156,7 @@ pub struct Handle { pub(crate) entity_type: PhantomData, } -#[derive(Clone, Copy, Eq, PartialEq, Hash)] -pub struct EntityId(usize); - -impl EntityId { - pub fn new(entity_count: &mut usize) -> EntityId { - let id = *entity_count; - *entity_count += 1; - Self(id) - } -} +slotmap::new_key_type! { pub struct EntityId; } impl Handle { fn new(id: EntityId) -> Self { diff --git a/crates/storybook/src/gpui3/window.rs b/crates/storybook/src/gpui3/window.rs index 20d7aa66ef..29677df58d 100644 --- a/crates/storybook/src/gpui3/window.rs +++ b/crates/storybook/src/gpui3/window.rs @@ -11,8 +11,7 @@ pub struct Window { } impl Window { - pub fn new(window_count: &mut usize) -> Window { - let id = WindowId::new(window_count); + pub fn new(id: WindowId) -> Window { Window { id, layout_engine: Box::new(TaffyLayoutEngine::new()), @@ -88,19 +87,17 @@ impl Context for WindowContext<'_, '_> { &mut self, build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T, ) -> Handle { - { - let id = EntityId::new(&mut self.app.entity_count); - let entity = build_entity(&mut ViewContext::mutable( - &mut *self.app, - &mut self.window, - id, - )); - let handle = Handle { - id, - entity_type: PhantomData, - }; - self.app.entities.insert(handle.id, Box::new(entity)); - handle + let id = self.entities.insert(None); + let entity = Box::new(build_entity(&mut ViewContext::mutable( + &mut *self.app, + &mut self.window, + id, + ))); + self.entities.get_mut(id).unwrap().replace(entity); + + Handle { + id, + entity_type: PhantomData, } } @@ -112,15 +109,24 @@ impl Context for WindowContext<'_, '_> { let mut entity = self .app .entities - .remove(&handle.id) + .get_mut(handle.id) + .unwrap() + .take() .unwrap() .downcast::() .unwrap(); + let result = update( &mut *entity, &mut ViewContext::mutable(&mut *self.app, &mut *self.window, handle.id), ); - self.entities.insert(handle.id, Box::new(entity)); + + self.app + .entities + .get_mut(handle.id) + .unwrap() + .replace(entity); + result } } @@ -135,15 +141,18 @@ pub struct ViewContext<'a, 'w, T> { } impl<'a, 'w, T: 'static> ViewContext<'a, 'w, T> { - fn update(&mut self, update: impl FnOnce(&mut T, &mut Self) -> R) -> R { - let mut entity = self.window_cx.app.entities.remove(&self.entity_id).unwrap(); - let result = update(entity.downcast_mut::().unwrap(), self); - self.window_cx - .app - .entities - .insert(self.entity_id, Box::new(entity)); - result - } + // fn update(&mut self, update: impl FnOnce(&mut T, &mut Self) -> R) -> R { + + // self.window_cx.update_entity(handle, update) + + // let mut entity = self.window_cx.app.entities.remove(&self.entity_id).unwrap(); + // let result = update(entity.downcast_mut::().unwrap(), self); + // self.window_cx + // .app + // .entities + // .insert(self.entity_id, Box::new(entity)); + // result + // } fn mutable(app: &'a mut AppContext, window: &'w mut Window, entity_id: EntityId) -> Self { Self { @@ -181,16 +190,8 @@ impl<'a, 'w, T: 'static> Context for ViewContext<'a, 'w, T> { } } -#[derive(Clone, Copy, Eq, PartialEq, Hash)] -pub struct WindowId(usize); - -impl WindowId { - fn new(window_count: &mut usize) -> Self { - let id = *window_count; - *window_count += 1; - Self(id) - } -} +// #[derive(Clone, Copy, Eq, PartialEq, Hash)] +slotmap::new_key_type! { pub struct WindowId; } pub struct WindowHandle { id: WindowId,