/* The Dioxus Virtual Dom integrates an event system and virtual nodes to create reactive user interfaces. The Dioxus VDom uses the same underlying mechanics as Dodrio (double buffering, bump dom, etc). Instead of making the allocator very obvious, we choose to parametrize over the DomTree trait. For our purposes, the DomTree trait is simply an abstraction over a lazy dom builder, much like the iterator trait. This means we can accept DomTree anywhere as well as return it. All components therefore look like this: ```ignore function Component(ctx: Context<()>) -> VNode { ctx.view(html! {
{ /// Start a new VirtualDom instance with a dependent props. /// Later, the props can be updated by calling "update" with a new set of props, causing a set of re-renders. /// /// This is useful when a component tree can be driven by external state (IE SSR) but it would be too expensive /// to toss out the entire tree. pub fn new_with_props(root: FC
, root_props: P) -> Self {
// 1. Create the component arena
// 2. Create the base scope (can never be removed)
// 3. Create the lifecycle queue
// 4. Create the event queue
// Arena allocate all the components
// This should make it *really* easy to store references in events and such
let mut components = Arena::new();
// Create a reference to the component in the arena
let base_scope = components.insert(Scope::new(root));
// Create a new mount event with no root container
let first_event = LifecycleEvent::mount(base_scope, None, 0);
// Create an event queue with a mount for the base scope
let event_queue = vec![first_event];
Self {
components,
base_scope,
event_queue,
root_props,
}
}
/// Pop an event off the even queue and process it
pub fn progress(&mut self) -> Result<(), ()> {
let LifecycleEvent { index, event_type } = self.event_queue.pop().ok_or(())?;
let scope = self.components.get(index).ok_or(())?;
match event_type {
// Component needs to be mounted to the virtual dom
LifecycleType::Mount { to, under } => {
// todo! run the FC with the bump allocator
// Run it with its properties
if let Some(other) = to {
// mount to another component
let p = ();
} else {
// mount to the root
}
}
// The parent for this component generated new props and the component needs update
LifecycleType::PropsChanged {} => {}
// Component was successfully mounted to the dom
LifecycleType::Mounted {} => {}
// Component was removed from the DOM
// Run any destructors and cleanup for the hooks and the dump the component
LifecycleType::Removed {} => {
let f = self.components.remove(index);
}
// Component was messaged via the internal subscription service
LifecycleType::Messaged => {}
}
Ok(())
}
/// Update the root props, causing a full event cycle
pub fn update_props(&mut self, new_props: P) {}
/// Run through every event in the event queue until the events are empty.
/// Function is asynchronous to allow for async components to finish their work.
pub async fn progess_completely() {}
/// Create a new context object for a given component and scope
fn new_context