|
@@ -2,13 +2,13 @@ use crate::{
|
|
any_props::AnyProps,
|
|
any_props::AnyProps,
|
|
any_props::VProps,
|
|
any_props::VProps,
|
|
bump_frame::BumpFrame,
|
|
bump_frame::BumpFrame,
|
|
- innerlude::{DynamicNode, EventHandler, VComponent, VNodeId, VText},
|
|
|
|
|
|
+ innerlude::{DynamicNode, ElementRef, EventHandler, VComponent, VNodeId, VText},
|
|
lazynodes::LazyNodes,
|
|
lazynodes::LazyNodes,
|
|
nodes::{IntoAttributeValue, IntoDynNode, RenderReturn},
|
|
nodes::{IntoAttributeValue, IntoDynNode, RenderReturn},
|
|
runtime::Runtime,
|
|
runtime::Runtime,
|
|
scope_context::ScopeContext,
|
|
scope_context::ScopeContext,
|
|
- AnyValue, Attribute, AttributeType, AttributeValue, Element, Event, MountedAttribute,
|
|
|
|
- Properties, TaskId,
|
|
|
|
|
|
+ AnyValue, Attribute, AttributeType, AttributeValue, Element, ElementId, Event,
|
|
|
|
+ MountedAttribute, Properties, TaskId, Template, VNode,
|
|
};
|
|
};
|
|
use bumpalo::{boxed::Box as BumpBox, Bump};
|
|
use bumpalo::{boxed::Box as BumpBox, Bump};
|
|
use std::{
|
|
use std::{
|
|
@@ -348,17 +348,76 @@ impl<'src> ScopeState {
|
|
/// }
|
|
/// }
|
|
/// ```
|
|
/// ```
|
|
pub fn render(&'src self, rsx: LazyNodes<'src, '_>) -> Element<'src> {
|
|
pub fn render(&'src self, rsx: LazyNodes<'src, '_>) -> Element<'src> {
|
|
- let element = rsx.call(self);
|
|
|
|
-
|
|
|
|
|
|
+ // <<<<<<< HEAD
|
|
|
|
+ // let element = rsx.call(self);
|
|
|
|
+
|
|
|
|
+ // let mut listeners = self.attributes_to_drop_before_render.borrow_mut();
|
|
|
|
+ // for attr in element.dynamic_attrs {
|
|
|
|
+ // attr.ty.for_each(|attr| {
|
|
|
|
+ // match attr.value {
|
|
|
|
+ // // We need to drop listeners before the next render because they may borrow data from the borrowed props which will be dropped
|
|
|
|
+ // AttributeValue::Listener(_) => {
|
|
|
|
+ // let unbounded = unsafe { std::mem::transmute(attr as *const Attribute) };
|
|
|
|
+ // listeners.push(unbounded);
|
|
|
|
+ // }
|
|
|
|
+ // // We need to drop any values manually to make sure that their drop implementation is called before the next render
|
|
|
|
+ // AttributeValue::Any(_) => {
|
|
|
|
+ // let unbounded = unsafe { std::mem::transmute(attr as *const Attribute) };
|
|
|
|
+ // self.previous_frame().add_attribute_to_drop(unbounded);
|
|
|
|
+ // }
|
|
|
|
+
|
|
|
|
+ // _ => (),
|
|
|
|
+ // }
|
|
|
|
+ // })
|
|
|
|
+ // }
|
|
|
|
+
|
|
|
|
+ // let mut props = self.borrowed_props.borrow_mut();
|
|
|
|
+ // let mut drop_props = self
|
|
|
|
+ // .previous_frame()
|
|
|
|
+ // .props_to_drop_before_reset
|
|
|
|
+ // .borrow_mut();
|
|
|
|
+ // for node in element.dynamic_nodes {
|
|
|
|
+ // if let DynamicNode::Component(comp) = node {
|
|
|
|
+ // let unbounded = unsafe { std::mem::transmute(comp as *const VComponent) };
|
|
|
|
+ // if !comp.static_props {
|
|
|
|
+ // props.push(unbounded);
|
|
|
|
+ // }
|
|
|
|
+ // drop_props.push(unbounded);
|
|
|
|
+ // }
|
|
|
|
+ // }
|
|
|
|
+
|
|
|
|
+ // Some(element)
|
|
|
|
+ // =======
|
|
|
|
+ // Note: We can't do anything in this function related to safety because the user could always circumvent it by creating a VNode manually and return it without calling this function
|
|
|
|
+ Some(rsx.call(self))
|
|
|
|
+ // >>>>>>> 9fe172e9 (Fix leak in render macro)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// Create a [`crate::VNode`] from the component parts
|
|
|
|
+ pub fn vnode(
|
|
|
|
+ &'src self,
|
|
|
|
+ parent: Cell<Option<ElementRef>>,
|
|
|
|
+ key: Option<&'src str>,
|
|
|
|
+ template: Cell<Template<'static>>,
|
|
|
|
+ root_ids: RefCell<bumpalo::collections::Vec<'src, ElementId>>,
|
|
|
|
+ dynamic_nodes: &'src [DynamicNode<'src>],
|
|
|
|
+ dynamic_attrs: &'src [MountedAttribute<'src>],
|
|
|
|
+ ) -> VNode<'src> {
|
|
let mut listeners = self.attributes_to_drop_before_render.borrow_mut();
|
|
let mut listeners = self.attributes_to_drop_before_render.borrow_mut();
|
|
- for attr in element.dynamic_attrs {
|
|
|
|
- attr.ty.for_each(|attr| {
|
|
|
|
|
|
+ for attr in dynamic_attrs {
|
|
|
|
+ let attrs = match attr.ty {
|
|
|
|
+ AttributeType::Single(ref attr) => std::slice::from_ref(attr),
|
|
|
|
+ AttributeType::Many(attrs) => attrs,
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ for attr in attrs {
|
|
match attr.value {
|
|
match attr.value {
|
|
// We need to drop listeners before the next render because they may borrow data from the borrowed props which will be dropped
|
|
// We need to drop listeners before the next render because they may borrow data from the borrowed props which will be dropped
|
|
AttributeValue::Listener(_) => {
|
|
AttributeValue::Listener(_) => {
|
|
let unbounded = unsafe { std::mem::transmute(attr as *const Attribute) };
|
|
let unbounded = unsafe { std::mem::transmute(attr as *const Attribute) };
|
|
listeners.push(unbounded);
|
|
listeners.push(unbounded);
|
|
}
|
|
}
|
|
|
|
+
|
|
// We need to drop any values manually to make sure that their drop implementation is called before the next render
|
|
// We need to drop any values manually to make sure that their drop implementation is called before the next render
|
|
AttributeValue::Any(_) => {
|
|
AttributeValue::Any(_) => {
|
|
let unbounded = unsafe { std::mem::transmute(attr as *const Attribute) };
|
|
let unbounded = unsafe { std::mem::transmute(attr as *const Attribute) };
|
|
@@ -367,7 +426,7 @@ impl<'src> ScopeState {
|
|
|
|
|
|
_ => (),
|
|
_ => (),
|
|
}
|
|
}
|
|
- })
|
|
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
let mut props = self.borrowed_props.borrow_mut();
|
|
let mut props = self.borrowed_props.borrow_mut();
|
|
@@ -375,7 +434,7 @@ impl<'src> ScopeState {
|
|
.previous_frame()
|
|
.previous_frame()
|
|
.props_to_drop_before_reset
|
|
.props_to_drop_before_reset
|
|
.borrow_mut();
|
|
.borrow_mut();
|
|
- for node in element.dynamic_nodes {
|
|
|
|
|
|
+ for node in dynamic_nodes {
|
|
if let DynamicNode::Component(comp) = node {
|
|
if let DynamicNode::Component(comp) = node {
|
|
let unbounded = unsafe { std::mem::transmute(comp as *const VComponent) };
|
|
let unbounded = unsafe { std::mem::transmute(comp as *const VComponent) };
|
|
if !comp.static_props {
|
|
if !comp.static_props {
|
|
@@ -385,45 +444,14 @@ impl<'src> ScopeState {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- Some(element)
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- #[doc(hidden)]
|
|
|
|
- /// Take a [`crate::VNode`] and link it to a [`ScopeState`]
|
|
|
|
- ///
|
|
|
|
- /// This is used internally in the render macro
|
|
|
|
- pub fn link_node(&'src self, element: &crate::VNode<'src>) {
|
|
|
|
- let mut listeners = self.attributes_to_drop_before_render.borrow_mut();
|
|
|
|
- for attr in element.dynamic_attrs {
|
|
|
|
- match attr.value {
|
|
|
|
- // We need to drop listeners before the next render because they may borrow data from the borrowed props which will be dropped
|
|
|
|
- AttributeValue::Listener(_) => {
|
|
|
|
- let unbounded = unsafe { std::mem::transmute(attr as *const Attribute) };
|
|
|
|
- listeners.push(unbounded);
|
|
|
|
- }
|
|
|
|
- // We need to drop any values manually to make sure that their drop implementation is called before the next render
|
|
|
|
- AttributeValue::Any(_) => {
|
|
|
|
- let unbounded = unsafe { std::mem::transmute(attr as *const Attribute) };
|
|
|
|
- self.previous_frame().add_attribute_to_drop(unbounded);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- _ => (),
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- let mut props = self.borrowed_props.borrow_mut();
|
|
|
|
- let mut drop_props = self
|
|
|
|
- .previous_frame()
|
|
|
|
- .props_to_drop_before_reset
|
|
|
|
- .borrow_mut();
|
|
|
|
- for node in element.dynamic_nodes {
|
|
|
|
- if let DynamicNode::Component(comp) = node {
|
|
|
|
- let unbounded = unsafe { std::mem::transmute(comp as *const VComponent) };
|
|
|
|
- if !comp.static_props {
|
|
|
|
- props.push(unbounded);
|
|
|
|
- }
|
|
|
|
- drop_props.push(unbounded);
|
|
|
|
- }
|
|
|
|
|
|
+ VNode {
|
|
|
|
+ stable_id: Default::default(),
|
|
|
|
+ key,
|
|
|
|
+ parent,
|
|
|
|
+ template,
|
|
|
|
+ root_ids,
|
|
|
|
+ dynamic_nodes,
|
|
|
|
+ dynamic_attrs,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|