feat: make hooks free-functions

This commit is contained in:
Jonathan Kelley committed 2021-07-27 11:28:05 -04:00
1 parent f782e14211
commit e5c88fe3a4
13 files changed
+373 -323

No files matched your search

+23 -3
View File
@@ -12,6 +12,7 @@ use std::{
cell::{Cell, RefCell},
fmt::{Arguments, Debug, Formatter},
marker::PhantomData,
mem::ManuallyDrop,
rc::Rc,
};
@@ -127,6 +128,8 @@ pub struct VComponent<'src> {
pub(crate) comparator: Option<&'src dyn Fn(&VComponent) -> bool>,
pub(crate) drop_props: Option<&'src dyn FnOnce()>,
pub is_static: bool,
// a pointer into the bump arena (given by the 'src lifetime)
@@ -335,15 +338,22 @@ impl<'a> NodeFactory<'a> {
// We don't want the fat part of the fat pointer
// This function does static dispatch so we don't need any VTable stuff
let props = self.bump().alloc(props);
let raw_props = props as *const P as *const ();
let raw_props = props as *mut P as *mut ();
let user_fc = component as *const ();
let comparator: Option<&dyn Fn(&VComponent) -> bool> = Some(self.bump().alloc_with(|| {
move |other: &VComponent| {
if user_fc == other.user_fc {
let real_other = unsafe { &*(other.raw_props as *const _ as *const P) };
let props_memoized = unsafe { props.memoize(&real_other) };
// Safety
// - We guarantee that FC<P> is the same by function pointer
// - Because FC<P> is the same, then P must be the same (even with generics)
// - Non-static P are autoderived to memoize as false
// - This comparator is only called on a corresponding set of bumpframes
let props_memoized = unsafe {
let real_other: &P = &*(other.raw_props as *const _ as *const P);
props.memoize(&real_other)
};
// It's only okay to memoize if there are no children and the props can be memoized
// Implementing memoize is unsafe and done automatically with the props trait
@@ -357,6 +367,15 @@ impl<'a> NodeFactory<'a> {
}
}));
// create a closure to drop the props
let drop_props: Option<&dyn FnOnce()> = Some(self.bump().alloc_with(|| {
move || unsafe {
let real_other = raw_props as *mut _ as *mut P;
let b = BumpBox::from_raw(real_other);
std::mem::drop(b);
}
}));
let is_static = children.len() == 0 && P::IS_STATIC && key.is_none();
VNode {
@@ -369,6 +388,7 @@ impl<'a> NodeFactory<'a> {
children,
caller: NodeFactory::create_component_caller(component, raw_props),
is_static,
drop_props,
ass_scope: Cell::new(None),
})),
}