This commit is contained in:
Nathan Sobo 2023-09-14 15:21:49 -06:00
parent e4f8fe941e
commit c74c60a629
2 changed files with 80 additions and 67 deletions

View file

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

View file

@ -11,8 +11,7 @@ pub struct Window {
} }
impl Window { impl Window {
pub fn new(window_count: &mut usize) -> Window { pub fn new(id: WindowId) -> Window {
let id = WindowId::new(window_count);
Window { Window {
id, id,
layout_engine: Box::new(TaffyLayoutEngine::new()), layout_engine: Box::new(TaffyLayoutEngine::new()),
@ -88,19 +87,17 @@ impl Context for WindowContext<'_, '_> {
&mut self, &mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T, build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
) -> Handle<T> { ) -> Handle<T> {
{ let id = self.entities.insert(None);
let id = EntityId::new(&mut self.app.entity_count); let entity = Box::new(build_entity(&mut ViewContext::mutable(
let entity = build_entity(&mut ViewContext::mutable( &mut *self.app,
&mut *self.app, &mut self.window,
&mut self.window, id,
id, )));
)); self.entities.get_mut(id).unwrap().replace(entity);
let handle = Handle {
id, Handle {
entity_type: PhantomData, id,
}; entity_type: PhantomData,
self.app.entities.insert(handle.id, Box::new(entity));
handle
} }
} }
@ -112,15 +109,24 @@ impl Context for WindowContext<'_, '_> {
let mut entity = self let mut entity = self
.app .app
.entities .entities
.remove(&handle.id) .get_mut(handle.id)
.unwrap()
.take()
.unwrap() .unwrap()
.downcast::<T>() .downcast::<T>()
.unwrap(); .unwrap();
let result = update( let result = update(
&mut *entity, &mut *entity,
&mut ViewContext::mutable(&mut *self.app, &mut *self.window, handle.id), &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 result
} }
} }
@ -135,15 +141,18 @@ pub struct ViewContext<'a, 'w, T> {
} }
impl<'a, 'w, T: 'static> ViewContext<'a, 'w, T> { impl<'a, 'w, T: 'static> ViewContext<'a, 'w, T> {
fn update<R>(&mut self, update: impl FnOnce(&mut T, &mut Self) -> R) -> R { // fn update<R>(&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::<T>().unwrap(), self); // self.window_cx.update_entity(handle, update)
self.window_cx
.app // let mut entity = self.window_cx.app.entities.remove(&self.entity_id).unwrap();
.entities // let result = update(entity.downcast_mut::<T>().unwrap(), self);
.insert(self.entity_id, Box::new(entity)); // self.window_cx
result // .app
} // .entities
// .insert(self.entity_id, Box::new(entity));
// result
// }
fn mutable(app: &'a mut AppContext, window: &'w mut Window, entity_id: EntityId) -> Self { fn mutable(app: &'a mut AppContext, window: &'w mut Window, entity_id: EntityId) -> Self {
Self { Self {
@ -181,16 +190,8 @@ impl<'a, 'w, T: 'static> Context for ViewContext<'a, 'w, T> {
} }
} }
#[derive(Clone, Copy, Eq, PartialEq, Hash)] // #[derive(Clone, Copy, Eq, PartialEq, Hash)]
pub struct WindowId(usize); slotmap::new_key_type! { pub struct WindowId; }
impl WindowId {
fn new(window_count: &mut usize) -> Self {
let id = *window_count;
*window_count += 1;
Self(id)
}
}
pub struct WindowHandle<S> { pub struct WindowHandle<S> {
id: WindowId, id: WindowId,