use boxed slices instead of vecs where possible

This commit is contained in:
Evan Almloff committed 2024-01-07 13:41:39 -06:00
1 parent c59926cb1f
commit aefa8a2431
9 files changed
+53 -46

No files matched your search

+8 -8
View File
@@ -76,7 +76,7 @@ impl VirtualDom {
/// Create this template and write its mutations /// Create this template and write its mutations
pub(crate) fn create(&mut self, node: &VNode, to: &mut impl WriteMutations) -> usize { pub(crate) fn create(&mut self, node: &VNode, to: &mut impl WriteMutations) -> usize {
// check for a overriden template // check for a overridden template
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
{ {
let (path, byte_index) = node.template.get().name.rsplit_once(':').unwrap(); let (path, byte_index) = node.template.get().name.rsplit_once(':').unwrap();
@@ -86,14 +86,14 @@ impl VirtualDom {
.and_then(|map| map.get(&byte_index.parse().unwrap())) .and_then(|map| map.get(&byte_index.parse().unwrap()))
{ {
node.template.set(*template); node.template.set(*template);
}
}
// Initialize the root nodes slice // Initialize the root nodes slice if it was changed
{ let mut nodes_mut = node.root_ids.borrow_mut();
let mut nodes_mut = node.root_ids.borrow_mut(); let len = node.template.get().roots.len();
let len = node.template.get().roots.len(); if nodes_mut.len() != len {
nodes_mut.resize(len, ElementId::default()); *nodes_mut = vec![ElementId::default(); len].into_boxed_slice();
};
}
}; };
// The best renderers will have templates prehydrated and registered // The best renderers will have templates prehydrated and registered
+3 -3
View File
@@ -149,9 +149,9 @@ impl VirtualDom {
// Make sure the roots get transferred over while we're here // Make sure the roots get transferred over while we're here
{ {
let mut right = right_template.root_ids.borrow_mut(); let mut right = right_template.root_ids.borrow_mut();
right.clear(); let left = left_template.root_ids.borrow();
for &element in left_template.root_ids.borrow().iter() { for (from, into) in left.iter().zip(right.iter_mut()) {
right.push(element); *into = *from;
} }
} }
} }
+13 -1
View File
@@ -2,12 +2,24 @@ use std::hash::Hash;
use crate::ScopeId; use crate::ScopeId;
#[derive(Debug, Clone, Eq, PartialOrd, Ord)] #[derive(Debug, Clone, Eq)]
pub struct DirtyScope { pub struct DirtyScope {
pub height: u32, pub height: u32,
pub id: ScopeId, pub id: ScopeId,
} }
impl PartialOrd for DirtyScope {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for DirtyScope {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.height.cmp(&other.height).then(self.id.cmp(&other.id))
}
}
impl PartialEq for DirtyScope { impl PartialEq for DirtyScope {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.id == other.id self.id == other.id
+4 -4
View File
@@ -287,8 +287,8 @@ fn default_handler(error: CapturedError) -> Element {
Some(VNode::new( Some(VNode::new(
None, None,
TEMPLATE, TEMPLATE,
Vec::with_capacity(1usize), Box::new([Default::default(); 1]),
vec![error.to_string().into_dyn_node()], Box::new([error.to_string().into_dyn_node()]),
Default::default(), Default::default(),
)) ))
} }
@@ -460,8 +460,8 @@ pub fn ErrorBoundary(props: ErrorBoundaryProps) -> Element {
VNode::new( VNode::new(
None, None,
TEMPLATE, TEMPLATE,
Vec::with_capacity(1usize), Box::new([Default::default(); 1]),
vec![(props.children).into_dyn_node()], Box::new([(props.children).into_dyn_node()]),
Default::default(), Default::default(),
) )
}), }),
+4 -3
View File
@@ -77,8 +77,8 @@ 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, RenderReturn, ScopeId, Task,
Template, TemplateAttribute, TemplateNode, VComponent, VNode, VPlaceholder, VText, VirtualDom, Template, TemplateAttribute, TemplateNode, VComponent, VNode, VNodeInner, VPlaceholder, VText,
WriteMutations, VirtualDom, WriteMutations,
}; };
/// The purpose of this module is to alleviate imports of many common types /// The purpose of this module is to alleviate imports of many common types
@@ -91,6 +91,7 @@ pub mod prelude {
push_future, remove_future, schedule_update, schedule_update_any, spawn, spawn_forever, push_future, remove_future, schedule_update, schedule_update_any, spawn, spawn_forever,
suspend, use_error_boundary, AnyValue, Component, Element, ErrorBoundary, Event, suspend, use_error_boundary, AnyValue, Component, Element, ErrorBoundary, Event,
EventHandler, Fragment, IntoAttributeValue, IntoDynNode, Properties, Runtime, RuntimeGuard, EventHandler, Fragment, IntoAttributeValue, IntoDynNode, Properties, Runtime, RuntimeGuard,
ScopeId, Task, Template, TemplateAttribute, TemplateNode, Throw, VNode, VirtualDom, ScopeId, Task, Template, TemplateAttribute, TemplateNode, Throw, VNode, VNodeInner,
VirtualDom,
}; };
} }
+9 -8
View File
@@ -4,6 +4,7 @@ use crate::Properties;
use crate::{arena::ElementId, Element, Event, ScopeId}; use crate::{arena::ElementId, Element, Event, ScopeId};
use std::ops::Deref; use std::ops::Deref;
use std::rc::Rc; use std::rc::Rc;
use std::vec;
use std::{ use std::{
any::{Any, TypeId}, any::{Any, TypeId},
cell::{Cell, RefCell}, cell::{Cell, RefCell},
@@ -53,16 +54,16 @@ pub struct VNodeInner {
/// The IDs for the roots of this template - to be used when moving the template around and removing it from /// The IDs for the roots of this template - to be used when moving the template around and removing it from
/// the actual Dom /// the actual Dom
pub root_ids: RefCell<Vec<ElementId>>, pub root_ids: RefCell<Box<[ElementId]>>,
/// The static nodes and static descriptor of the template /// The static nodes and static descriptor of the template
pub template: Cell<Template>, pub template: Cell<Template>,
/// The dynamic parts of the template /// The dynamic parts of the template
pub dynamic_nodes: Vec<DynamicNode>, pub dynamic_nodes: Box<[DynamicNode]>,
/// The dynamic parts of the template /// The dynamic parts of the template
pub dynamic_attrs: Vec<Attribute>, pub dynamic_attrs: Box<[Attribute]>,
} }
/// A reference to a template along with any context needed to hydrate it /// A reference to a template along with any context needed to hydrate it
@@ -93,8 +94,8 @@ impl VNode {
key: None, key: None,
parent: Default::default(), parent: Default::default(),
root_ids: Default::default(), root_ids: Default::default(),
dynamic_nodes: Vec::new(), dynamic_nodes: Box::new([]),
dynamic_attrs: Vec::new(), dynamic_attrs: Box::new([]),
template: Cell::new(Template { template: Cell::new(Template {
name: "dioxus-empty", name: "dioxus-empty",
roots: &[], roots: &[],
@@ -108,9 +109,9 @@ impl VNode {
pub fn new( pub fn new(
key: Option<String>, key: Option<String>,
template: Template, template: Template,
root_ids: Vec<ElementId>, root_ids: Box<[ElementId]>,
dynamic_nodes: Vec<DynamicNode>, dynamic_nodes: Box<[DynamicNode]>,
dynamic_attrs: Vec<Attribute>, dynamic_attrs: Box<[Attribute]>,
) -> Self { ) -> Self {
Self(Rc::new(VNodeInner { Self(Rc::new(VNodeInner {
key, key,
+5 -12
View File
@@ -317,9 +317,9 @@ impl VirtualDom {
/// ///
/// Whenever the Runtime "works", it will re-render this scope /// Whenever the Runtime "works", it will re-render this scope
pub fn mark_dirty(&mut self, id: ScopeId) { pub fn mark_dirty(&mut self, id: ScopeId) {
if let Some(scope) = self.get_scope(id) { if let Some(context) = self.runtime.get_context(id) {
let height = scope.context().height(); let height = context.height();
tracing::trace!("Marking scope {:?} ({}) as dirty", id, scope.context().name); tracing::trace!("Marking scope {:?} ({}) as dirty", id, context.name);
self.dirty_scopes.insert(DirtyScope { height, id }); self.dirty_scopes.insert(DirtyScope { height, id });
} }
} }
@@ -504,7 +504,7 @@ impl VirtualDom {
/// Replace a template at runtime. This will re-render all components that use this template. /// Replace a template at runtime. This will re-render all components that use this template.
/// This is the primitive that enables hot-reloading. /// This is the primitive that enables hot-reloading.
/// ///
/// The caller must ensure that the template refrences the same dynamic attributes and nodes as the original template. /// The caller must ensure that the template references the same dynamic attributes and nodes as the original template.
/// ///
/// This will only replace the the parent template, not any nested templates. /// This will only replace the the parent template, not any nested templates.
pub fn replace_template(&mut self, template: Template) { pub fn replace_template(&mut self, template: Template) {
@@ -619,9 +619,7 @@ impl VirtualDom {
loop { loop {
// Next, diff any dirty scopes // Next, diff any dirty scopes
// We choose not to poll the deadline since we complete pretty quickly anyways // We choose not to poll the deadline since we complete pretty quickly anyways
if let Some(dirty) = self.dirty_scopes.iter().next().cloned() { while let Some(dirty) = self.dirty_scopes.pop_first() {
self.dirty_scopes.remove(&dirty);
// If the scope doesn't exist for whatever reason, then we should skip it // If the scope doesn't exist for whatever reason, then we should skip it
if !self.scopes.contains(dirty.id.0) { if !self.scopes.contains(dirty.id.0) {
continue; continue;
@@ -635,11 +633,6 @@ impl VirtualDom {
} }
} }
// If there's more work, then just continue, plenty of work to do
if !self.dirty_scopes.is_empty() {
continue;
}
// Poll the suspense leaves in the meantime // Poll the suspense leaves in the meantime
let mut work = self.wait_for_work(); let mut work = self.wait_for_work();
@@ -15,7 +15,7 @@ use syn::spanned::Spanned;
use super::hot_reload_diff::{find_rsx, DiffResult}; use super::hot_reload_diff::{find_rsx, DiffResult};
pub enum UpdateResult { pub enum UpdateResult {
UpdatedRsx(Vec<Template<'static>>), UpdatedRsx(Vec<Template>),
NeedsRebuild, NeedsRebuild,
} }
@@ -28,7 +28,7 @@ pub struct FileMapBuildResult<Ctx: HotReloadingContext> {
} }
pub struct FileMap<Ctx: HotReloadingContext> { pub struct FileMap<Ctx: HotReloadingContext> {
pub map: HashMap<PathBuf, (String, Option<Template<'static>>)>, pub map: HashMap<PathBuf, (String, Option<Template>)>,
in_workspace: HashMap<PathBuf, Option<PathBuf>>, in_workspace: HashMap<PathBuf, Option<PathBuf>>,
phantom: std::marker::PhantomData<Ctx>, phantom: std::marker::PhantomData<Ctx>,
} }
@@ -45,7 +45,7 @@ impl<Ctx: HotReloadingContext> FileMap<Ctx> {
mut filter: impl FnMut(&Path) -> bool, mut filter: impl FnMut(&Path) -> bool,
) -> io::Result<FileMapBuildResult<Ctx>> { ) -> io::Result<FileMapBuildResult<Ctx>> {
struct FileMapSearchResult { struct FileMapSearchResult {
map: HashMap<PathBuf, (String, Option<Template<'static>>)>, map: HashMap<PathBuf, (String, Option<Template>)>,
errors: Vec<io::Error>, errors: Vec<io::Error>,
} }
fn find_rs_files( fn find_rs_files(
@@ -115,7 +115,7 @@ impl<Ctx: HotReloadingContext> FileMap<Ctx> {
self.map.insert(file_path.to_path_buf(), (src, None)); self.map.insert(file_path.to_path_buf(), (src, None));
} }
DiffResult::RsxChanged(changed) => { DiffResult::RsxChanged(changed) => {
let mut messages: Vec<Template<'static>> = Vec::new(); let mut messages: Vec<Template> = Vec::new();
for (old, new) in changed.into_iter() { for (old, new) in changed.into_iter() {
let old_start = old.span().start(); let old_start = old.span().start();
+3 -3
View File
@@ -256,9 +256,9 @@ impl<'a> ToTokens for TemplateRenderer<'a> {
::dioxus::core::VNode::new( ::dioxus::core::VNode::new(
#key_tokens, #key_tokens,
TEMPLATE, TEMPLATE,
Vec::with_capacity(#root_count), Box::new([Default::default();#root_count]),
vec![ #( #node_printer ),* ], Box::new([ #( #node_printer ),* ]),
vec![ #( #dyn_attr_printer ),* ], Box::new([ #( #dyn_attr_printer ),* ]),
) )
}); });
} }