From fb4f97406c5ecd68d32c13263affe518052645de Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Tue, 16 Jan 2024 15:48:37 -0800 Subject: [PATCH] Fix router codegen --- packages/core/src/nodes.rs | 9 +++++---- packages/core/src/properties.rs | 17 +++++++++-------- packages/router-macro/src/lib.rs | 19 ++++++++++--------- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/packages/core/src/nodes.rs b/packages/core/src/nodes.rs index 40d9c1b7a..cbe0011b3 100644 --- a/packages/core/src/nodes.rs +++ b/packages/core/src/nodes.rs @@ -9,6 +9,7 @@ use crate::{ }; use crate::{Properties, VirtualDom}; use core::panic; +use std::ops::Deref; use std::rc::Rc; use std::vec; use std::{ @@ -16,7 +17,6 @@ use std::{ cell::Cell, fmt::{Arguments, Debug}, }; -use std::{ffi::c_void, ops::Deref}; pub type TemplateId = &'static str; @@ -513,7 +513,7 @@ pub struct VComponent { /// The function pointer of the component, known at compile time /// /// It is possible that components get folded at compile time, so these shouldn't be really used as a key - pub(crate) render_fn: *const c_void, + pub(crate) render_fn: TypeId, pub(crate) props: BoxedAnyProps, } @@ -542,8 +542,9 @@ impl VComponent { // The properties must be valid until the next bump frame P: Properties + 'static, { - let component = Rc::new(component).as_component(); - let render_fn = component.as_ref() as *const _ as *const c_void; + let component = Rc::new(component); + let render_fn = component.id(); + let component = component.as_component(); let vcomp = VProps::new(component,

::memoize, props, fn_name); VComponent { diff --git a/packages/core/src/properties.rs b/packages/core/src/properties.rs index e0ad12f7b..4cb66e10e 100644 --- a/packages/core/src/properties.rs +++ b/packages/core/src/properties.rs @@ -1,4 +1,4 @@ -use std::rc::Rc; +use std::{any::TypeId, rc::Rc}; use crate::innerlude::*; @@ -62,23 +62,25 @@ where } /// Any component that implements the `ComponentFn` trait can be used as a component. -pub trait ComponentFunction { - type Props; +pub trait ComponentFunction: 'static { + /// Get the type id of the component. + fn id(&self) -> TypeId { + TypeId::of::() + } + /// Convert the component to a function that takes props and returns an element. fn as_component(self: Rc) -> Component; } /// Accept pre-formed component render functions as components -impl

ComponentFunction for Component

{ - type Props = P; +impl ComponentFunction

for Component

{ fn as_component(self: Rc) -> Component

{ self.as_ref().clone() } } /// Accept any callbacks that take props -impl Element + 'static, P> ComponentFunction for F { - type Props = P; +impl Element + 'static, P> ComponentFunction

for F { fn as_component(self: Rc) -> Component

{ self } @@ -87,7 +89,6 @@ impl Element + 'static, P> ComponentFunction for F { /// Accept any callbacks that take no props pub struct EmptyMarker; impl Element + 'static> ComponentFunction<(), EmptyMarker> for F { - type Props = (); fn as_component(self: Rc) -> Rc Element> { Rc::new(move |_| self()) } diff --git a/packages/router-macro/src/lib.rs b/packages/router-macro/src/lib.rs index 55ac4184b..65602edf5 100644 --- a/packages/router-macro/src/lib.rs +++ b/packages/router-macro/src/lib.rs @@ -605,18 +605,19 @@ impl RouteEnum { fn component_impl(&self) -> TokenStream2 { let name = &self.name; + let props = quote! { ::std::rc::Rc<::std::cell::Cell<::dioxus_router::prelude::RouterConfig<#name>>> }; quote! { - impl dioxus_core::ComponentFunction<#name> for #name { - type Props = ::std::rc::Rc<::std::cell::Cell<::dioxus_router::prelude::RouterConfig<#name>>>; - - fn call(&self, props: Self::Props) -> dioxus_core::Element { - let initial_route = self.clone(); - rsx! { - ::dioxus_router::prelude::Router::<#name> { - config: move || props.take().initial_route(initial_route) + impl dioxus_core::ComponentFunction<#props> for #name { + fn as_component(self: ::std::rc::Rc) -> Component<#props> { + ::std::rc::Rc::new(move |props| { + let initial_route = self.as_ref().clone(); + rsx! { + ::dioxus_router::prelude::Router::<#name> { + config: move || props.take().initial_route(initial_route) + } } - } + }) } } }