diff --git a/packages/core/examples/nested.rs b/packages/core/examples/nested.rs index 4a0f1d5a5..440864e69 100644 --- a/packages/core/examples/nested.rs +++ b/packages/core/examples/nested.rs @@ -17,7 +17,7 @@ static Header: FC<()> = |ctx, props| { .child(VNode::Component(VComponent::new( Bottom, // - (), + &mut (), ))) .finish() }) diff --git a/packages/core/src/component.rs b/packages/core/src/component.rs index f1771719e..e1e9b4008 100644 --- a/packages/core/src/component.rs +++ b/packages/core/src/component.rs @@ -7,13 +7,64 @@ use crate::innerlude::FC; +use self::sized_any::SizedAny; + pub type ScopeIdx = generational_arena::Index; +struct ComparableComp<'s> { + fc_raw: *const (), + f: &'s dyn SizedAny, +} + +impl<'s> ComparableComp<'s> { + fn compare_to(&self, other: &ComparableComp) -> bool { + if self.fc_raw == other.fc_raw { + let real_other = unsafe { &*(other.f as *const _ as *const P) }; + true + } else { + false + } + } +} + +struct TestProps {} + +fn test() {} + +mod sized_any { + use std::any::TypeId; + + // don't allow other implementations of `SizedAny`; `SizedAny` must only be + // implemented for sized types. + mod seal { + // it must be a `pub trait`, but not be reachable - hide it in + // private mod. + pub trait Seal {} + } + + pub trait SizedAny: seal::Seal {} + + impl seal::Seal for T {} + impl SizedAny for T {} + + // `SizedAny + ?Sized` means it can be a trait object, but `SizedAny` was + // implemented for the underlying sized type. + pub fn downcast_ref(v: &From) -> Option<&To> + where + From: SizedAny + ?Sized + 'static, + To: 'static, + { + // if TypeId::of::() == < From as SizedAny>::get_type_id(v) { + Some(unsafe { &*(v as *const From as *const To) }) + // } else { + // None + // } + } +} + pub trait Properties: PartialEq { type Builder; - type StaticOutput: Properties + 'static; fn builder() -> Self::Builder; - unsafe fn into_static(self) -> Self::StaticOutput; } pub struct EmptyBuilder; @@ -25,15 +76,10 @@ impl EmptyBuilder { impl Properties for () { type Builder = EmptyBuilder; - type StaticOutput = (); fn builder() -> Self::Builder { EmptyBuilder {} } - - unsafe fn into_static(self) -> Self::StaticOutput { - std::mem::transmute(self) - } } pub fn fc_to_builder(_f: FC) -> T::Builder { diff --git a/packages/core/src/context.rs b/packages/core/src/context.rs index 49889d576..958aac53e 100644 --- a/packages/core/src/context.rs +++ b/packages/core/src/context.rs @@ -76,9 +76,9 @@ impl<'a> Context<'a> { #[derive(Debug, Clone)] pub struct NodeCtx<'a> { pub bump: &'a Bump, + pub listeners: &'a RefCell>, pub idx: RefCell, pub scope: ScopeIdx, - pub listeners: &'a RefCell>, } impl<'a> Context<'a> { diff --git a/packages/core/src/nodebuilder.rs b/packages/core/src/nodebuilder.rs index cb5613d51..16c40b856 100644 --- a/packages/core/src/nodebuilder.rs +++ b/packages/core/src/nodebuilder.rs @@ -1,6 +1,6 @@ //! Helpers for building virtual DOM VNodes. -use std::{borrow::BorrowMut, intrinsics::transmute}; +use std::{any::Any, borrow::BorrowMut, intrinsics::transmute, u128}; use crate::{ context::NodeCtx, @@ -521,12 +521,30 @@ pub fn attr<'a>(name: &'static str, value: &'a str) -> Attribute<'a> { // } // } -// _f: crate::innerlude::FC, -// _props: T pub fn virtual_child<'a, T: Properties>(ctx: &NodeCtx<'a>, f: FC, p: T) -> VNode<'a> { - // alloc props into the bump; - - // erase the lifetime - let p_static = unsafe { p.into_static() }; - VNode::Component(crate::nodes::VComponent::new(f, p_static)) + VNode::Component(crate::nodes::VComponent::new(f, ctx.bump.alloc(p))) } + +trait Bany { + // fn compare_to(other: &P) -> bool; +} + +pub fn test_vchild(p: &T) { + // let r = p as *const dyn Bany; + // let r = p as *const dyn Bany; + + // std::any::Any + // let r = p as &dyn Any; + // let g = p as *const u128; + // let l = unsafe { std::mem::transmute::<&T, &dyn Any>(p) }; +} + +/* + +Problem: +compare two props that we know are the same type without transmute + + + + +*/ diff --git a/packages/core/src/nodes.rs b/packages/core/src/nodes.rs index b9f5c8b23..5490e3974 100644 --- a/packages/core/src/nodes.rs +++ b/packages/core/src/nodes.rs @@ -269,8 +269,8 @@ pub type StableScopeAddres = Rc>>; #[derive(Debug, Clone)] pub struct VComponent<'src> { pub stable_addr: StableScopeAddres, - pub raw_props: Rc, - pub comparator: Comparator, + pub raw_props: Rc<*mut dyn Any>, + // pub comparator: Comparator, pub caller: Caller, pub caller_ref: *const (), _p: PhantomData<&'src ()>, @@ -278,8 +278,8 @@ pub struct VComponent<'src> { pub trait PropsComparator {} #[derive(Clone)] -pub struct Comparator(pub Rc bool>); -// pub struct Comparator(pub Rc bool>); +// pub struct Comparator(pub Rc bool>); +pub struct Comparator(pub Rc bool>); impl std::fmt::Debug for Comparator { fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { Ok(()) @@ -300,29 +300,24 @@ impl<'a> VComponent<'a> { // - perform comparisons when diffing (memoization) // 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(caller: FC, props: P) -> Self { + pub fn new(caller: FC

, props: &mut P) -> Self { let caller_ref = caller as *const (); let props = Rc::new(props); // used for memoization let p1 = props.clone(); - let props_comparator = move |new_props: ()| -> bool { - false - // let props_comparator = move |new_props: &dyn Any| -> bool { - // new_props - // .downcast_ref::

() - // .map(|new_p| p1.as_ref() == new_p) - // .unwrap_or_else(|| { - // log::debug!("downcasting failed, this receovered but SHOULD NOT FAIL"); - // false - // }) - }; + + // let props_comparator = move |new_props| -> bool { + // false + // let p = new_props.downcast_ref::().expect(""); + // let r = unsafe { std::mem::transmute::<_, &P>(p) }; + // &r == p1.as_ref() + // }; // used for actually rendering the custom component let p2 = props.clone(); let caller = move |ctx: Context| -> DomTree { - // // cast back into the right lifetime caller(ctx, p2.as_ref()) }; diff --git a/packages/web/examples/weather.rs b/packages/web/examples/weather.rs index 2ebc0e86f..66d89a56e 100644 --- a/packages/web/examples/weather.rs +++ b/packages/web/examples/weather.rs @@ -45,3 +45,4 @@ fn main() { }) })); } +