diff --git a/packages/core/.vscode/settings.json b/packages/core/.vscode/settings.json index 80f51cff8..2f418701b 100644 --- a/packages/core/.vscode/settings.json +++ b/packages/core/.vscode/settings.json @@ -1,3 +1,3 @@ { - "rust-analyzer.inlayHints.enable": false + "rust-analyzer.inlayHints.enable": true } \ No newline at end of file diff --git a/packages/core/src/scope.rs b/packages/core/src/scope.rs index 4948391c1..31f38416e 100644 --- a/packages/core/src/scope.rs +++ b/packages/core/src/scope.rs @@ -1,23 +1,13 @@ -use crate::innerlude::*; +use crate::{innerlude::*, virtual_dom::OpaqueComponent}; use bumpalo::Bump; use std::{ - any::Any, cell::RefCell, collections::HashSet, marker::PhantomData, - ops::Deref, rc::{Rc, Weak}, }; -// pub trait Scoped { -// fn run(&mut self); -// // fn compare_props(&self, new: &dyn std::any::Any) -> bool; -// fn call_listener(&mut self, trigger: EventTrigger); -// fn new_frame<'bump>(&'bump self) -> &'bump VNode<'bump>; -// fn old_frame<'bump>(&'bump self) -> &'bump VNode<'bump>; -// } - /// Every component in Dioxus is represented by a `Scope`. /// /// Scopes contain the state for hooks, the component's props, and other lifecycle information. @@ -25,7 +15,6 @@ use std::{ /// Scopes are allocated in a generational arena. As components are mounted/unmounted, they will replace slots of dead components. /// The actual contents of the hooks, though, will be allocated with the standard allocator. These should not allocate as frequently. pub struct Scope { - // pub struct Scope { // Map to the parent pub parent: Option, @@ -35,16 +24,7 @@ pub struct Scope { // pub children: HashSet, - pub caller: Weak DomTree + 'static>, - - // // the props - // pub props: P, - - // and the actual render function - // pub caller: *const dyn Fn(Context) -> DomTree, - // _p: std::marker::PhantomData

, - // _p: std::marker::PhantomData

, - // pub raw_caller: FC

, + pub caller: Weak>, // ========================== // slightly unsafe stuff @@ -57,6 +37,7 @@ pub struct Scope { // or we could dedicate a tiny bump arena just for them // could also use ourborous pub hooks: RefCell>, + pub hook_arena: typed_arena::Arena, // Unsafety: @@ -66,49 +47,20 @@ pub struct Scope { listeners: RefCell>, } -// instead of having it as a trait method, we use a single function -// todo: do the unsafety magic stuff to erase the type of p -// pub fn create_scoped( -// // raw_f: FC

, -// // caller: Caller, - -// // props: P, -// myidx: ScopeIdx, -// parent: Option, -// ) -> Box { -// Box::new(Scope::<()> { -// // raw_caller: raw_f, -// _p: Default::default(), -// // caller, -// myidx, -// hook_arena: typed_arena::Arena::new(), -// hooks: RefCell::new(Vec::new()), -// frames: ActiveFrame::new(), -// children: HashSet::new(), -// listeners: Default::default(), -// parent, -// // props, -// }) -// } - impl Scope { // we are being created in the scope of an existing component (where the creator_node lifetime comes into play) // we are going to break this lifetime by force in order to save it on ourselves. // To make sure that the lifetime isn't truly broken, we receive a Weak RC so we can't keep it around after the parent dies. // This should never happen, but is a good check to keep around pub fn new<'creator_node>( - // pub fn new( - // caller: Weak DomTree + 'static>, - caller: Weak DomTree + 'creator_node>, + caller: Weak>, myidx: ScopeIdx, parent: Option, ) -> Self { - // caller has been broken free - // however, it's still weak, so if the original Rc gets killed, we can't touch it - let broken_caller: Weak DomTree + 'static> = - unsafe { std::mem::transmute(caller) }; + // Caller has been broken free + // However, it's still weak, so if the original Rc gets killed, we can't touch it + let broken_caller: Weak> = unsafe { std::mem::transmute(caller) }; - // let broken_caller = caller; Self { caller: broken_caller, hook_arena: typed_arena::Arena::new(), @@ -121,7 +73,6 @@ impl Scope { } } - // impl Scoped for Scope

