polish: clean up warnings
This commit is contained in:
1 parent
e881b86d2e
commit
b32e2611e3
21 files changed
+126
-129
No files matched your search
@@ -1 +0,0 @@
|
|||||||
settings.json
|
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"rust-analyzer.inlayHints.enable": false,
|
||||||
|
"rust-analyzer.cargo.allFeatures": true
|
||||||
|
}
|
||||||
@@ -1,12 +1,9 @@
|
|||||||
//! Example: Calculator
|
//! Example: Calculator
|
||||||
//! -------------------------
|
//! -------------------------
|
||||||
|
|
||||||
// use dioxus::events::on::*;
|
|
||||||
// use dioxus::prelude::*;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
dioxus::desktop::launch(App, |cfg| cfg);
|
dioxus::desktop::launch(App, |cfg| cfg).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
use dioxus::events::on::*;
|
use dioxus::events::on::*;
|
||||||
@@ -97,10 +94,10 @@ const App: FC<()> = |cx, props| {
|
|||||||
}
|
}
|
||||||
div { class: "digit-keys"
|
div { class: "digit-keys"
|
||||||
CalculatorKey { name: "key-0", onclick: move |_| input_digit(0), "0" }
|
CalculatorKey { name: "key-0", onclick: move |_| input_digit(0), "0" }
|
||||||
CalculatorKey { name: "key-dot", onclick: move |_| input_dot(), "●" }
|
CalculatorKey { name: "key-dot", onclick: move |_| input_dot(), "●" }
|
||||||
|
|
||||||
{(1..9).map(move |k| rsx!{
|
{(1..9).map(|k| rsx!{
|
||||||
CalculatorKey { key: "{k}", name: "key-{k}", onclick: move |_| input_digit(k), "{k}" }
|
CalculatorKey { key: "{k}", name: "key-{k}", onclick: move |_| input_digit(k), "{k}" }
|
||||||
})}
|
})}
|
||||||
}
|
}
|
||||||
div { class: "operator-keys"
|
div { class: "operator-keys"
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ fn main() {
|
|||||||
AppendChildren { many: 1 },
|
AppendChildren { many: 1 },
|
||||||
// ReplaceWith { many: 1 },
|
// ReplaceWith { many: 1 },
|
||||||
];
|
];
|
||||||
|
|
||||||
dioxus_desktop::WebviewRenderer::run_with_edits(App, (), |c| c, Some(edits)).expect("failed");
|
dioxus_desktop::WebviewRenderer::run_with_edits(App, (), |c| c, Some(edits)).expect("failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -237,8 +237,8 @@ where
|
|||||||
// # Safety
|
// # Safety
|
||||||
//
|
//
|
||||||
// - This is the canonical example of using `ManuallyDrop`.
|
// - This is the canonical example of using `ManuallyDrop`.
|
||||||
let value = ManuallyDrop::into_inner(ptr::read(&mut self.0));
|
let value = ManuallyDrop::into_inner(ptr::read(&self.0));
|
||||||
let drop = ManuallyDrop::into_inner(ptr::read(&mut self.1));
|
let drop = ManuallyDrop::into_inner(ptr::read(&self.1));
|
||||||
drop(value);
|
drop(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,11 +86,11 @@ impl Parse for AmbiguousElement<AS_HTML> {
|
|||||||
if first_char.is_ascii_uppercase() {
|
if first_char.is_ascii_uppercase() {
|
||||||
input
|
input
|
||||||
.parse::<Component<AS_HTML>>()
|
.parse::<Component<AS_HTML>>()
|
||||||
.map(|c| AmbiguousElement::Component(c))
|
.map(AmbiguousElement::Component)
|
||||||
} else {
|
} else {
|
||||||
input
|
input
|
||||||
.parse::<Element<AS_HTML>>()
|
.parse::<Element<AS_HTML>>()
|
||||||
.map(|c| AmbiguousElement::Element(c))
|
.map(AmbiguousElement::Element)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(Error::new(input.span(), "Not a valid Html tag"))
|
Err(Error::new(input.span(), "Not a valid Html tag"))
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ fn parse_rsx_element_field(
|
|||||||
name,
|
name,
|
||||||
value: ty,
|
value: ty,
|
||||||
namespace: None,
|
namespace: None,
|
||||||
element_name: element_name.clone(),
|
element_name,
|
||||||
});
|
});
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ impl<'a> Iterator for RealChildIterator<'a> {
|
|||||||
// We've recursed INTO an element/text
|
// We've recursed INTO an element/text
|
||||||
// We need to recurse *out* of it and move forward to the next
|
// We need to recurse *out* of it and move forward to the next
|
||||||
should_pop = true;
|
should_pop = true;
|
||||||
returned_node = Some(&*node);
|
returned_node = Some(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we get a fragment we push the next child
|
// If we get a fragment we push the next child
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ use crate::innerlude::{Context, DomTree, LazyNodes, FC};
|
|||||||
/// You want to use this free-function when your fragment needs a key and simply returning multiple nodes from rsx! won't cut it.
|
/// You want to use this free-function when your fragment needs a key and simply returning multiple nodes from rsx! won't cut it.
|
||||||
///
|
///
|
||||||
#[allow(non_upper_case_globals, non_snake_case)]
|
#[allow(non_upper_case_globals, non_snake_case)]
|
||||||
pub fn Fragment<'a>(cx: Context<'a>, props: &'a ()) -> DomTree<'a> {
|
pub fn Fragment<'a>(cx: Context<'a>, _: &'a ()) -> DomTree<'a> {
|
||||||
cx.render(LazyNodes::new(|f| f.fragment_from_iter(cx.children())))
|
cx.render(LazyNodes::new(|f| f.fragment_from_iter(cx.children())))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,9 +91,7 @@ impl Properties for () {
|
|||||||
pub struct EmptyBuilder;
|
pub struct EmptyBuilder;
|
||||||
impl EmptyBuilder {
|
impl EmptyBuilder {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn build(self) -> () {
|
pub fn build(self) {}
|
||||||
()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This utility function launches the builder method so rsx! and html! macros can use the typed-builder pattern
|
/// This utility function launches the builder method so rsx! and html! macros can use the typed-builder pattern
|
||||||
|
|||||||
@@ -34,10 +34,7 @@ pub struct Context<'src> {
|
|||||||
impl<'src> Copy for Context<'src> {}
|
impl<'src> Copy for Context<'src> {}
|
||||||
impl<'src> Clone for Context<'src> {
|
impl<'src> Clone for Context<'src> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self { scope: self.scope }
|
||||||
// props: self.props,
|
|
||||||
scope: self.scope,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,16 +199,18 @@ impl<'src> Context<'src> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if !is_initialized {
|
if !is_initialized {
|
||||||
self.scope
|
let existing = self
|
||||||
.shared_contexts
|
.scope
|
||||||
.borrow_mut()
|
.shared_contexts
|
||||||
.insert(TypeId::of::<T>(), Rc::new(init()))
|
.borrow_mut()
|
||||||
.map(|_| {
|
.insert(TypeId::of::<T>(), Rc::new(init()));
|
||||||
|
|
||||||
|
if existing.is_some() {
|
||||||
log::warn!(
|
log::warn!(
|
||||||
"A shared state was replaced with itself. \
|
"A shared state was replaced with itself. \
|
||||||
This is does not result in a panic, but is probably not what you are trying to do"
|
This is does not result in a panic, but is probably not what you are trying to do"
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.use_consume_state().unwrap()
|
self.use_consume_state().unwrap()
|
||||||
@@ -244,12 +243,15 @@ impl<'src> Context<'src> {
|
|||||||
/// - Runner: closure used to output a value every time the hook is used
|
/// - Runner: closure used to output a value every time the hook is used
|
||||||
/// - Cleanup: closure used to teardown the hook once the dom is cleaned up
|
/// - Cleanup: closure used to teardown the hook once the dom is cleaned up
|
||||||
///
|
///
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
/// ```ignore
|
/// ```ignore
|
||||||
/// // use_ref is the simplest way of storing a value between renders
|
/// // use_ref is the simplest way of storing a value between renders
|
||||||
/// pub fn use_ref<T: 'static>(initial_value: impl FnOnce() -> T + 'static) -> Rc<RefCell<T>> {
|
/// fn use_ref<T: 'static>(initial_value: impl FnOnce() -> T) -> &RefCell<T> {
|
||||||
/// use_hook(
|
/// use_hook(
|
||||||
/// || Rc::new(RefCell::new(initial_value())),
|
/// || Rc::new(RefCell::new(initial_value())),
|
||||||
/// |state| state.clone(),
|
/// |state| state,
|
||||||
/// |_| {},
|
/// |_| {},
|
||||||
/// )
|
/// )
|
||||||
/// }
|
/// }
|
||||||
@@ -275,14 +277,14 @@ impl<'src> Context<'src> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ERR_MSG: &str = r###"
|
runner(self.scope.hooks.next::<State>().expect(HOOK_ERR_MSG))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const HOOK_ERR_MSG: &str = r###"
|
||||||
Unable to retrive the hook that was initialized in this index.
|
Unable to retrive the hook that was initialized in this index.
|
||||||
Consult the `rules of hooks` to understand how to use hooks properly.
|
Consult the `rules of hooks` to understand how to use hooks properly.
|
||||||
|
|
||||||
You likely used the hook in a conditional. Hooks rely on consistent ordering between renders.
|
You likely used the hook in a conditional. Hooks rely on consistent ordering between renders.
|
||||||
Any function prefixed with "use" should not be called conditionally.
|
Any function prefixed with "use" should not be called conditionally.
|
||||||
"###;
|
"###;
|
||||||
|
|
||||||
runner(self.scope.hooks.next::<State>().expect(ERR_MSG))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+32
-24
@@ -328,8 +328,8 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
self.mutations.set_attribute(attr);
|
self.mutations.set_attribute(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if children.len() > 0 {
|
if children.is_empty() {
|
||||||
self.stack.element_id_stack.push(real_id);;
|
self.stack.element_id_stack.push(real_id);
|
||||||
// push our element_id onto the stack
|
// push our element_id onto the stack
|
||||||
// drop our element off the stack
|
// drop our element off the stack
|
||||||
self.stack.create_children(children, MountType::Append);
|
self.stack.create_children(children, MountType::Append);
|
||||||
@@ -341,7 +341,7 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn create_component_node(&mut self, vcomponent: &'bump VComponent<'bump>) {
|
fn create_component_node(&mut self, vcomponent: &'bump VComponent<'bump>) {
|
||||||
let caller = vcomponent.caller.clone();
|
let caller = vcomponent.caller;
|
||||||
|
|
||||||
let parent_idx = self.stack.current_scope().unwrap();
|
let parent_idx = self.stack.current_scope().unwrap();
|
||||||
|
|
||||||
@@ -546,13 +546,15 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
// 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();
|
||||||
|
|
||||||
scope.update_scope_dependencies(new.caller.clone(), ScopeChildren(new.children));
|
scope.update_scope_dependencies(new.caller, ScopeChildren(new.children));
|
||||||
|
|
||||||
// React doesn't automatically memoize, but we do.
|
// React doesn't automatically memoize, but we do.
|
||||||
let props_are_the_same = old.comparator.unwrap();
|
let props_are_the_same = old.comparator.unwrap();
|
||||||
|
|
||||||
if self.cfg.force_diff || !props_are_the_same(new) {
|
if self.cfg.force_diff || !props_are_the_same(new) {
|
||||||
if scope.run_scope(self.vdom) {
|
let succeeded = scope.run_scope(self.vdom);
|
||||||
|
|
||||||
|
if succeeded {
|
||||||
self.diff_node(scope.frames.wip_head(), scope.frames.fin_head());
|
self.diff_node(scope.frames.wip_head(), scope.frames.fin_head());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -664,16 +666,20 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
self.stack.push(DiffInstruction::Diff { new, old });
|
self.stack.push(DiffInstruction::Diff { new, old });
|
||||||
}
|
}
|
||||||
|
|
||||||
if old.len() > new.len() {
|
use std::cmp::Ordering;
|
||||||
self.remove_nodes(&old[new.len()..]);
|
match old.len().cmp(&new.len()) {
|
||||||
} else if new.len() > old.len() {
|
Ordering::Greater => self.remove_nodes(&old[new.len()..]),
|
||||||
log::debug!("Calling create children on array differences");
|
Ordering::Less => {
|
||||||
self.stack.create_children(
|
self.stack.create_children(
|
||||||
&new[old.len()..],
|
&new[old.len()..],
|
||||||
MountType::InsertAfter {
|
MountType::InsertAfter {
|
||||||
other_node: old.last().unwrap(),
|
other_node: old.last().unwrap(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
Ordering::Equal => {
|
||||||
|
// nothing - they're the same size
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -922,7 +928,7 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
// for each spacing, generate a mount instruction
|
// for each spacing, generate a mount instruction
|
||||||
let mut lis_iter = lis_sequence.iter().rev();
|
let mut lis_iter = lis_sequence.iter().rev();
|
||||||
let mut last = *lis_iter.next().unwrap();
|
let mut last = *lis_iter.next().unwrap();
|
||||||
while let Some(&next) = lis_iter.next() {
|
for next in lis_iter {
|
||||||
if last - next > 1 {
|
if last - next > 1 {
|
||||||
self.stack.push_nodes_created(0);
|
self.stack.push_nodes_created(0);
|
||||||
self.stack.push(DiffInstruction::Mount {
|
self.stack.push(DiffInstruction::Mount {
|
||||||
@@ -934,7 +940,7 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
apply(idx + next + 1, new_node, &mut self.stack);
|
apply(idx + next + 1, new_node, &mut self.stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
last = next;
|
last = *next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add mount instruction for the first items not covered by the lis
|
// add mount instruction for the first items not covered by the lis
|
||||||
@@ -1036,25 +1042,27 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
for node in nodes {
|
for node in nodes {
|
||||||
match node {
|
match node {
|
||||||
VNode::Text(t) => {
|
VNode::Text(t) => {
|
||||||
t.dom_id.get().map(|id| {
|
if let Some(id) = t.dom_id.get() {
|
||||||
self.mutations.remove(id.as_u64());
|
self.mutations.remove(id.as_u64());
|
||||||
self.vdom.collect_garbage(id);
|
self.vdom.collect_garbage(id);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
VNode::Suspended(s) => {
|
VNode::Suspended(s) => {
|
||||||
s.dom_id.get().map(|id| {
|
if let Some(id) = s.dom_id.get() {
|
||||||
self.mutations.remove(id.as_u64());
|
self.mutations.remove(id.as_u64());
|
||||||
self.vdom.collect_garbage(id);
|
self.vdom.collect_garbage(id);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
VNode::Anchor(a) => {
|
VNode::Anchor(a) => {
|
||||||
a.dom_id.get().map(|id| {
|
if let Some(id) = a.dom_id.get() {
|
||||||
self.mutations.remove(id.as_u64());
|
self.mutations.remove(id.as_u64());
|
||||||
self.vdom.collect_garbage(id);
|
self.vdom.collect_garbage(id);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
VNode::Element(e) => {
|
VNode::Element(e) => {
|
||||||
e.dom_id.get().map(|id| self.mutations.remove(id.as_u64()));
|
if let Some(id) = e.dom_id.get() {
|
||||||
|
self.mutations.remove(id.as_u64());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
VNode::Fragment(f) => {
|
VNode::Fragment(f) => {
|
||||||
self.remove_nodes(f.children);
|
self.remove_nodes(f.children);
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ impl<'bump> DiffStack<'bump> {
|
|||||||
self.nodes_created_stack.push(0);
|
self.nodes_created_stack.push(0);
|
||||||
self.instructions.push(DiffInstruction::Mount { and });
|
self.instructions.push(DiffInstruction::Mount { and });
|
||||||
|
|
||||||
for child in children.into_iter().rev() {
|
for child in children.iter().rev() {
|
||||||
self.instructions
|
self.instructions
|
||||||
.push(DiffInstruction::Create { node: child });
|
.push(DiffInstruction::Create { node: child });
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ impl<'bump> DiffStack<'bump> {
|
|||||||
self.nodes_created_stack.push(count);
|
self.nodes_created_stack.push(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_element_id(&mut self, id: ElementId) {
|
pub fn _push_element_id(&mut self, id: ElementId) {
|
||||||
self.element_id_stack.push(id);
|
self.element_id_stack.push(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ impl<'bump> DiffStack<'bump> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn current_scope(&self) -> Option<ScopeId> {
|
pub fn current_scope(&self) -> Option<ScopeId> {
|
||||||
self.scope_stack.last().map(|f| f.clone())
|
self.scope_stack.last().copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_component(&mut self, idx: ScopeId, node: &'bump VNode<'bump>) {
|
pub fn create_component(&mut self, idx: ScopeId, node: &'bump VNode<'bump>) {
|
||||||
|
|||||||
@@ -52,8 +52,11 @@ impl HookList {
|
|||||||
pub(crate) fn at_end(&self) -> bool {
|
pub(crate) fn at_end(&self) -> bool {
|
||||||
self.cur_idx() >= self.len()
|
self.cur_idx() >= self.len()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn cleanup_hooks(&mut self) {
|
// When the scope is dropped, we want to call the cleanup function for each of the hooks
|
||||||
|
impl Drop for HookList {
|
||||||
|
fn drop(&mut self) {
|
||||||
self.vals
|
self.vals
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.drain(..)
|
.drain(..)
|
||||||
|
|||||||
@@ -11,13 +11,7 @@
|
|||||||
|
|
||||||
use crate::innerlude::*;
|
use crate::innerlude::*;
|
||||||
use futures_util::FutureExt;
|
use futures_util::FutureExt;
|
||||||
use std::{
|
use std::{any::Any, cell::RefCell, future::Future, ops::Deref, rc::Rc};
|
||||||
any::{Any, TypeId},
|
|
||||||
cell::RefCell,
|
|
||||||
future::Future,
|
|
||||||
ops::Deref,
|
|
||||||
rc::Rc,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Awaits the given task, forcing the component to re-render when the value is ready.
|
/// Awaits the given task, forcing the component to re-render when the value is ready.
|
||||||
///
|
///
|
||||||
@@ -104,11 +98,10 @@ where
|
|||||||
- if it doesn't, then we render a suspended node along with with the callback and task id
|
- if it doesn't, then we render a suspended node along with with the callback and task id
|
||||||
*/
|
*/
|
||||||
cx.use_hook(
|
cx.use_hook(
|
||||||
move |hook_idx| {
|
move |_| {
|
||||||
let value = Rc::new(RefCell::new(None));
|
let value = Rc::new(RefCell::new(None));
|
||||||
let slot = value.clone();
|
let slot = value.clone();
|
||||||
|
let originator = cx.scope.our_arena_idx;
|
||||||
let originator = cx.scope.our_arena_idx.clone();
|
|
||||||
|
|
||||||
let handle = cx.submit_task(Box::pin(task_initializer().then(
|
let handle = cx.submit_task(Box::pin(task_initializer().then(
|
||||||
move |output| async move {
|
move |output| async move {
|
||||||
@@ -176,9 +169,7 @@ impl<'src> SuspendedContext<'src> {
|
|||||||
self,
|
self,
|
||||||
lazy_nodes: LazyNodes<'src, F>,
|
lazy_nodes: LazyNodes<'src, F>,
|
||||||
) -> DomTree<'src> {
|
) -> DomTree<'src> {
|
||||||
let scope_ref = self.inner.scope;
|
|
||||||
let bump = &self.inner.scope.frames.wip_frame().bump;
|
let bump = &self.inner.scope.frames.wip_frame().bump;
|
||||||
|
|
||||||
Some(lazy_nodes.into_vnode(NodeFactory { bump }))
|
Some(lazy_nodes.into_vnode(NodeFactory { bump }))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -194,14 +185,5 @@ impl<'a, T> Deref for NodeRef<'a, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn use_node_ref<T, P>(cx: Context) -> NodeRef<T> {
|
pub fn use_node_ref<T, P>(cx: Context) -> NodeRef<T> {
|
||||||
cx.use_hook(
|
cx.use_hook(|_| RefCell::new(None), |f| NodeRef { 0: f }, |_| {})
|
||||||
|f| {},
|
|
||||||
|f| {
|
|
||||||
//
|
|
||||||
todo!()
|
|
||||||
},
|
|
||||||
|f| {
|
|
||||||
//
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
+10
-10
@@ -307,7 +307,7 @@ impl<'a> NodeFactory<'a> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn bump(&self) -> &'a bumpalo::Bump {
|
pub fn bump(&self) -> &'a bumpalo::Bump {
|
||||||
&self.bump
|
self.bump
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_directly<F>(&self, lazy_nodes: LazyNodes<'a, F>) -> DomTree<'a>
|
pub fn render_directly<F>(&self, lazy_nodes: LazyNodes<'a, F>) -> DomTree<'a>
|
||||||
@@ -466,12 +466,12 @@ impl<'a> NodeFactory<'a> {
|
|||||||
// - This comparator is only called on a corresponding set of bumpframes
|
// - This comparator is only called on a corresponding set of bumpframes
|
||||||
let props_memoized = unsafe {
|
let props_memoized = unsafe {
|
||||||
let real_other: &P = &*(other.raw_props as *const _ as *const P);
|
let real_other: &P = &*(other.raw_props as *const _ as *const P);
|
||||||
props.memoize(&real_other)
|
props.memoize(real_other)
|
||||||
};
|
};
|
||||||
|
|
||||||
// It's only okay to memoize if there are no children and the props can be memoized
|
// It's only okay to memoize if there are no children and the props can be memoized
|
||||||
// Implementing memoize is unsafe and done automatically with the props trait
|
// Implementing memoize is unsafe and done automatically with the props trait
|
||||||
match (props_memoized, children.len() == 0) {
|
match (props_memoized, children.is_empty()) {
|
||||||
(true, true) => true,
|
(true, true) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
@@ -504,7 +504,7 @@ impl<'a> NodeFactory<'a> {
|
|||||||
RefCell::new(Some(drop_props))
|
RefCell::new(Some(drop_props))
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_static = children.len() == 0 && P::IS_STATIC && key.is_none();
|
let is_static = children.is_empty() && P::IS_STATIC && key.is_none();
|
||||||
|
|
||||||
let key = key.map(|f| self.raw_text(f).0);
|
let key = key.map(|f| self.raw_text(f).0);
|
||||||
|
|
||||||
@@ -515,7 +515,7 @@ impl<'a> NodeFactory<'a> {
|
|||||||
unsafe { std::mem::transmute(res) }
|
unsafe { std::mem::transmute(res) }
|
||||||
});
|
});
|
||||||
|
|
||||||
let can_memoize = children.len() == 0 && P::IS_STATIC;
|
let can_memoize = children.is_empty() && P::IS_STATIC;
|
||||||
|
|
||||||
VNode::Component(bump.alloc(VComponent {
|
VNode::Component(bump.alloc(VComponent {
|
||||||
user_fc,
|
user_fc,
|
||||||
@@ -596,7 +596,7 @@ where
|
|||||||
nodes.push(node.into_vnode(cx));
|
nodes.push(node.into_vnode(cx));
|
||||||
}
|
}
|
||||||
|
|
||||||
if nodes.len() == 0 {
|
if nodes.is_empty() {
|
||||||
nodes.push(VNode::Anchor(VAnchor {
|
nodes.push(VNode::Anchor(VAnchor {
|
||||||
dom_id: empty_cell(),
|
dom_id: empty_cell(),
|
||||||
}));
|
}));
|
||||||
@@ -716,14 +716,14 @@ where
|
|||||||
|
|
||||||
// Conveniently, we also support "null" (nothing) passed in
|
// Conveniently, we also support "null" (nothing) passed in
|
||||||
impl IntoVNode<'_> for () {
|
impl IntoVNode<'_> for () {
|
||||||
fn into_vnode<'a>(self, cx: NodeFactory<'a>) -> VNode<'a> {
|
fn into_vnode(self, cx: NodeFactory) -> VNode {
|
||||||
cx.fragment_from_iter(None as Option<VNode>)
|
cx.fragment_from_iter(None as Option<VNode>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Conveniently, we also support "None"
|
// Conveniently, we also support "None"
|
||||||
impl IntoVNode<'_> for Option<()> {
|
impl IntoVNode<'_> for Option<()> {
|
||||||
fn into_vnode<'a>(self, cx: NodeFactory<'a>) -> VNode<'a> {
|
fn into_vnode(self, cx: NodeFactory) -> VNode {
|
||||||
cx.fragment_from_iter(None as Option<VNode>)
|
cx.fragment_from_iter(None as Option<VNode>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -738,12 +738,12 @@ impl<'a> IntoVNode<'a> for Option<VNode<'a>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl IntoVNode<'_> for &'static str {
|
impl IntoVNode<'_> for &'static str {
|
||||||
fn into_vnode<'a>(self, cx: NodeFactory<'a>) -> VNode<'a> {
|
fn into_vnode(self, cx: NodeFactory) -> VNode {
|
||||||
cx.static_text(self)
|
cx.static_text(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl IntoVNode<'_> for Arguments<'_> {
|
impl IntoVNode<'_> for Arguments<'_> {
|
||||||
fn into_vnode<'a>(self, cx: NodeFactory<'a>) -> VNode<'a> {
|
fn into_vnode(self, cx: NodeFactory) -> VNode {
|
||||||
cx.text(self)
|
cx.text(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,9 +88,11 @@ pub(crate) struct EventChannel {
|
|||||||
pub sender: UnboundedSender<SchedulerMsg>,
|
pub sender: UnboundedSender<SchedulerMsg>,
|
||||||
pub schedule_any_immediate: Rc<dyn Fn(ScopeId)>,
|
pub schedule_any_immediate: Rc<dyn Fn(ScopeId)>,
|
||||||
pub submit_task: Rc<dyn Fn(FiberTask) -> TaskHandle>,
|
pub submit_task: Rc<dyn Fn(FiberTask) -> TaskHandle>,
|
||||||
pub get_shared_context: Rc<dyn Fn(ScopeId, TypeId) -> Option<Rc<dyn Any>>>,
|
pub get_shared_context: GetSharedContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type GetSharedContext = Rc<dyn Fn(ScopeId, TypeId) -> Option<Rc<dyn Any>>>;
|
||||||
|
|
||||||
pub enum SchedulerMsg {
|
pub enum SchedulerMsg {
|
||||||
// events from the host
|
// events from the host
|
||||||
UiEvent(UserEvent),
|
UiEvent(UserEvent),
|
||||||
@@ -175,7 +177,6 @@ impl Scheduler {
|
|||||||
Rc::new(move |id| sender.unbounded_send(SchedulerMsg::Immediate(id)).unwrap())
|
Rc::new(move |id| sender.unbounded_send(SchedulerMsg::Immediate(id)).unwrap())
|
||||||
},
|
},
|
||||||
submit_task: {
|
submit_task: {
|
||||||
let sender = sender.clone();
|
|
||||||
Rc::new(move |fiber_task| {
|
Rc::new(move |fiber_task| {
|
||||||
let task_id = task_counter.get();
|
let task_id = task_counter.get();
|
||||||
task_counter.set(task_id + 1);
|
task_counter.set(task_id + 1);
|
||||||
@@ -206,7 +207,7 @@ impl Scheduler {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let pool = ResourcePool {
|
let pool = ResourcePool {
|
||||||
components: components.clone(),
|
components,
|
||||||
raw_elements,
|
raw_elements,
|
||||||
channel,
|
channel,
|
||||||
};
|
};
|
||||||
@@ -295,7 +296,7 @@ impl Scheduler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_pending_events(&self) -> bool {
|
pub fn has_pending_events(&self) -> bool {
|
||||||
self.ui_events.len() > 0
|
!self.ui_events.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// re-balance the work lanes, ensuring high-priority work properly bumps away low priority work
|
/// re-balance the work lanes, ensuring high-priority work properly bumps away low priority work
|
||||||
@@ -550,6 +551,6 @@ impl PriorityLane {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn has_work(&self) -> bool {
|
fn has_work(&self) -> bool {
|
||||||
self.dirty_scopes.len() > 0 || self.in_progress == true
|
!self.dirty_scopes.is_empty() || self.in_progress
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -190,7 +190,7 @@ impl Scope {
|
|||||||
self.child_nodes = child_nodes;
|
self.child_nodes = child_nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn child_nodes<'a>(&'a self) -> ScopeChildren {
|
pub(crate) fn child_nodes(&self) -> ScopeChildren {
|
||||||
unsafe { self.child_nodes.shorten_lifetime() }
|
unsafe { self.child_nodes.shorten_lifetime() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,10 +246,7 @@ impl Scope {
|
|||||||
let search_id = search.mounted_node.get();
|
let search_id = search.mounted_node.get();
|
||||||
|
|
||||||
// this assumes the node might not be mounted - should we assume that though?
|
// this assumes the node might not be mounted - should we assume that though?
|
||||||
match search_id.map(|f| f == element) {
|
search_id.map(|f| f == element).unwrap_or(false)
|
||||||
Some(same) => same,
|
|
||||||
None => false,
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(raw_listener) = raw_listener {
|
if let Some(raw_listener) = raw_listener {
|
||||||
@@ -356,11 +353,11 @@ impl<'a> ScopeRenderer<'a> {
|
|||||||
match &node {
|
match &node {
|
||||||
VNode::Text(text) => {
|
VNode::Text(text) => {
|
||||||
write_indent(f, il);
|
write_indent(f, il);
|
||||||
write!(f, "\"{}\"\n", text.text)?
|
writeln!(f, "\"{}\"", text.text)?
|
||||||
}
|
}
|
||||||
VNode::Anchor(_anchor) => {
|
VNode::Anchor(_anchor) => {
|
||||||
write_indent(f, il);
|
write_indent(f, il);
|
||||||
write!(f, "Anchor {{}}\n")?;
|
writeln!(f, "Anchor {{}}")?;
|
||||||
}
|
}
|
||||||
VNode::Element(el) => {
|
VNode::Element(el) => {
|
||||||
write_indent(f, il);
|
write_indent(f, il);
|
||||||
@@ -373,7 +370,7 @@ impl<'a> ScopeRenderer<'a> {
|
|||||||
None => {
|
None => {
|
||||||
//
|
//
|
||||||
write_indent(f, il + 1);
|
write_indent(f, il + 1);
|
||||||
write!(f, "{}: \"{}\"\n", attr.name, attr.value)?
|
writeln!(f, "{}: \"{}\"", attr.name, attr.value)?
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(ns) => {
|
Some(ns) => {
|
||||||
@@ -401,17 +398,17 @@ impl<'a> ScopeRenderer<'a> {
|
|||||||
}
|
}
|
||||||
write_indent(f, il);
|
write_indent(f, il);
|
||||||
|
|
||||||
write!(f, "}}\n")?;
|
writeln!(f, "}}")?;
|
||||||
}
|
}
|
||||||
VNode::Fragment(frag) => {
|
VNode::Fragment(frag) => {
|
||||||
if self.show_fragments {
|
if self.show_fragments {
|
||||||
write_indent(f, il);
|
write_indent(f, il);
|
||||||
write!(f, "Fragment {{\n")?;
|
writeln!(f, "Fragment {{")?;
|
||||||
for child in frag.children {
|
for child in frag.children {
|
||||||
self.render(vdom, child, f, il + 1)?;
|
self.render(vdom, child, f, il + 1)?;
|
||||||
}
|
}
|
||||||
write_indent(f, il);
|
write_indent(f, il);
|
||||||
write!(f, "}}\n")?;
|
writeln!(f, "}}")?;
|
||||||
} else {
|
} else {
|
||||||
for child in frag.children {
|
for child in frag.children {
|
||||||
self.render(vdom, child, f, il)?;
|
self.render(vdom, child, f, il)?;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ impl TestDom {
|
|||||||
TestDom { bump, scheduler }
|
TestDom { bump, scheduler }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_factory<'a>(&'a self) -> NodeFactory<'a> {
|
pub fn new_factory(&self) -> NodeFactory {
|
||||||
NodeFactory::new(&self.bump)
|
NodeFactory::new(&self.bump)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,6 +87,12 @@ impl TestDom {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for TestDom {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl VirtualDom {
|
impl VirtualDom {
|
||||||
pub fn simulate(&mut self) {
|
pub fn simulate(&mut self) {
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
use crate::innerlude::*;
|
|
||||||
|
|
||||||
// create a cell with a "none" value
|
// create a cell with a "none" value
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn empty_cell() -> Cell<Option<ElementId>> {
|
pub fn empty_cell() -> Cell<Option<ElementId>> {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
//! Additional functionality is defined in the respective files.
|
//! Additional functionality is defined in the respective files.
|
||||||
|
|
||||||
use crate::innerlude::*;
|
use crate::innerlude::*;
|
||||||
|
use futures_util::Future;
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
|
|
||||||
/// An integrated virtual node system that progresses events and diffs UI trees.
|
/// An integrated virtual node system that progresses events and diffs UI trees.
|
||||||
@@ -186,7 +187,10 @@ impl VirtualDom {
|
|||||||
///
|
///
|
||||||
/// let mutations = dom.update_root_props(AppProps { route: "end" }).unwrap();
|
/// let mutations = dom.update_root_props(AppProps { route: "end" }).unwrap();
|
||||||
/// ```
|
/// ```
|
||||||
pub fn update_root_props<'s, P: 'static>(&'s mut self, root_props: P) -> Option<Mutations<'s>> {
|
pub fn update_root_props<P>(&mut self, root_props: P) -> Option<Mutations>
|
||||||
|
where
|
||||||
|
P: 'static,
|
||||||
|
{
|
||||||
let root_scope = self.scheduler.pool.get_scope_mut(self.base_scope).unwrap();
|
let root_scope = self.scheduler.pool.get_scope_mut(self.base_scope).unwrap();
|
||||||
|
|
||||||
// Pre-emptively drop any downstream references of the old props
|
// Pre-emptively drop any downstream references of the old props
|
||||||
@@ -233,7 +237,7 @@ impl VirtualDom {
|
|||||||
///
|
///
|
||||||
/// apply_edits(edits);
|
/// apply_edits(edits);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn rebuild<'s>(&'s mut self) -> Mutations<'s> {
|
pub fn rebuild(&mut self) -> Mutations {
|
||||||
self.scheduler.rebuild(self.base_scope)
|
self.scheduler.rebuild(self.base_scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,7 +275,7 @@ impl VirtualDom {
|
|||||||
///
|
///
|
||||||
/// let edits = dom.diff();
|
/// let edits = dom.diff();
|
||||||
/// ```
|
/// ```
|
||||||
pub fn diff<'s>(&'s mut self) -> Mutations<'s> {
|
pub fn diff(&mut self) -> Mutations {
|
||||||
self.scheduler.hard_diff(self.base_scope)
|
self.scheduler.hard_diff(self.base_scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,7 +283,7 @@ impl VirtualDom {
|
|||||||
///
|
///
|
||||||
/// This method will not wait for any suspended nodes to complete. If there is no pending work, then this method will
|
/// This method will not wait for any suspended nodes to complete. If there is no pending work, then this method will
|
||||||
/// return "None"
|
/// return "None"
|
||||||
pub fn run_immediate<'s>(&'s mut self) -> Option<Vec<Mutations<'s>>> {
|
pub fn run_immediate(&mut self) -> Option<Vec<Mutations>> {
|
||||||
if self.scheduler.has_any_work() {
|
if self.scheduler.has_any_work() {
|
||||||
Some(self.scheduler.work_sync())
|
Some(self.scheduler.work_sync())
|
||||||
} else {
|
} else {
|
||||||
@@ -330,10 +334,10 @@ impl VirtualDom {
|
|||||||
/// applied the edits.
|
/// applied the edits.
|
||||||
///
|
///
|
||||||
/// Mutations are the only link between the RealDOM and the VirtualDOM.
|
/// Mutations are the only link between the RealDOM and the VirtualDOM.
|
||||||
pub async fn run_with_deadline<'s>(
|
pub async fn run_with_deadline(
|
||||||
&'s mut self,
|
&mut self,
|
||||||
deadline: impl std::future::Future<Output = ()>,
|
deadline: impl Future<Output = ()>,
|
||||||
) -> Vec<Mutations<'s>> {
|
) -> Vec<Mutations<'_>> {
|
||||||
self.scheduler.work_with_deadline(deadline).await
|
self.scheduler.work_with_deadline(deadline).await
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,8 +384,3 @@ impl std::fmt::Display for VirtualDom {
|
|||||||
renderer.render(self, root, f, 0)
|
renderer.render(self, root, f, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct VirtualDomConfig {
|
|
||||||
component_slab_size: usize,
|
|
||||||
element_slab_size: usize,
|
|
||||||
}
|
|
||||||
@@ -64,10 +64,12 @@ impl<T: Properties + 'static> WebviewRenderer<T> {
|
|||||||
Self::run_with_edits(root, props, user_builder, None)
|
Self::run_with_edits(root, props, user_builder, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_with_edits(
|
pub fn run_with_edits<
|
||||||
|
F: for<'a, 'b> FnOnce(&'a mut DesktopConfig<'b>) -> &'a mut DesktopConfig<'b>,
|
||||||
|
>(
|
||||||
root: FC<T>,
|
root: FC<T>,
|
||||||
props: T,
|
props: T,
|
||||||
user_builder: impl for<'a, 'b> FnOnce(&'a mut DesktopConfig<'b>) -> &'a mut DesktopConfig<'b>,
|
user_builder: F,
|
||||||
redits: Option<Vec<DomEdit<'static>>>,
|
redits: Option<Vec<DomEdit<'static>>>,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
log::info!("hello edits");
|
log::info!("hello edits");
|
||||||
|
|||||||
Reference in new issue
Block a user