mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-27 14:40:44 +00:00
wip: a few things left, slme cleanup
This commit is contained in:
parent
f33510b13f
commit
289d2f2518
5 changed files with 30 additions and 66 deletions
|
@ -124,7 +124,7 @@ impl<'bump> DiffState<'bump> {
|
||||||
|
|
||||||
impl<'bump> ScopeArena {
|
impl<'bump> ScopeArena {
|
||||||
pub fn diff_scope(&'bump self, state: &mut DiffState<'bump>, id: &ScopeId) {
|
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());
|
let (old, new) = (component.wip_head(), component.fin_head());
|
||||||
state.stack.push(DiffInstruction::Diff { new, old });
|
state.stack.push(DiffInstruction::Diff { new, old });
|
||||||
self.work(state, || false);
|
self.work(state, || false);
|
||||||
|
@ -221,7 +221,7 @@ impl<'bump> ScopeArena {
|
||||||
state.mutations.replace_with(old_id, nodes_created as u32);
|
state.mutations.replace_with(old_id, nodes_created as u32);
|
||||||
self.remove_nodes(state, Some(old), true);
|
self.remove_nodes(state, Some(old), true);
|
||||||
} else {
|
} 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);
|
state.mutations.replace_with(id, nodes_created as u32);
|
||||||
}
|
}
|
||||||
self.remove_nodes(state, Some(old), true);
|
self.remove_nodes(state, Some(old), true);
|
||||||
|
@ -235,12 +235,12 @@ impl<'bump> ScopeArena {
|
||||||
}
|
}
|
||||||
|
|
||||||
MountType::InsertAfter { other_node } => {
|
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);
|
state.mutations.insert_after(root, nodes_created as u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
MountType::InsertBefore { other_node } => {
|
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);
|
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();
|
let scope = self.get_scope(&cur_scope_id).unwrap();
|
||||||
|
|
||||||
for listener in *listeners {
|
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));
|
listener.mounted_node.set(Some(real_id));
|
||||||
state.mutations.new_event_listener(listener, cur_scope_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);
|
state.mutations.new_event_listener(new_l, cur_scope_id);
|
||||||
}
|
}
|
||||||
new_l.mounted_node.set(old_l.mounted_node.get());
|
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 {
|
} else {
|
||||||
for listener in old.listeners {
|
for listener in old.listeners {
|
||||||
|
@ -572,7 +572,7 @@ impl<'bump> ScopeArena {
|
||||||
for listener in new.listeners {
|
for listener in new.listeners {
|
||||||
listener.mounted_node.set(Some(root));
|
listener.mounted_node.set(Some(root));
|
||||||
state.mutations.new_event_listener(listener, cur_scope_id);
|
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
|
// Utilities
|
||||||
// =====================
|
// =====================
|
||||||
|
|
||||||
fn find_last_element(
|
fn find_last_element(&'bump self, vnode: &'bump VNode<'bump>) -> Option<ElementId> {
|
||||||
&'bump self,
|
|
||||||
state: &mut DiffState<'bump>,
|
|
||||||
vnode: &'bump VNode<'bump>,
|
|
||||||
) -> Option<ElementId> {
|
|
||||||
let mut search_node = Some(vnode);
|
let mut search_node = Some(vnode);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
@ -1156,11 +1152,7 @@ impl<'bump> ScopeArena {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_first_element_id(
|
fn find_first_element_id(&'bump self, vnode: &'bump VNode<'bump>) -> Option<ElementId> {
|
||||||
&'bump self,
|
|
||||||
state: &mut DiffState<'bump>,
|
|
||||||
vnode: &'bump VNode<'bump>,
|
|
||||||
) -> Option<ElementId> {
|
|
||||||
let mut search_node = Some(vnode);
|
let mut search_node = Some(vnode);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
@ -1288,12 +1280,7 @@ impl<'bump> ScopeArena {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a listener closure to a scope during diff.
|
/// Adds a listener closure to a scope during diff.
|
||||||
fn attach_listener_to_scope(
|
fn attach_listener_to_scope(&'bump self, listener: &'bump Listener<'bump>, scope: &ScopeState) {
|
||||||
&'bump self,
|
|
||||||
state: &mut DiffState<'bump>,
|
|
||||||
listener: &'bump Listener<'bump>,
|
|
||||||
scope: &ScopeState,
|
|
||||||
) {
|
|
||||||
let long_listener = unsafe { std::mem::transmute(listener) };
|
let long_listener = unsafe { std::mem::transmute(listener) };
|
||||||
scope.items.borrow_mut().listeners.push(long_listener)
|
scope.items.borrow_mut().listeners.push(long_listener)
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,14 +39,12 @@ impl<'a, 'b> LazyNodes<'a, 'b> {
|
||||||
where
|
where
|
||||||
F: FnOnce(NodeFactory<'a>) -> VNode<'a> + 'b,
|
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 mut slot = Some(_val);
|
||||||
|
|
||||||
let val = move |f| {
|
let val = move |fac: Option<NodeFactory<'a>>| {
|
||||||
let inn = slot.take().unwrap();
|
let inner = slot.take().unwrap();
|
||||||
match f {
|
fac.map(inner)
|
||||||
Some(f) => Some(inn(f)),
|
|
||||||
None => None,
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe { LazyNodes::new_inner(val) }
|
unsafe { LazyNodes::new_inner(val) }
|
||||||
|
@ -125,7 +123,6 @@ impl<'a, 'b> LazyNodes<'a, 'b> {
|
||||||
*dataptr.add(i) = *src_ptr.add(i);
|
*dataptr.add(i) = *src_ptr.add(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
log::debug!("I am forgetting the contents of the stuff");
|
|
||||||
std::mem::forget(val);
|
std::mem::forget(val);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
@ -143,7 +140,6 @@ impl<'a, 'b> LazyNodes<'a, 'b> {
|
||||||
StackNodeStorage::Heap(mut lazy) => lazy(Some(f)).unwrap(),
|
StackNodeStorage::Heap(mut lazy) => lazy(Some(f)).unwrap(),
|
||||||
StackNodeStorage::Stack(mut stack) => stack.call(f),
|
StackNodeStorage::Stack(mut stack) => stack.call(f),
|
||||||
}
|
}
|
||||||
// todo drop?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,25 +150,12 @@ struct LazyStack {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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> {
|
fn call<'a>(&mut self, f: NodeFactory<'a>) -> VNode<'a> {
|
||||||
let LazyStack { buf, .. } = self;
|
let LazyStack { buf, .. } = self;
|
||||||
let data = buf.as_ref();
|
let data = buf.as_ref();
|
||||||
|
|
||||||
let info_size =
|
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>()
|
/ mem::size_of::<usize>()
|
||||||
- 1;
|
- 1;
|
||||||
|
|
||||||
|
@ -190,13 +173,11 @@ impl LazyStack {
|
||||||
impl Drop for LazyStack {
|
impl Drop for LazyStack {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if !self.dropped {
|
if !self.dropped {
|
||||||
log::debug!("manually dropping lazy nodes");
|
|
||||||
|
|
||||||
let LazyStack { buf, .. } = self;
|
let LazyStack { buf, .. } = self;
|
||||||
let data = buf.as_ref();
|
let data = buf.as_ref();
|
||||||
|
|
||||||
let info_size = mem::size_of::<
|
let info_size = mem::size_of::<
|
||||||
*mut dyn FnOnce(Option<NodeFactory<'_>>) -> Option<VNode<'_>>,
|
*mut dyn FnMut(Option<NodeFactory<'_>>) -> Option<VNode<'_>>,
|
||||||
>() / mem::size_of::<usize>()
|
>() / mem::size_of::<usize>()
|
||||||
- 1;
|
- 1;
|
||||||
|
|
||||||
|
|
|
@ -177,7 +177,7 @@ impl<'src> VNode<'src> {
|
||||||
|
|
||||||
pub fn children(&self) -> &[VNode<'src>] {
|
pub fn children(&self) -> &[VNode<'src>] {
|
||||||
match &self {
|
match &self {
|
||||||
VNode::Fragment(f) => &f.children,
|
VNode::Fragment(f) => f.children,
|
||||||
VNode::Component(c) => todo!("children are not accessible through this"),
|
VNode::Component(c) => todo!("children are not accessible through this"),
|
||||||
_ => &[],
|
_ => &[],
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,6 @@ impl ScopeArena {
|
||||||
parent_scope: Option<*mut ScopeState>,
|
parent_scope: Option<*mut ScopeState>,
|
||||||
height: u32,
|
height: u32,
|
||||||
subtree: u32,
|
subtree: u32,
|
||||||
sender: UnboundedSender<SchedulerMsg>,
|
|
||||||
) -> ScopeId {
|
) -> ScopeId {
|
||||||
if let Some(id) = self.free_scopes.pop() {
|
if let Some(id) = self.free_scopes.pop() {
|
||||||
// have already called drop on it - the slot is still chillin tho
|
// 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 vcomp = unsafe { std::mem::transmute(vcomp as *const VComponent) };
|
||||||
|
|
||||||
let new_scope = ScopeState {
|
let new_scope = ScopeState {
|
||||||
sender,
|
sender: self.sender.clone(),
|
||||||
parent_scope,
|
parent_scope,
|
||||||
our_arena_idx: id,
|
our_arena_idx: id,
|
||||||
height,
|
height,
|
||||||
|
|
|
@ -69,7 +69,7 @@ use std::{
|
||||||
pub struct VirtualDom {
|
pub struct VirtualDom {
|
||||||
base_scope: ScopeId,
|
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
|
// we need to keep the allocation around, but we don't necessarily use it
|
||||||
_root_caller: Box<dyn Any>,
|
_root_caller: Box<dyn Any>,
|
||||||
|
@ -156,7 +156,7 @@ impl VirtualDom {
|
||||||
sender: UnboundedSender<SchedulerMsg>,
|
sender: UnboundedSender<SchedulerMsg>,
|
||||||
receiver: UnboundedReceiver<SchedulerMsg>,
|
receiver: UnboundedReceiver<SchedulerMsg>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut scopes = ScopeArena::new(sender.clone());
|
let mut scopes = ScopeArena::new(sender);
|
||||||
|
|
||||||
let base_scope = scopes.new_with_key(
|
let base_scope = scopes.new_with_key(
|
||||||
//
|
//
|
||||||
|
@ -166,7 +166,6 @@ impl VirtualDom {
|
||||||
None,
|
None,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
sender.clone(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
@ -175,7 +174,7 @@ impl VirtualDom {
|
||||||
receiver,
|
receiver,
|
||||||
sender,
|
sender,
|
||||||
|
|
||||||
root_props: todo!(),
|
_root_props: todo!(),
|
||||||
_root_caller: todo!(),
|
_root_caller: todo!(),
|
||||||
|
|
||||||
pending_messages: VecDeque::new(),
|
pending_messages: VecDeque::new(),
|
||||||
|
@ -201,7 +200,7 @@ impl VirtualDom {
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
pub fn get_scope<'a>(&'a self, id: &ScopeId) -> Option<&'a ScopeState> {
|
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.
|
/// 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
|
// 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) };
|
let unpinned = unsafe { Pin::new_unchecked(task) };
|
||||||
|
|
||||||
if let Poll::Ready(_) = unpinned.poll(cx) {
|
if unpinned.poll(cx).is_ready() {
|
||||||
all_pending = false
|
all_pending = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -331,7 +330,7 @@ impl VirtualDom {
|
||||||
///
|
///
|
||||||
/// loop {
|
/// loop {
|
||||||
/// let mut timeout = TimeoutFuture::from_ms(16);
|
/// 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;
|
/// let mutations = dom.run_with_deadline(deadline).await;
|
||||||
///
|
///
|
||||||
|
@ -346,11 +345,8 @@ impl VirtualDom {
|
||||||
/// applied the edits.
|
/// applied the edits.
|
||||||
///
|
///
|
||||||
/// Mutations are the only link between the RealDOM and the VirtualDOM.
|
/// Mutations are the only link between the RealDOM and the VirtualDOM.
|
||||||
pub fn work_with_deadline<'a>(
|
pub fn work_with_deadline(&mut self, mut deadline: impl FnMut() -> bool) -> Vec<Mutations> {
|
||||||
&'a mut self,
|
let mut committed_mutations = vec![];
|
||||||
mut deadline: impl FnMut() -> bool,
|
|
||||||
) -> Vec<Mutations<'a>> {
|
|
||||||
let mut committed_mutations = Vec::<Mutations>::new();
|
|
||||||
|
|
||||||
while self.has_any_work() {
|
while self.has_any_work() {
|
||||||
while let Ok(Some(msg)) = self.receiver.try_next() {
|
while let Ok(Some(msg)) = self.receiver.try_next() {
|
||||||
|
@ -375,7 +371,7 @@ impl VirtualDom {
|
||||||
self.pending_messages.push_front(dirty_scope);
|
self.pending_messages.push_front(dirty_scope);
|
||||||
}
|
}
|
||||||
} else {
|
} 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);
|
committed_mutations.push(mutations);
|
||||||
} else {
|
} 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;
|
return committed_mutations;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -506,7 +503,7 @@ impl VirtualDom {
|
||||||
pub fn hard_diff<'a>(&'a mut self, scope_id: &ScopeId) -> Option<Mutations<'a>> {
|
pub fn hard_diff<'a>(&'a mut self, scope_id: &ScopeId) -> Option<Mutations<'a>> {
|
||||||
log::debug!("hard diff {:?}", scope_id);
|
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());
|
let mut diff_machine = DiffState::new(Mutations::new());
|
||||||
|
|
||||||
diff_machine.force_diff = true;
|
diff_machine.force_diff = true;
|
||||||
|
|
Loading…
Reference in a new issue