{ /// Create a new context and run the component with references from the Virtual Dom /// This function downcasts the function pointer based on the stored props_type /// @@ -170,12 +121,6 @@ impl Scope { // .expect("Viewing did not happen"); } - // pub fn compare_props(&self, new: &dyn Any) -> bool { - // new.downcast_ref::

() - // .map(|f| &self.props == f) - // .expect("Props should not be of a different type") - // } - // A safe wrapper around calling listeners // calling listeners will invalidate the list of listeners // The listener list will be completely drained because the next frame will write over previous listeners diff --git a/packages/core/src/virtual_dom.rs b/packages/core/src/virtual_dom.rs index 0cc94c68e..e7154ce68 100644 --- a/packages/core/src/virtual_dom.rs +++ b/packages/core/src/virtual_dom.rs @@ -76,19 +76,22 @@ impl VirtualDom { // Diff from the top let mut diff_machine = DiffMachine::new(); // partial borrow - self.components + let mut component = self + .components .get_mut(self.base_scope) - .ok_or_else(|| Error::FatalInternal("Acquring base component should never fail"))? - .run_scope()?; + .ok_or_else(|| Error::FatalInternal("Acquring base component should never fail"))?; + + component.run_scope()?; + let component = &*component; // // get raw pointer to the arena // let very_unsafe_components = &mut self.components as *mut generational_arena::Arena; // { - // let component = self - // .components - // .get(self.base_scope) - // .expect("failed to acquire base scope"); + // let component = self + // .components + // .get(self.base_scope) + // .ok_or_else(|| Error::FatalInternal("Acquring base component should never fail"))? // diff_machine.diff_node(component.old_frame(), component.new_frame()); // } diff --git a/packages/web/.vscode/settings.json b/packages/web/.vscode/settings.json new file mode 100644 index 000000000..80f51cff8 --- /dev/null +++ b/packages/web/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "rust-analyzer.inlayHints.enable": false +} \ No newline at end of file diff --git a/packages/web/examples/infer.rs b/packages/web/examples/infer.rs index 0bc4f1541..00f3e72cc 100644 --- a/packages/web/examples/infer.rs +++ b/packages/web/examples/infer.rs @@ -57,10 +57,3 @@ static Example2: FC = |ctx, props| { }) }; - -impl Properties for ExampleProps { - type Builder = ExamplePropsBuilder<((),)>; - fn builder() -> Self::Builder { - ExampleProps::builder() - } -} diff --git a/packages/web/examples/rsxt.rs b/packages/web/examples/rsxt.rs index 152aa7cea..83bfc4606 100644 --- a/packages/web/examples/rsxt.rs +++ b/packages/web/examples/rsxt.rs @@ -6,11 +6,16 @@ use dioxus_web::WebsysRenderer; fn main() { wasm_logger::init(wasm_logger::Config::new(log::Level::Trace)); console_error_panic_hook::set_once(); - wasm_bindgen_futures::spawn_local(WebsysRenderer::start(Example)) + wasm_bindgen_futures::spawn_local(async {WebsysRenderer::new_with_props(Example, ExampleProps { initial_name: "..?"}).run().await.unwrap()} ); } -static Example: FC<()> = |ctx, _props| { - let (name, set_name) = use_state(&ctx, || "...?"); +#[derive(PartialEq, Props)] +struct ExampleProps { + initial_name: &'static str +} + +static Example: FC = |ctx, props| { + let (name, set_name) = use_state(&ctx, move || props.initial_name); ctx.render(rsx! { div { @@ -35,9 +40,24 @@ static Example: FC<()> = |ctx, _props| { } button { class: "inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow" - onmouseover: move |e| set_name("....") + onmouseover: move |_| set_name(props.initial_name) "Reset!" } + Child { + initial_name: "bill" + } + Child { + initial_name: "bob" + } } }) }; + +static Child: FC = |ctx, props| { + ctx.render(rsx!{ + div { + "Child name: {props.initial_name}" + } + }) +}; +