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 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 {
|
||||||
|
|
|
@ -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,
|
||||||
));
|
)));
|
||||||
let handle = Handle {
|
self.entities.get_mut(id).unwrap().replace(entity);
|
||||||
|
|
||||||
|
Handle {
|
||||||
id,
|
id,
|
||||||
entity_type: PhantomData,
|
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,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue