feat: wire up resource pool
This commit is contained in:
1 parent
927b05f358
commit
31702dbf87
6 files changed
+73
-81
No files matched your search
@@ -74,7 +74,8 @@ impl<'a> Iterator for RealChildIterator<'a> {
|
|||||||
// For components, we load their root and push them onto the stack
|
// For components, we load their root and push them onto the stack
|
||||||
VNode::Component(sc) => {
|
VNode::Component(sc) => {
|
||||||
let scope =
|
let scope =
|
||||||
unsafe { self.scopes.get_scope(sc.ass_scope.get().unwrap()) }.unwrap();
|
unsafe { self.scopes.get_scope(sc.associated_scope.get().unwrap()) }
|
||||||
|
.unwrap();
|
||||||
// let scope = self.scopes.get(sc.ass_scope.get().unwrap()).unwrap();
|
// let scope = self.scopes.get(sc.ass_scope.get().unwrap()).unwrap();
|
||||||
|
|
||||||
// Simply swap the current node on the stack with the root of the component
|
// Simply swap the current node on the stack with the root of the component
|
||||||
|
|||||||
@@ -341,7 +341,7 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Actually initialize the caller's slot with the right address
|
// Actually initialize the caller's slot with the right address
|
||||||
vcomponent.ass_scope.set(Some(new_idx));
|
vcomponent.associated_scope.set(Some(new_idx));
|
||||||
|
|
||||||
if !vcomponent.can_memoize {
|
if !vcomponent.can_memoize {
|
||||||
let cur_scope = self.vdom.get_scope_mut(parent_idx).unwrap();
|
let cur_scope = self.vdom.get_scope_mut(parent_idx).unwrap();
|
||||||
@@ -357,7 +357,7 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
let new_component = self.vdom.get_scope_mut(new_idx).unwrap();
|
let new_component = self.vdom.get_scope_mut(new_idx).unwrap();
|
||||||
|
|
||||||
// Run the scope for one iteration to initialize it
|
// Run the scope for one iteration to initialize it
|
||||||
if new_component.run_scope() {
|
if new_component.run_scope(self.vdom) {
|
||||||
// Take the node that was just generated from running the component
|
// Take the node that was just generated from running the component
|
||||||
let nextnode = new_component.frames.fin_head();
|
let nextnode = new_component.frames.fin_head();
|
||||||
self.stack.create_component(new_idx, nextnode);
|
self.stack.create_component(new_idx, nextnode);
|
||||||
@@ -505,7 +505,7 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
old: &'bump VComponent<'bump>,
|
old: &'bump VComponent<'bump>,
|
||||||
new: &'bump VComponent<'bump>,
|
new: &'bump VComponent<'bump>,
|
||||||
) {
|
) {
|
||||||
let scope_addr = old.ass_scope.get().unwrap();
|
let scope_addr = old.associated_scope.get().unwrap();
|
||||||
|
|
||||||
// Make sure we're dealing with the same component (by function pointer)
|
// Make sure we're dealing with the same component (by function pointer)
|
||||||
if old.user_fc == new.user_fc {
|
if old.user_fc == new.user_fc {
|
||||||
@@ -513,7 +513,7 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
self.stack.scope_stack.push(scope_addr);
|
self.stack.scope_stack.push(scope_addr);
|
||||||
|
|
||||||
// Make sure the new component vnode is referencing the right scope id
|
// Make sure the new component vnode is referencing the right scope id
|
||||||
new.ass_scope.set(Some(scope_addr));
|
new.associated_scope.set(Some(scope_addr));
|
||||||
|
|
||||||
// make sure the component's caller function is up to date
|
// make sure the component's caller function is up to date
|
||||||
let scope = self.vdom.get_scope_mut(scope_addr).unwrap();
|
let scope = self.vdom.get_scope_mut(scope_addr).unwrap();
|
||||||
@@ -529,7 +529,7 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
}
|
}
|
||||||
false => {
|
false => {
|
||||||
// the props are different...
|
// the props are different...
|
||||||
if scope.run_scope() {
|
if scope.run_scope(self.vdom) {
|
||||||
self.diff_node(scope.frames.wip_head(), scope.frames.fin_head());
|
self.diff_node(scope.frames.wip_head(), scope.frames.fin_head());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -967,7 +967,7 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
search_node = frag.children.last();
|
search_node = frag.children.last();
|
||||||
}
|
}
|
||||||
VNode::Component(el) => {
|
VNode::Component(el) => {
|
||||||
let scope_id = el.ass_scope.get().unwrap();
|
let scope_id = el.associated_scope.get().unwrap();
|
||||||
let scope = self.vdom.get_scope(scope_id).unwrap();
|
let scope = self.vdom.get_scope(scope_id).unwrap();
|
||||||
search_node = Some(scope.root());
|
search_node = Some(scope.root());
|
||||||
}
|
}
|
||||||
@@ -985,7 +985,7 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
search_node = Some(&frag.children[0]);
|
search_node = Some(&frag.children[0]);
|
||||||
}
|
}
|
||||||
VNode::Component(el) => {
|
VNode::Component(el) => {
|
||||||
let scope_id = el.ass_scope.get().unwrap();
|
let scope_id = el.associated_scope.get().unwrap();
|
||||||
let scope = self.vdom.get_scope(scope_id).unwrap();
|
let scope = self.vdom.get_scope(scope_id).unwrap();
|
||||||
search_node = Some(scope.root());
|
search_node = Some(scope.root());
|
||||||
}
|
}
|
||||||
@@ -1043,7 +1043,7 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
VNode::Component(c) => {
|
VNode::Component(c) => {
|
||||||
let scope_id = c.ass_scope.get().unwrap();
|
let scope_id = c.associated_scope.get().unwrap();
|
||||||
let scope = self.vdom.get_scope(scope_id).unwrap();
|
let scope = self.vdom.get_scope(scope_id).unwrap();
|
||||||
let root = scope.root();
|
let root = scope.root();
|
||||||
self.remove_nodes(Some(root));
|
self.remove_nodes(Some(root));
|
||||||
|
|||||||
+32
-41
@@ -13,7 +13,6 @@ use std::{
|
|||||||
cell::{Cell, RefCell},
|
cell::{Cell, RefCell},
|
||||||
fmt::{Arguments, Debug, Formatter},
|
fmt::{Arguments, Debug, Formatter},
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
mem::ManuallyDrop,
|
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -43,8 +42,8 @@ impl<'src> VNode<'src> {
|
|||||||
VNode::Component(c) => c.key,
|
VNode::Component(c) => c.key,
|
||||||
VNode::Fragment(f) => f.key,
|
VNode::Fragment(f) => f.key,
|
||||||
VNode::Text(_t) => None,
|
VNode::Text(_t) => None,
|
||||||
VNode::Suspended(s) => None,
|
VNode::Suspended(_s) => None,
|
||||||
VNode::Anchor(f) => None,
|
VNode::Anchor(_f) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn direct_id(&self) -> ElementId {
|
pub fn direct_id(&self) -> ElementId {
|
||||||
@@ -68,16 +67,36 @@ pub struct VAnchor {
|
|||||||
|
|
||||||
pub struct VText<'src> {
|
pub struct VText<'src> {
|
||||||
pub text: &'src str,
|
pub text: &'src str,
|
||||||
|
|
||||||
pub dom_id: Cell<Option<ElementId>>,
|
pub dom_id: Cell<Option<ElementId>>,
|
||||||
|
|
||||||
pub is_static: bool,
|
pub is_static: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct VFragment<'src> {
|
pub struct VFragment<'src> {
|
||||||
pub children: &'src [VNode<'src>],
|
|
||||||
pub key: Option<&'src str>,
|
pub key: Option<&'src str>,
|
||||||
|
|
||||||
|
pub children: &'src [VNode<'src>],
|
||||||
|
|
||||||
pub is_static: bool,
|
pub is_static: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct VElement<'a> {
|
||||||
|
pub tag_name: &'static str,
|
||||||
|
|
||||||
|
pub namespace: Option<&'static str>,
|
||||||
|
|
||||||
|
pub key: Option<&'a str>,
|
||||||
|
|
||||||
|
pub dom_id: Cell<Option<ElementId>>,
|
||||||
|
|
||||||
|
pub listeners: &'a [Listener<'a>],
|
||||||
|
|
||||||
|
pub attributes: &'a [Attribute<'a>],
|
||||||
|
|
||||||
|
pub children: &'a [VNode<'a>],
|
||||||
|
}
|
||||||
|
|
||||||
pub trait DioxusElement {
|
pub trait DioxusElement {
|
||||||
const TAG_NAME: &'static str;
|
const TAG_NAME: &'static str;
|
||||||
const NAME_SPACE: Option<&'static str>;
|
const NAME_SPACE: Option<&'static str>;
|
||||||
@@ -91,19 +110,6 @@ pub trait DioxusElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct VElement<'a> {
|
|
||||||
pub key: Option<&'a str>,
|
|
||||||
|
|
||||||
// tag is always static
|
|
||||||
pub tag_name: &'static str,
|
|
||||||
pub namespace: Option<&'static str>,
|
|
||||||
pub dom_id: Cell<Option<ElementId>>,
|
|
||||||
|
|
||||||
pub listeners: &'a [Listener<'a>],
|
|
||||||
pub attributes: &'a [Attribute<'a>],
|
|
||||||
pub children: &'a [VNode<'a>],
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An attribute on a DOM node, such as `id="my-thing"` or
|
/// An attribute on a DOM node, such as `id="my-thing"` or
|
||||||
/// `href="https://example.com"`.
|
/// `href="https://example.com"`.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@@ -131,22 +137,12 @@ pub struct Listener<'bump> {
|
|||||||
pub(crate) callback: RefCell<Option<BumpBox<'bump, dyn FnMut(SyntheticEvent) + 'bump>>>,
|
pub(crate) callback: RefCell<Option<BumpBox<'bump, dyn FnMut(SyntheticEvent) + 'bump>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Listener<'_> {
|
|
||||||
// serialize the listener event stuff to a string
|
|
||||||
pub fn serialize(&self) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
pub fn deserialize() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Virtual Components for custom user-defined components
|
/// Virtual Components for custom user-defined components
|
||||||
/// Only supports the functional syntax
|
/// Only supports the functional syntax
|
||||||
pub struct VComponent<'src> {
|
pub struct VComponent<'src> {
|
||||||
pub key: Option<&'src str>,
|
pub key: Option<&'src str>,
|
||||||
|
|
||||||
pub ass_scope: Cell<Option<ScopeId>>,
|
pub associated_scope: Cell<Option<ScopeId>>,
|
||||||
|
|
||||||
pub(crate) caller: Rc<dyn Fn(&Scope) -> DomTree>,
|
pub(crate) caller: Rc<dyn Fn(&Scope) -> DomTree>,
|
||||||
|
|
||||||
@@ -158,21 +154,19 @@ pub struct VComponent<'src> {
|
|||||||
|
|
||||||
pub is_static: bool,
|
pub is_static: bool,
|
||||||
|
|
||||||
pub can_memoize: bool,
|
pub(crate) can_memoize: bool,
|
||||||
|
|
||||||
pub name: &'static str,
|
// Raw pointer into the bump arena for the props of the component
|
||||||
|
|
||||||
// a pointer into the bump arena (given by the 'src lifetime)
|
|
||||||
pub(crate) raw_props: *const (),
|
pub(crate) raw_props: *const (),
|
||||||
|
|
||||||
// a pointer to the raw fn typ
|
// Function pointer to the FC that was used to generate this component
|
||||||
pub(crate) user_fc: *const (),
|
pub(crate) user_fc: *const (),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct VSuspended<'a> {
|
pub struct VSuspended<'a> {
|
||||||
pub dom_id: Cell<Option<ElementId>>,
|
|
||||||
pub task_id: u64,
|
pub task_id: u64,
|
||||||
pub callback: RefCell<Option<&'a dyn FnOnce(SuspendedContext<'a>) -> DomTree<'a>>>,
|
pub dom_id: Cell<Option<ElementId>>,
|
||||||
|
pub(crate) callback: RefCell<Option<&'a dyn FnOnce(SuspendedContext<'a>) -> DomTree<'a>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This struct provides an ergonomic API to quickly build VNodes.
|
/// This struct provides an ergonomic API to quickly build VNodes.
|
||||||
@@ -350,10 +344,8 @@ impl<'a> NodeFactory<'a> {
|
|||||||
{
|
{
|
||||||
let bump = self.bump();
|
let bump = self.bump();
|
||||||
|
|
||||||
let name = crate::util::type_name_of(component);
|
|
||||||
|
|
||||||
// We don't want the fat part of the fat pointer
|
// We don't want the fat part of the fat pointer
|
||||||
// This function does static dispatch so we don't need any VTable stuff
|
// THe "Fat" part is provided on next-render
|
||||||
let children: &'a V = bump.alloc(children);
|
let children: &'a V = bump.alloc(children);
|
||||||
let children = children.as_ref();
|
let children = children.as_ref();
|
||||||
|
|
||||||
@@ -415,9 +407,8 @@ impl<'a> NodeFactory<'a> {
|
|||||||
is_static,
|
is_static,
|
||||||
drop_props: RefCell::new(Some(drop_props)),
|
drop_props: RefCell::new(Some(drop_props)),
|
||||||
can_memoize: P::IS_STATIC,
|
can_memoize: P::IS_STATIC,
|
||||||
ass_scope: Cell::new(None),
|
associated_scope: Cell::new(None),
|
||||||
key,
|
key,
|
||||||
name,
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -663,7 +654,7 @@ impl Debug for VNode<'_> {
|
|||||||
VNode::Component(comp) => write!(
|
VNode::Component(comp) => write!(
|
||||||
s,
|
s,
|
||||||
"VComponent {{ fc: {:?}, children: {:?} }}",
|
"VComponent {{ fc: {:?}, children: {:?} }}",
|
||||||
comp.name, comp.children
|
comp.user_fc, comp.children
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-28
@@ -115,12 +115,12 @@ impl Scope {
|
|||||||
|
|
||||||
/// Returns true if the scope completed successfully
|
/// Returns true if the scope completed successfully
|
||||||
///
|
///
|
||||||
pub(crate) fn run_scope<'sel>(&'sel mut self) -> bool {
|
pub(crate) fn run_scope<'sel>(&'sel mut self, pool: &ResourcePool) -> bool {
|
||||||
// Cycle to the next frame and then reset it
|
// Cycle to the next frame and then reset it
|
||||||
// This breaks any latent references, invalidating every pointer referencing into it.
|
// This breaks any latent references, invalidating every pointer referencing into it.
|
||||||
// Remove all the outdated listeners
|
// Remove all the outdated listeners
|
||||||
|
|
||||||
self.ensure_drop_safety();
|
self.ensure_drop_safety(pool);
|
||||||
|
|
||||||
// Safety:
|
// Safety:
|
||||||
// - We dropped the listeners, so no more &mut T can be used while these are held
|
// - We dropped the listeners, so no more &mut T can be used while these are held
|
||||||
@@ -154,7 +154,7 @@ impl Scope {
|
|||||||
///
|
///
|
||||||
/// Refrences to hook data can only be stored in listeners and component props. During diffing, we make sure to log
|
/// Refrences to hook data can only be stored in listeners and component props. During diffing, we make sure to log
|
||||||
/// all listeners and borrowed props so we can clear them here.
|
/// all listeners and borrowed props so we can clear them here.
|
||||||
fn ensure_drop_safety(&mut self) {
|
fn ensure_drop_safety(&mut self, pool: &ResourcePool) {
|
||||||
// make sure all garabge is collected before trying to proceed with anything else
|
// make sure all garabge is collected before trying to proceed with anything else
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
self.pending_garbage.borrow().is_empty(),
|
self.pending_garbage.borrow().is_empty(),
|
||||||
@@ -163,33 +163,33 @@ impl Scope {
|
|||||||
|
|
||||||
// todo!("arch changes");
|
// todo!("arch changes");
|
||||||
|
|
||||||
// // make sure we drop all borrowed props manually to guarantee that their drop implementation is called before we
|
// make sure we drop all borrowed props manually to guarantee that their drop implementation is called before we
|
||||||
// // run the hooks (which hold an &mut Referrence)
|
// run the hooks (which hold an &mut Referrence)
|
||||||
// // right now, we don't drop
|
// right now, we don't drop
|
||||||
// // let vdom = &self.vdom;
|
// let vdom = &self.vdom;
|
||||||
// self.borrowed_props
|
self.borrowed_props
|
||||||
// .get_mut()
|
.get_mut()
|
||||||
// .drain(..)
|
.drain(..)
|
||||||
// .map(|li| unsafe { &*li })
|
.map(|li| unsafe { &*li })
|
||||||
// .for_each(|comp| {
|
.for_each(|comp| {
|
||||||
// // First drop the component's undropped references
|
// First drop the component's undropped references
|
||||||
// let scope_id = comp.ass_scope.get().unwrap();
|
let scope_id = comp.associated_scope.get().unwrap();
|
||||||
// let scope = unsafe { vdom.get_scope_mut(scope_id) }.unwrap();
|
let scope = pool.get_scope_mut(scope_id).unwrap();
|
||||||
// scope.ensure_drop_safety();
|
scope.ensure_drop_safety(pool);
|
||||||
|
|
||||||
// // Now, drop our own reference
|
// Now, drop our own reference
|
||||||
// let mut dropper = comp.drop_props.borrow_mut().take().unwrap();
|
let mut dropper = comp.drop_props.borrow_mut().take().unwrap();
|
||||||
// dropper();
|
dropper();
|
||||||
// });
|
});
|
||||||
|
|
||||||
// // Now that all the references are gone, we can safely drop our own references in our listeners.
|
// Now that all the references are gone, we can safely drop our own references in our listeners.
|
||||||
// self.listeners
|
self.listeners
|
||||||
// .get_mut()
|
.get_mut()
|
||||||
// .drain(..)
|
.drain(..)
|
||||||
// .map(|li| unsafe { &*li })
|
.map(|li| unsafe { &*li })
|
||||||
// .for_each(|listener| {
|
.for_each(|listener| {
|
||||||
// listener.callback.borrow_mut().take();
|
listener.callback.borrow_mut().take();
|
||||||
// });
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// A safe wrapper around calling listeners
|
// A safe wrapper around calling listeners
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ impl VirtualDom {
|
|||||||
.expect("The base scope should never be moved");
|
.expect("The base scope should never be moved");
|
||||||
|
|
||||||
// // We run the component. If it succeeds, then we can diff it and add the changes to the dom.
|
// // We run the component. If it succeeds, then we can diff it and add the changes to the dom.
|
||||||
if cur_component.run_scope() {
|
if cur_component.run_scope(&self.scheduler.pool) {
|
||||||
diff_machine
|
diff_machine
|
||||||
.stack
|
.stack
|
||||||
.create_node(cur_component.frames.fin_head(), MountType::Append);
|
.create_node(cur_component.frames.fin_head(), MountType::Append);
|
||||||
@@ -204,7 +204,7 @@ impl VirtualDom {
|
|||||||
.get_scope_mut(self.base_scope)
|
.get_scope_mut(self.base_scope)
|
||||||
.expect("The base scope should never be moved");
|
.expect("The base scope should never be moved");
|
||||||
|
|
||||||
if cur_component.run_scope() {
|
if cur_component.run_scope(&self.scheduler.pool) {
|
||||||
diff_machine.diff_scope(self.base_scope).await;
|
diff_machine.diff_scope(self.base_scope).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ impl<'a> TextRenderer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
VNode::Component(vcomp) => {
|
VNode::Component(vcomp) => {
|
||||||
let idx = vcomp.ass_scope.get().unwrap();
|
let idx = vcomp.associated_scope.get().unwrap();
|
||||||
match (self.vdom, self.cfg.skip_components) {
|
match (self.vdom, self.cfg.skip_components) {
|
||||||
(Some(vdom), false) => {
|
(Some(vdom), false) => {
|
||||||
let new_node = vdom.get_scope(idx).unwrap().root();
|
let new_node = vdom.get_scope(idx).unwrap().root();
|
||||||
|
|||||||
Reference in new issue
Block a user