Use zero cost option instead of null pointers

This commit is contained in:
Evan Almloff committed 2023-01-12 15:42:23 -06:00
commit 09da9c04a8
2 files changed
+10 -7

No files matched your search

+8 -5
View File
@@ -1,3 +1,5 @@
use std::ptr::NonNull;
use crate::{ use crate::{
nodes::RenderReturn, nodes::VNode, virtual_dom::VirtualDom, AttributeValue, DynamicNode, nodes::RenderReturn, nodes::VNode, virtual_dom::VirtualDom, AttributeValue, DynamicNode,
ScopeId, ScopeId,
@@ -17,7 +19,7 @@ pub(crate) struct ElementRef {
pub path: ElementPath, pub path: ElementPath,
// The actual template // The actual template
pub template: *const VNode<'static>, pub template: Option<NonNull<VNode<'static>>>,
} }
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
@@ -27,9 +29,9 @@ pub enum ElementPath {
} }
impl ElementRef { impl ElementRef {
pub(crate) fn null() -> Self { pub(crate) fn none() -> Self {
Self { Self {
template: std::ptr::null_mut(), template: None,
path: ElementPath::Root(0), path: ElementPath::Root(0),
} }
} }
@@ -48,7 +50,7 @@ impl VirtualDom {
let entry = self.elements.vacant_entry(); let entry = self.elements.vacant_entry();
let id = entry.key(); let id = entry.key();
entry.insert(ElementRef::null()); entry.insert(ElementRef::none());
ElementId(id) ElementId(id)
} }
@@ -57,7 +59,8 @@ impl VirtualDom {
let id = entry.key(); let id = entry.key();
entry.insert(ElementRef { entry.insert(ElementRef {
template: template as *const _ as *mut _, // We know this is non-null because it comes from a reference
template: Some(unsafe { NonNull::new_unchecked(template as *const _ as *mut _) }),
path, path,
}); });
ElementId(id) ElementId(id)
+2 -2
View File
@@ -282,7 +282,7 @@ impl VirtualDom {
root.provide_context(Rc::new(ErrorBoundary::new(ScopeId(0)))); root.provide_context(Rc::new(ErrorBoundary::new(ScopeId(0))));
// the root element is always given element ID 0 since it's the container for the entire tree // the root element is always given element ID 0 since it's the container for the entire tree
dom.elements.insert(ElementRef::null()); dom.elements.insert(ElementRef::none());
dom dom
} }
@@ -387,7 +387,7 @@ impl VirtualDom {
// Loop through each dynamic attribute in this template before moving up to the template's parent. // Loop through each dynamic attribute in this template before moving up to the template's parent.
while let Some(el_ref) = parent_path { while let Some(el_ref) = parent_path {
// safety: we maintain references of all vnodes in the element slab // safety: we maintain references of all vnodes in the element slab
let template = unsafe { &*el_ref.template }; let template = unsafe { el_ref.template.unwrap().as_ref() };
let node_template = template.template.get(); let node_template = template.template.get();
let target_path = el_ref.path; let target_path = el_ref.path;