Slotmaps
This commit is contained in:
parent
e4f8fe941e
commit
c74c60a629
2 changed files with 80 additions and 67 deletions
|
@ -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 {
|
||||
|
|
|
@ -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(
|
||||
let id = self.entities.insert(None);
|
||||
let entity = Box::new(build_entity(&mut ViewContext::mutable(
|
||||
&mut *self.app,
|
||||
&mut self.window,
|
||||
id,
|
||||
));
|
||||
let handle = Handle {
|
||||
)));
|
||||
self.entities.get_mut(id).unwrap().replace(entity);
|
||||
|
||||
Handle {
|
||||
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
|
||||
.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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue