wip: merge in some code from the other branch

This commit is contained in:
Jonathan Kelley committed 2021-06-05 23:47:54 -04:00
1 parent 795a54a2e4
commit 7790750349
12 files changed
+782 -124

No files matched your search

+45 -51
View File
@@ -27,7 +27,7 @@ pub enum VNode<'src> {
Element(&'src VElement<'src>),
/// A text node (node type `TEXT_NODE`).
Text(VText<'src>),
Text(&'src str),
/// A fragment is a "virtual position" in the DOM
/// Fragments may have children and keys
@@ -46,11 +46,11 @@ pub enum VNode<'src> {
impl<'a> Clone for VNode<'a> {
fn clone(&self) -> Self {
match self {
VNode::Element(el) => VNode::Element(el),
VNode::Text(origi) => VNode::Text(VText { text: origi.text }),
VNode::Fragment(frag) => VNode::Fragment(frag),
VNode::Element(element) => VNode::Element(element),
VNode::Text(text) => VNode::Text(text),
VNode::Fragment(fragment) => VNode::Fragment(fragment),
VNode::Component(component) => VNode::Component(component),
VNode::Suspended => VNode::Suspended,
VNode::Component(c) => VNode::Component(c),
}
}
}
@@ -86,7 +86,7 @@ impl<'a> VNode<'a> {
/// Construct a new text node with the given text.
#[inline]
pub fn text(text: &'a str) -> VNode<'a> {
VNode::Text(VText { text })
VNode::Text(text)
}
pub fn text_args(bump: &'a Bump, args: Arguments) -> VNode<'a> {
@@ -210,47 +210,31 @@ impl<'a> NodeKey<'a> {
}
}
#[derive(Debug, PartialEq)]
pub struct VText<'bump> {
pub text: &'bump str,
}
impl<'b> Clone for VText<'b> {
fn clone(&self) -> Self {
Self { text: self.text }
}
}
impl<'a> VText<'a> {
// / Create an new `VText` instance with the specified text.
pub fn new(text: &'a str) -> Self {
VText { text: text.into() }
}
}
// ==============================
// Custom components
// ==============================
/// Virtual Components for custom user-defined components
/// Only supports the functional syntax
pub type StableScopeAddres = RefCell<Option<u32>>;
pub type VCompAssociatedScope = RefCell<Option<ScopeIdx>>;
pub type StableScopeAddres = Option<u32>;
pub type VCompAssociatedScope = Option<ScopeIdx>;
pub struct VComponent<'src> {
pub key: NodeKey<'src>,
pub stable_addr: Rc<StableScopeAddres>,
pub ass_scope: Rc<VCompAssociatedScope>,
pub stable_addr: RefCell<StableScopeAddres>,
pub ass_scope: RefCell<VCompAssociatedScope>,
// pub comparator: Rc<dyn Fn(&VComponent) -> bool + 'src>,
pub caller: Rc<dyn Fn(&Scope) -> VNode + 'src>,
pub children: &'src [VNode<'src>],
pub comparator: Option<&'src dyn Fn(&VComponent) -> bool>,
// a pointer into the bump arena (given by the 'src lifetime)
// raw_props: Box<dyn Any>,
// raw_props: *const (),
raw_props: *const (),
// a pointer to the raw fn typ
pub user_fc: *const (),
@@ -264,7 +248,8 @@ impl<'a> VComponent<'a> {
// TODO: lift the requirement that props need to be static
// we want them to borrow references... maybe force implementing a "to_static_unsafe" trait
pub fn new<P: Properties>(
pub fn new<P: Properties + 'a>(
bump: &'a Bump,
component: FC<P>,
// props: bumpalo::boxed::Box<'a, P>,
props: P,
@@ -273,25 +258,32 @@ impl<'a> VComponent<'a> {
// pub fn new<P: Properties + 'a>(component: FC<P>, props: P, key: Option<&'a str>) -> Self {
// let bad_props = unsafe { transmogrify(props) };
let caller_ref = component as *const ();
let props = bump.alloc(props);
// let raw_props = props as *const P as *const ();
let raw_props = props as *const P as *const ();
// let props_comparator = move |other: &VComponent| {
// // Safety:
// // We are guaranteed that the props will be of the same type because
// // there is no way to create a VComponent other than this `new` method.
// //
// // Therefore, if the render functions are identical (by address), then so will be
// // props type paramter (because it is the same render function). Therefore, we can be
// // sure
// if caller_ref == other.user_fc {
// let g = other.raw_ctx.downcast_ref::<P>().unwrap();
// // let real_other = unsafe { &*(other.raw_props as *const _ as *const P) };
// &props == g
// } else {
// false
// }
// };
let comparator: Option<&dyn Fn(&VComponent) -> bool> = {
if P::CAN_BE_MEMOIZED {
Some(bump.alloc(move |other: &VComponent| {
// Safety:
// We are guaranteed that the props will be of the same type because
// there is no way to create a VComponent other than this `new` method.
//
// Therefore, if the render functions are identical (by address), then so will be
// props type paramter (because it is the same render function). Therefore, we can be
// sure
if caller_ref == other.user_fc {
// let g = other.raw_ctx.downcast_ref::<P>().unwrap();
let real_other = unsafe { &*(other.raw_props as *const _ as *const P) };
&props == &real_other
} else {
false
}
}))
} else {
None
}
};
// let prref: &'a P = props.as_ref();
@@ -313,16 +305,18 @@ impl<'a> VComponent<'a> {
None => NodeKey(None),
};
// raw_props: Box::new(props),
// comparator: Rc::new(props_comparator),
Self {
key,
ass_scope: Rc::new(RefCell::new(None)),
ass_scope: RefCell::new(None),
user_fc: caller_ref,
// raw_props: Box::new(props),
comparator,
raw_props,
_p: PhantomData,
children: &[],
caller,
// comparator: Rc::new(props_comparator),
stable_addr: Rc::new(RefCell::new(None)),
stable_addr: RefCell::new(None),
}
}
}