wip: clean up, use old approach to components

This commit is contained in:
Jonathan Kelley committed 2021-11-07 20:59:09 -05:00
1 parent 289d2f2518
commit 2559740463
18 files changed
+180 -247

No files matched your search

+66 -9
View File
@@ -1,3 +1,4 @@
use slab::Slab;
use std::cell::{Cell, RefCell};
use bumpalo::{boxed::Box as BumpBox, Bump};
@@ -19,7 +20,7 @@ pub struct Heuristic {
// has an internal heuristics engine to pre-allocate arenas to the right size
pub(crate) struct ScopeArena {
bump: Bump,
scopes: Vec<*mut ScopeState>,
scopes: Vec<*mut Scope>,
free_scopes: Vec<ScopeId>,
pub(crate) sender: UnboundedSender<SchedulerMsg>,
}
@@ -30,19 +31,20 @@ impl ScopeArena {
bump: Bump::new(),
scopes: Vec::new(),
free_scopes: Vec::new(),
sender,
}
}
pub fn get_scope(&self, id: &ScopeId) -> Option<&ScopeState> {
pub fn get_scope(&self, id: &ScopeId) -> Option<&Scope> {
unsafe { Some(&*self.scopes[id.0]) }
}
pub fn new_with_key(
&mut self,
fc_ptr: *const (),
vcomp: &VComponent,
parent_scope: Option<*mut ScopeState>,
caller: *mut dyn Fn(&Scope) -> Element,
parent_scope: Option<*mut Scope>,
height: u32,
subtree: u32,
) -> ScopeId {
@@ -55,9 +57,10 @@ impl ScopeArena {
} else {
let id = ScopeId(self.scopes.len());
let vcomp = unsafe { std::mem::transmute(vcomp as *const VComponent) };
// cast off the lifetime
let caller = unsafe { std::mem::transmute(caller) };
let new_scope = ScopeState {
let new_scope = Scope {
sender: self.sender.clone(),
parent_scope,
our_arena_idx: id,
@@ -65,7 +68,6 @@ impl ScopeArena {
subtree: Cell::new(subtree),
is_subtree_root: Cell::new(false),
frames: [Bump::default(), Bump::default()],
vcomp,
hooks: Default::default(),
shared_contexts: Default::default(),
@@ -78,7 +80,8 @@ impl ScopeArena {
pending_effects: Default::default(),
cached_nodes_old: Default::default(),
generation: Default::default(),
cached_nodes_new: todo!(),
cached_nodes_new: Default::default(),
caller,
}),
old_root: todo!(),
new_root: todo!(),
@@ -90,7 +93,7 @@ impl ScopeArena {
}
}
pub fn try_remove(&self, id: &ScopeId) -> Option<ScopeState> {
pub fn try_remove(&self, id: &ScopeId) -> Option<Scope> {
todo!()
}
@@ -154,4 +157,58 @@ impl ScopeArena {
.map(|li| unsafe { &*li })
.for_each(|listener| drop(listener.callback.borrow_mut().take()));
}
pub(crate) fn run_scope(&self, id: &ScopeId) -> bool {
let scope = self
.get_scope(id)
.expect("The base scope should never be moved");
// Cycle to the next frame and then reset it
// This breaks any latent references, invalidating every pointer referencing into it.
// Remove all the outdated listeners
self.ensure_drop_safety(id);
// Safety:
// - We dropped the listeners, so no more &mut T can be used while these are held
// - All children nodes that rely on &mut T are replaced with a new reference
unsafe { scope.hooks.reset() };
// Safety:
// - We've dropped all references to the wip bump frame with "ensure_drop_safety"
unsafe { scope.reset_wip_frame() };
let mut items = scope.items.borrow_mut();
// just forget about our suspended nodes while we're at it
items.suspended_nodes.clear();
// guarantee that we haven't screwed up - there should be no latent references anywhere
debug_assert!(items.listeners.is_empty());
debug_assert!(items.suspended_nodes.is_empty());
debug_assert!(items.borrowed_props.is_empty());
log::debug!("Borrowed stuff is successfully cleared");
// temporarily cast the vcomponent to the right lifetime
// let vcomp = scope.load_vcomp();
let render: &dyn Fn(&Scope) -> Element = todo!();
// Todo: see if we can add stronger guarantees around internal bookkeeping and failed component renders.
if let Some(key) = render(scope) {
// todo!("attach the niode");
// let new_head = builder.into_vnode(NodeFactory {
// bump: &scope.frames.wip_frame().bump,
// });
// log::debug!("Render is successful");
// the user's component succeeded. We can safely cycle to the next frame
// scope.frames.wip_frame_mut().head_node = unsafe { std::mem::transmute(new_head) };
// scope.frames.cycle_frame();
true
} else {
false
}
}
}