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 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<EntityId, Box<dyn Any>>,
pub(crate) window_count: usize,
pub(crate) windows: HashMap<WindowId, Window>,
pub(crate) entities: SlotMap<EntityId, Option<Box<dyn Any>>>,
pub(crate) windows: SlotMap<WindowId, Option<Window>>,
// We recycle this memory across layout requests.
pub(crate) child_layout_buffer: Vec<LayoutId>,
}
@ -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<S>,
) -> WindowHandle<S> {
let window = Window::new(&mut self.window_count);
// let window = self.windows.insert_with_key(|id| {
// });
unimplemented!()
}
@ -42,10 +41,18 @@ impl AppContext {
) -> Result<R> {
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<T> {
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<T: 'static, R>(
@ -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::<T>()
.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<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);
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<T> {
pub(crate) entity_type: PhantomData<T>,
}
#[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<T: 'static> Handle<T> {
fn new(id: EntityId) -> Self {

View file

@ -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<T> {
{
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::<T>()
.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<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
.app
.entities
.insert(self.entity_id, Box::new(entity));
result
}
// fn update<R>(&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::<T>().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<S> {
id: WindowId,