feat: props memoization is more powerful
This commit solves the memoization , properly memoizing properties that don't have any generic parameters. This is a rough heuristic to prevent non-static lifetimes from creeping into props and breaking our minual lifetime management. Props that have a generic parameter are opted-out of the `partialeq` requirement and props *without* lifetimes must implement partialeq. We're going to leave manual disabling of memoization for future work.
This commit is contained in:
1 parent
7102fe5f98
commit
73047fe956
37 files changed
+877
-977
No files matched your search
@@ -7,21 +7,27 @@
|
||||
|
||||
use crate::innerlude::FC;
|
||||
|
||||
pub unsafe trait Properties: PartialEq + Sized {
|
||||
pub trait Properties: Sized {
|
||||
type Builder;
|
||||
const CAN_BE_MEMOIZED: bool;
|
||||
fn builder() -> Self::Builder;
|
||||
|
||||
/// Memoization can only happen if the props are 'static
|
||||
/// The user must know if their props are static, but if they make a mistake, UB happens
|
||||
/// Therefore it's unsafe to memeoize.
|
||||
unsafe fn memoize(&self, other: &Self) -> bool;
|
||||
}
|
||||
|
||||
unsafe impl Properties for () {
|
||||
const CAN_BE_MEMOIZED: bool = true;
|
||||
impl Properties for () {
|
||||
type Builder = EmptyBuilder;
|
||||
|
||||
fn builder() -> Self::Builder {
|
||||
EmptyBuilder {}
|
||||
}
|
||||
unsafe fn memoize(&self, _other: &Self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
// We allow components to use the () generic parameter if they have no props. This impl enables the "build" method
|
||||
// that the macros use to anonymously complete prop construction.
|
||||
pub struct EmptyBuilder;
|
||||
impl EmptyBuilder {
|
||||
#[inline]
|
||||
@@ -30,6 +36,8 @@ impl EmptyBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
/// This utility function launches the builder method so rsx! and html! macros can use the typed-builder pattern
|
||||
/// to initialize a component's props.
|
||||
pub fn fc_to_builder<T: Properties>(_: FC<T>) -> T::Builder {
|
||||
T::builder()
|
||||
}
|
||||
@@ -39,9 +47,10 @@ pub fn fc_to_builder<T: Properties>(_: FC<T>) -> T::Builder {
|
||||
///
|
||||
/// Fragments capture a series of children without rendering extra nodes.
|
||||
///
|
||||
///
|
||||
///
|
||||
pub static Fragment: FC<()> = |ctx| {
|
||||
/// Fragments are incredibly useful when necessary, but *do* add cost in the diffing phase.
|
||||
/// Try to avoid nesting fragments if you can. Infinitely nested Fragments *will* cause diffing to crash.
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub const Fragment: FC<()> = |ctx| {
|
||||
use crate::prelude::*;
|
||||
ctx.render(LazyNodes::new(move |c| {
|
||||
crate::nodebuilder::vfragment(c, None, ctx.children())
|
||||
|
||||
Reference in new issue
Block a user