feat: a new vnode type for anchors

This commit is contained in:
Jonathan Kelley committed 2021-07-29 18:04:09 -04:00
1 parent 63a85e4865
commit d618092e9d
15 files changed
+715 -441

No files matched your search

+35 -10
View File
@@ -1,5 +1,6 @@
use crate::innerlude::*;
use bumpalo::boxed::Box as BumpBox;
use fxhash::FxHashSet;
use std::{
any::{Any, TypeId},
borrow::BorrowMut,
@@ -24,13 +25,15 @@ pub struct Scope {
pub(crate) parent_idx: Option<ScopeId>,
pub(crate) our_arena_idx: ScopeId,
pub(crate) height: u32,
pub(crate) descendents: RefCell<HashSet<ScopeId>>,
pub(crate) descendents: RefCell<FxHashSet<ScopeId>>,
// Nodes
// an internal, highly efficient storage of vnodes
// lots of safety condsiderations
pub(crate) frames: ActiveFrame,
pub(crate) caller: Rc<WrappedCaller>,
pub(crate) child_nodes: ScopeChildren<'static>,
pub(crate) pending_garbage: RefCell<Vec<*const VNode<'static>>>,
// Listeners
pub(crate) listeners: RefCell<Vec<*const Listener<'static>>>,
@@ -67,11 +70,18 @@ impl Scope {
height: u32,
child_nodes: ScopeChildren,
// child_nodes: &'creator_node [VNode<'creator_node>],
vdom: SharedResources,
) -> Self {
let child_nodes = unsafe { child_nodes.extend_lifetime() };
// insert ourself as a descendent of the parent
// when the parent is removed, this map will be traversed, and we will also be cleaned up.
if let Some(parent) = &parent {
let parent = unsafe { vdom.get_scope(*parent) }.unwrap();
parent.descendents.borrow_mut().insert(arena_idx);
}
Self {
child_nodes,
caller,
@@ -80,10 +90,12 @@ impl Scope {
height,
vdom,
frames: ActiveFrame::new(),
hooks: Default::default(),
shared_contexts: Default::default(),
listeners: Default::default(),
descendents: Default::default(),
pending_garbage: Default::default(),
}
}
@@ -102,6 +114,9 @@ impl Scope {
// 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
if !self.pending_garbage.borrow().is_empty() {
panic!("cannot run scope while garbage is pending! Please clean up your mess first");
}
log::debug!("reset okay");
@@ -189,11 +204,11 @@ impl Scope {
if let Some(raw_listener) = raw_listener {
let listener = unsafe { &**raw_listener };
log::info!(
"calling listener {:?}, {:?}",
listener.event,
listener.scope
);
// log::info!(
// "calling listener {:?}, {:?}",
// listener.event,
// // listener.scope
// );
let mut cb = listener.callback.borrow_mut();
if let Some(cb) = cb.as_mut() {
(cb)(event);
@@ -209,10 +224,20 @@ impl Scope {
self.frames.fin_head()
}
// #[inline]
pub fn child_nodes<'a>(&'a self) -> ScopeChildren {
// self.child_nodes
unsafe { self.child_nodes.unextend_lfetime() }
// unsafe { std::mem::transmute(self.child_nodes) }
}
pub fn consume_garbage(&self) -> Vec<&VNode> {
let mut garbage = self.pending_garbage.borrow_mut();
garbage
.drain(..)
.map(|node| {
// safety: scopes cannot cycle without their garbage being collected. these nodes are safe
let node: &VNode<'static> = unsafe { &*node };
let node: &VNode = unsafe { std::mem::transmute(node) };
node
})
.collect::<Vec<_>>()
}
}