mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-10 14:44:12 +00:00
fix mounted information
This commit is contained in:
parent
967c082085
commit
b43dfb1f67
6 changed files with 44 additions and 35 deletions
|
@ -23,11 +23,6 @@ impl Default for MountId {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MountId {
|
impl MountId {
|
||||||
pub(crate) fn new(id: usize) -> Self {
|
|
||||||
debug_assert_ne!(id, usize::MAX);
|
|
||||||
Self(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn as_usize(self) -> Option<usize> {
|
pub(crate) fn as_usize(self) -> Option<usize> {
|
||||||
if self.0 == usize::MAX {
|
if self.0 == usize::MAX {
|
||||||
None
|
None
|
||||||
|
@ -35,10 +30,6 @@ impl MountId {
|
||||||
Some(self.0)
|
Some(self.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn is_none(self) -> bool {
|
|
||||||
self.0 == usize::MAX
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
|
|
@ -22,9 +22,6 @@ impl VirtualDom {
|
||||||
let new = &new_nodes;
|
let new = &new_nodes;
|
||||||
let old = scope_state.last_rendered_node.take().unwrap();
|
let old = scope_state.last_rendered_node.take().unwrap();
|
||||||
|
|
||||||
use RenderReturn::{Aborted, Ready};
|
|
||||||
|
|
||||||
let (Ready(old) | Aborted(old), Ready(new) | Aborted(new)) = (&old, new);
|
|
||||||
old.diff_node(new, self, to);
|
old.diff_node(new, self, to);
|
||||||
|
|
||||||
let scope_state = &mut self.scopes[scope.0];
|
let scope_state = &mut self.scopes[scope.0];
|
||||||
|
@ -40,11 +37,17 @@ impl VirtualDom {
|
||||||
&mut self,
|
&mut self,
|
||||||
to: &mut impl WriteMutations,
|
to: &mut impl WriteMutations,
|
||||||
scope: ScopeId,
|
scope: ScopeId,
|
||||||
new_node: &VNode,
|
new_node: &RenderReturn,
|
||||||
parent: Option<ElementRef>,
|
parent: Option<ElementRef>,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
self.runtime.scope_stack.borrow_mut().push(scope);
|
self.runtime.scope_stack.borrow_mut().push(scope);
|
||||||
|
|
||||||
|
// Create the node
|
||||||
let nodes = new_node.create(self, to, parent);
|
let nodes = new_node.create(self, to, parent);
|
||||||
|
|
||||||
|
// Then set the new node as the last rendered node
|
||||||
|
self.scopes[scope.0].last_rendered_node = Some(new_node.clone());
|
||||||
|
|
||||||
self.runtime.scope_stack.borrow_mut().pop();
|
self.runtime.scope_stack.borrow_mut().pop();
|
||||||
nodes
|
nodes
|
||||||
}
|
}
|
||||||
|
@ -134,8 +137,6 @@ impl VNode {
|
||||||
|
|
||||||
let new = dom.run_scope(scope);
|
let new = dom.run_scope(scope);
|
||||||
|
|
||||||
dom.scopes[scope.0].last_rendered_node = Some(new.clone());
|
|
||||||
|
|
||||||
dom.create_scope(to, scope, &new, parent)
|
dom.create_scope(to, scope, &new, parent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,9 @@ impl VNode {
|
||||||
dom: &mut VirtualDom,
|
dom: &mut VirtualDom,
|
||||||
to: &mut impl WriteMutations,
|
to: &mut impl WriteMutations,
|
||||||
) {
|
) {
|
||||||
|
// The node we are diffing from should always be mounted
|
||||||
|
debug_assert!(dom.mounts.get(self.mount.get().0).is_some());
|
||||||
|
|
||||||
// If hot reloading is enabled, we need to make sure we're using the latest template
|
// If hot reloading is enabled, we need to make sure we're using the latest template
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
{
|
{
|
||||||
|
@ -44,7 +47,7 @@ impl VNode {
|
||||||
let mount = &mut dom.mounts[mount_id.0];
|
let mount = &mut dom.mounts[mount_id.0];
|
||||||
|
|
||||||
// Update the reference to the node for bubbling events
|
// Update the reference to the node for bubbling events
|
||||||
mount.node = new.clone_with_parent();
|
mount.node = new.clone_mounted();
|
||||||
|
|
||||||
// If the templates are the same, we don't need to do anything, except copy over the mount information
|
// If the templates are the same, we don't need to do anything, except copy over the mount information
|
||||||
if self == new {
|
if self == new {
|
||||||
|
@ -216,6 +219,8 @@ impl VNode {
|
||||||
|
|
||||||
// Remove the mount information
|
// Remove the mount information
|
||||||
dom.mounts.remove(mount.0);
|
dom.mounts.remove(mount.0);
|
||||||
|
|
||||||
|
tracing::trace!(?self, "removed node");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reclaim_roots(
|
fn reclaim_roots(
|
||||||
|
@ -419,6 +424,19 @@ impl VNode {
|
||||||
// Just in case, let's create the template using instructions anyways
|
// Just in case, let's create the template using instructions anyways
|
||||||
dom.register_template(to, template);
|
dom.register_template(to, template);
|
||||||
|
|
||||||
|
// Initialize the mount information for this template
|
||||||
|
let entry = dom.mounts.vacant_entry();
|
||||||
|
let mount = MountId(entry.key());
|
||||||
|
self.mount.set(mount);
|
||||||
|
tracing::info!(?self, ?mount, "creating template");
|
||||||
|
entry.insert(VNodeMount {
|
||||||
|
node: self.clone_mounted(),
|
||||||
|
parent,
|
||||||
|
root_ids: vec![ElementId(0); template.roots.len()].into_boxed_slice(),
|
||||||
|
mounted_attributes: vec![ElementId(0); template.attr_paths.len()].into_boxed_slice(),
|
||||||
|
mounted_dynamic_nodes: vec![0; template.node_paths.len()].into_boxed_slice(),
|
||||||
|
});
|
||||||
|
|
||||||
// Walk the roots, creating nodes and assigning IDs
|
// Walk the roots, creating nodes and assigning IDs
|
||||||
// nodes in an iterator of ((dynamic_node_index, sorted_index), path)
|
// nodes in an iterator of ((dynamic_node_index, sorted_index), path)
|
||||||
// todo: adjust dynamic nodes to be in the order of roots and then leaves (ie BFS)
|
// todo: adjust dynamic nodes to be in the order of roots and then leaves (ie BFS)
|
||||||
|
@ -451,18 +469,6 @@ impl VNode {
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initialize the mount information for this template
|
|
||||||
let entry = dom.mounts.vacant_entry();
|
|
||||||
let mount = MountId(entry.key());
|
|
||||||
self.mount.set(mount);
|
|
||||||
entry.insert(VNodeMount {
|
|
||||||
node: self.clone_with_parent(),
|
|
||||||
parent,
|
|
||||||
root_ids: vec![ElementId(0); template.roots.len()].into_boxed_slice(),
|
|
||||||
mounted_attributes: vec![ElementId(0); template.attr_paths.len()].into_boxed_slice(),
|
|
||||||
mounted_dynamic_nodes: vec![0; template.node_paths.len()].into_boxed_slice(),
|
|
||||||
});
|
|
||||||
|
|
||||||
template
|
template
|
||||||
.roots
|
.roots
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -672,6 +678,10 @@ impl VNode {
|
||||||
AttributeValue::Listener(_) => {
|
AttributeValue::Listener(_) => {
|
||||||
// If this is a listener, we need to create an element reference for it so that when we receive an event, we can find the element
|
// If this is a listener, we need to create an element reference for it so that when we receive an event, we can find the element
|
||||||
let path = &self.template.get().attr_paths[idx];
|
let path = &self.template.get().attr_paths[idx];
|
||||||
|
|
||||||
|
// The mount information should always be in the VDOM at this point
|
||||||
|
debug_assert!(dom.mounts.get(mount.0).is_some());
|
||||||
|
|
||||||
let element_ref = ElementRef {
|
let element_ref = ElementRef {
|
||||||
path: ElementPath { path },
|
path: ElementPath { path },
|
||||||
mount,
|
mount,
|
||||||
|
|
|
@ -29,7 +29,6 @@ pub(crate) mod innerlude {
|
||||||
pub use crate::fragment::*;
|
pub use crate::fragment::*;
|
||||||
pub use crate::global_context::*;
|
pub use crate::global_context::*;
|
||||||
pub use crate::mutations::*;
|
pub use crate::mutations::*;
|
||||||
pub use crate::nodes::RenderReturn;
|
|
||||||
pub use crate::nodes::*;
|
pub use crate::nodes::*;
|
||||||
pub use crate::properties::*;
|
pub use crate::properties::*;
|
||||||
pub use crate::runtime::{Runtime, RuntimeGuard};
|
pub use crate::runtime::{Runtime, RuntimeGuard};
|
||||||
|
@ -75,7 +74,7 @@ pub(crate) mod innerlude {
|
||||||
pub use crate::innerlude::{
|
pub use crate::innerlude::{
|
||||||
fc_to_builder, generation, once, schedule_update, schedule_update_any, vdom_is_rendering,
|
fc_to_builder, generation, once, schedule_update, schedule_update_any, vdom_is_rendering,
|
||||||
AnyValue, Attribute, AttributeValue, CapturedError, Component, DynamicNode, Element, ElementId,
|
AnyValue, Attribute, AttributeValue, CapturedError, Component, DynamicNode, Element, ElementId,
|
||||||
Event, Fragment, IntoDynNode, Mutation, MutationsVec, Properties, RenderReturn, ScopeId, Task,
|
Event, Fragment, IntoDynNode, Mutation, MutationsVec, Properties, ScopeId, Task,
|
||||||
Template, TemplateAttribute, TemplateNode, VComponent, VNode, VNodeInner, VPlaceholder, VText,
|
Template, TemplateAttribute, TemplateNode, VComponent, VNode, VNodeInner, VPlaceholder, VText,
|
||||||
VirtualDom, WriteMutations,
|
VirtualDom, WriteMutations,
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,8 +20,7 @@ pub type TemplateId = &'static str;
|
||||||
///
|
///
|
||||||
/// Dioxus will do its best to immediately resolve any async components into a regular Element, but as an implementor
|
/// Dioxus will do its best to immediately resolve any async components into a regular Element, but as an implementor
|
||||||
/// you might need to handle the case where there's no node immediately ready.
|
/// you might need to handle the case where there's no node immediately ready.
|
||||||
#[derive(Clone)]
|
pub(crate) enum RenderReturn {
|
||||||
pub enum RenderReturn {
|
|
||||||
/// A currently-available element
|
/// A currently-available element
|
||||||
Ready(VNode),
|
Ready(VNode),
|
||||||
|
|
||||||
|
@ -31,6 +30,15 @@ pub enum RenderReturn {
|
||||||
Aborted(VNode),
|
Aborted(VNode),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Clone for RenderReturn {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
match self {
|
||||||
|
RenderReturn::Ready(node) => RenderReturn::Ready(node.clone_mounted()),
|
||||||
|
RenderReturn::Aborted(node) => RenderReturn::Aborted(node.clone_mounted()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for RenderReturn {
|
impl Default for RenderReturn {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
RenderReturn::Aborted(VNode::placeholder())
|
RenderReturn::Aborted(VNode::placeholder())
|
||||||
|
@ -125,8 +133,8 @@ impl Deref for VNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VNode {
|
impl VNode {
|
||||||
/// Clone the element while retaining the mounted parent of the node
|
/// Clone the element while retaining the mount information of the node
|
||||||
pub(crate) fn clone_with_parent(&self) -> Self {
|
pub(crate) fn clone_mounted(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
vnode: self.vnode.clone(),
|
vnode: self.vnode.clone(),
|
||||||
mount: self.mount.clone(),
|
mount: self.mount.clone(),
|
||||||
|
|
|
@ -556,10 +556,10 @@ impl VirtualDom {
|
||||||
self.flush_templates(to);
|
self.flush_templates(to);
|
||||||
let _runtime = RuntimeGuard::new(self.runtime.clone());
|
let _runtime = RuntimeGuard::new(self.runtime.clone());
|
||||||
let new_nodes = self.run_scope(ScopeId::ROOT);
|
let new_nodes = self.run_scope(ScopeId::ROOT);
|
||||||
self.scopes[ScopeId::ROOT.0].last_rendered_node = Some(new_nodes.clone());
|
|
||||||
|
|
||||||
// Rebuilding implies we append the created elements to the root
|
// Rebuilding implies we append the created elements to the root
|
||||||
let m = self.create_scope(to, ScopeId::ROOT, &new_nodes, None);
|
let m = self.create_scope(to, ScopeId::ROOT, &new_nodes, None);
|
||||||
|
|
||||||
to.append_children(ElementId(0), m);
|
to.append_children(ElementId(0), m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue