use boxed slices instead of vecs where possible
This commit is contained in:
1 parent
c59926cb1f
commit
aefa8a2431
9 files changed
+53
-46
No files matched your search
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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(),
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -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,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -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,
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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 ),* ]),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user