wip: a few things left, slme cleanup

This commit is contained in:
Jonathan Kelley 2021-11-07 09:58:19 -05:00
parent f33510b13f
commit 289d2f2518
5 changed files with 30 additions and 66 deletions

View file

@ -124,7 +124,7 @@ impl<'bump> DiffState<'bump> {
impl<'bump> ScopeArena {
pub fn diff_scope(&'bump self, state: &mut DiffState<'bump>, id: &ScopeId) {
if let Some(component) = self.get_scope(&id) {
if let Some(component) = self.get_scope(id) {
let (old, new) = (component.wip_head(), component.fin_head());
state.stack.push(DiffInstruction::Diff { new, old });
self.work(state, || false);
@ -221,7 +221,7 @@ impl<'bump> ScopeArena {
state.mutations.replace_with(old_id, nodes_created as u32);
self.remove_nodes(state, Some(old), true);
} else {
if let Some(id) = self.find_first_element_id(state, old) {
if let Some(id) = self.find_first_element_id(old) {
state.mutations.replace_with(id, nodes_created as u32);
}
self.remove_nodes(state, Some(old), true);
@ -235,12 +235,12 @@ impl<'bump> ScopeArena {
}
MountType::InsertAfter { other_node } => {
let root = self.find_last_element(state, other_node).unwrap();
let root = self.find_last_element(other_node).unwrap();
state.mutations.insert_after(root, nodes_created as u32);
}
MountType::InsertBefore { other_node } => {
let root = self.find_first_element_id(state, other_node).unwrap();
let root = self.find_first_element_id(other_node).unwrap();
state.mutations.insert_before(root, nodes_created as u32);
}
}
@ -331,7 +331,7 @@ impl<'bump> ScopeArena {
let scope = self.get_scope(&cur_scope_id).unwrap();
for listener in *listeners {
self.attach_listener_to_scope(state, listener, scope);
self.attach_listener_to_scope(listener, scope);
listener.mounted_node.set(Some(real_id));
state.mutations.new_event_listener(listener, cur_scope_id);
}
@ -561,7 +561,7 @@ impl<'bump> ScopeArena {
state.mutations.new_event_listener(new_l, cur_scope_id);
}
new_l.mounted_node.set(old_l.mounted_node.get());
self.attach_listener_to_scope(state, new_l, scope);
self.attach_listener_to_scope(new_l, scope);
}
} else {
for listener in old.listeners {
@ -572,7 +572,7 @@ impl<'bump> ScopeArena {
for listener in new.listeners {
listener.mounted_node.set(Some(root));
state.mutations.new_event_listener(listener, cur_scope_id);
self.attach_listener_to_scope(state, listener, scope);
self.attach_listener_to_scope(listener, scope);
}
}
}
@ -1128,11 +1128,7 @@ impl<'bump> ScopeArena {
// Utilities
// =====================
fn find_last_element(
&'bump self,
state: &mut DiffState<'bump>,
vnode: &'bump VNode<'bump>,
) -> Option<ElementId> {
fn find_last_element(&'bump self, vnode: &'bump VNode<'bump>) -> Option<ElementId> {
let mut search_node = Some(vnode);
loop {
@ -1156,11 +1152,7 @@ impl<'bump> ScopeArena {
}
}
fn find_first_element_id(
&'bump self,
state: &mut DiffState<'bump>,
vnode: &'bump VNode<'bump>,
) -> Option<ElementId> {
fn find_first_element_id(&'bump self, vnode: &'bump VNode<'bump>) -> Option<ElementId> {
let mut search_node = Some(vnode);
loop {
@ -1288,12 +1280,7 @@ impl<'bump> ScopeArena {
}
/// Adds a listener closure to a scope during diff.
fn attach_listener_to_scope(
&'bump self,
state: &mut DiffState<'bump>,
listener: &'bump Listener<'bump>,
scope: &ScopeState,
) {
fn attach_listener_to_scope(&'bump self, listener: &'bump Listener<'bump>, scope: &ScopeState) {
let long_listener = unsafe { std::mem::transmute(listener) };
scope.items.borrow_mut().listeners.push(long_listener)
}

View file

@ -39,14 +39,12 @@ impl<'a, 'b> LazyNodes<'a, 'b> {
where
F: FnOnce(NodeFactory<'a>) -> VNode<'a> + 'b,
{
// there's no way to call FnOnce without a box, so we need to store it in a slot and use static dispatch
let mut slot = Some(_val);
let val = move |f| {
let inn = slot.take().unwrap();
match f {
Some(f) => Some(inn(f)),
None => None,
}
let val = move |fac: Option<NodeFactory<'a>>| {
let inner = slot.take().unwrap();
fac.map(inner)
};
unsafe { LazyNodes::new_inner(val) }
@ -125,7 +123,6 @@ impl<'a, 'b> LazyNodes<'a, 'b> {
*dataptr.add(i) = *src_ptr.add(i);
}
log::debug!("I am forgetting the contents of the stuff");
std::mem::forget(val);
Self {
@ -143,7 +140,6 @@ impl<'a, 'b> LazyNodes<'a, 'b> {
StackNodeStorage::Heap(mut lazy) => lazy(Some(f)).unwrap(),
StackNodeStorage::Stack(mut stack) => stack.call(f),
}
// todo drop?
}
}
@ -154,25 +150,12 @@ struct LazyStack {
}
impl LazyStack {
unsafe fn as_raw<'a>(&mut self) -> *mut dyn FnOnce(NodeFactory<'a>) -> VNode<'a> {
let LazyStack { buf, .. } = self;
let data = buf.as_ref();
let info_size = mem::size_of::<*mut dyn FnOnce(NodeFactory<'a>) -> VNode<'a>>()
/ mem::size_of::<usize>()
- 1;
let info_ofs = data.len() - info_size;
make_fat_ptr(data[..].as_ptr() as usize, &data[info_ofs..])
}
fn call<'a>(&mut self, f: NodeFactory<'a>) -> VNode<'a> {
let LazyStack { buf, .. } = self;
let data = buf.as_ref();
let info_size =
mem::size_of::<*mut dyn FnOnce(Option<NodeFactory<'a>>) -> Option<VNode<'a>>>()
mem::size_of::<*mut dyn FnMut(Option<NodeFactory<'a>>) -> Option<VNode<'a>>>()
/ mem::size_of::<usize>()
- 1;
@ -190,13 +173,11 @@ impl LazyStack {
impl Drop for LazyStack {
fn drop(&mut self) {
if !self.dropped {
log::debug!("manually dropping lazy nodes");
let LazyStack { buf, .. } = self;
let data = buf.as_ref();
let info_size = mem::size_of::<
*mut dyn FnOnce(Option<NodeFactory<'_>>) -> Option<VNode<'_>>,
*mut dyn FnMut(Option<NodeFactory<'_>>) -> Option<VNode<'_>>,
>() / mem::size_of::<usize>()
- 1;

View file

@ -177,7 +177,7 @@ impl<'src> VNode<'src> {
pub fn children(&self) -> &[VNode<'src>] {
match &self {
VNode::Fragment(f) => &f.children,
VNode::Fragment(f) => f.children,
VNode::Component(c) => todo!("children are not accessible through this"),
_ => &[],
}

View file

@ -45,7 +45,6 @@ impl ScopeArena {
parent_scope: Option<*mut ScopeState>,
height: u32,
subtree: u32,
sender: UnboundedSender<SchedulerMsg>,
) -> ScopeId {
if let Some(id) = self.free_scopes.pop() {
// have already called drop on it - the slot is still chillin tho
@ -59,7 +58,7 @@ impl ScopeArena {
let vcomp = unsafe { std::mem::transmute(vcomp as *const VComponent) };
let new_scope = ScopeState {
sender,
sender: self.sender.clone(),
parent_scope,
our_arena_idx: id,
height,

View file

@ -69,7 +69,7 @@ use std::{
pub struct VirtualDom {
base_scope: ScopeId,
root_props: Rc<dyn Any>,
_root_props: Rc<dyn Any>,
// we need to keep the allocation around, but we don't necessarily use it
_root_caller: Box<dyn Any>,
@ -156,7 +156,7 @@ impl VirtualDom {
sender: UnboundedSender<SchedulerMsg>,
receiver: UnboundedReceiver<SchedulerMsg>,
) -> Self {
let mut scopes = ScopeArena::new(sender.clone());
let mut scopes = ScopeArena::new(sender);
let base_scope = scopes.new_with_key(
//
@ -166,7 +166,6 @@ impl VirtualDom {
None,
0,
0,
sender.clone(),
);
Self {
@ -175,7 +174,7 @@ impl VirtualDom {
receiver,
sender,
root_props: todo!(),
_root_props: todo!(),
_root_caller: todo!(),
pending_messages: VecDeque::new(),
@ -201,7 +200,7 @@ impl VirtualDom {
///
///
pub fn get_scope<'a>(&'a self, id: &ScopeId) -> Option<&'a ScopeState> {
self.scopes.get_scope(&id)
self.scopes.get_scope(id)
}
/// Get an [`UnboundedSender`] handle to the channel used by the scheduler.
@ -265,7 +264,7 @@ impl VirtualDom {
// right now, they're bump allocated so this shouldn't matter anyway - they're not going to move
let unpinned = unsafe { Pin::new_unchecked(task) };
if let Poll::Ready(_) = unpinned.poll(cx) {
if unpinned.poll(cx).is_ready() {
all_pending = false
}
}
@ -331,7 +330,7 @@ impl VirtualDom {
///
/// loop {
/// let mut timeout = TimeoutFuture::from_ms(16);
/// let deadline = move || timeout.now_or_never();
/// let deadline = move || (&mut timeout).now_or_never();
///
/// let mutations = dom.run_with_deadline(deadline).await;
///
@ -346,11 +345,8 @@ impl VirtualDom {
/// applied the edits.
///
/// Mutations are the only link between the RealDOM and the VirtualDOM.
pub fn work_with_deadline<'a>(
&'a mut self,
mut deadline: impl FnMut() -> bool,
) -> Vec<Mutations<'a>> {
let mut committed_mutations = Vec::<Mutations>::new();
pub fn work_with_deadline(&mut self, mut deadline: impl FnMut() -> bool) -> Vec<Mutations> {
let mut committed_mutations = vec![];
while self.has_any_work() {
while let Ok(Some(msg)) = self.receiver.try_next() {
@ -375,7 +371,7 @@ impl VirtualDom {
self.pending_messages.push_front(dirty_scope);
}
} else {
log::debug!("User event without a targetted ElementId. Unsure how to proceed. {:?}", event);
log::debug!("User event without a targetted ElementId. Not currently supported.\nUnsure how to proceed. {:?}", event);
}
}
}
@ -434,7 +430,8 @@ impl VirtualDom {
committed_mutations.push(mutations);
} else {
todo!("don't have a mechanism to pause work (yet)");
// leave the work in an incomplete state
log::debug!("don't have a mechanism to pause work (yet)");
return committed_mutations;
}
}
@ -506,7 +503,7 @@ impl VirtualDom {
pub fn hard_diff<'a>(&'a mut self, scope_id: &ScopeId) -> Option<Mutations<'a>> {
log::debug!("hard diff {:?}", scope_id);
if self.run_scope(&scope_id) {
if self.run_scope(scope_id) {
let mut diff_machine = DiffState::new(Mutations::new());
diff_machine.force_diff = true;