mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-23 12:43:08 +00:00
Merge pull request #1546 from DioxusLabs/jk/loop-allocation-strategy
Change the semantics of exprs/for loops allocations strategy
This commit is contained in:
commit
c7963a0344
4 changed files with 52 additions and 10 deletions
|
@ -6,11 +6,17 @@ fn main() {
|
|||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
let running = dioxus_signals::use_signal(cx, || true);
|
||||
let mut count = dioxus_signals::use_signal(cx, || 0);
|
||||
let saved_values = dioxus_signals::use_signal(cx, || vec![0.to_string()]);
|
||||
|
||||
// Signals can be used in async functions without an explicit clone since they're 'static and Copy
|
||||
// Signals are backed by a runtime that is designed to deeply integrate with Dioxus apps
|
||||
use_future!(cx, || async move {
|
||||
loop {
|
||||
count += 1;
|
||||
if running.value() {
|
||||
count += 1;
|
||||
}
|
||||
tokio::time::sleep(Duration::from_millis(400)).await;
|
||||
}
|
||||
});
|
||||
|
@ -19,9 +25,25 @@ fn app(cx: Scope) -> Element {
|
|||
h1 { "High-Five counter: {count}" }
|
||||
button { onclick: move |_| count += 1, "Up high!" }
|
||||
button { onclick: move |_| count -= 1, "Down low!" }
|
||||
button { onclick: move |_| running.toggle(), "Toggle counter" }
|
||||
button { onclick: move |_| saved_values.push(count.value().to_string()), "Save this value" }
|
||||
button { onclick: move |_| saved_values.write().clear(), "Clear saved values" }
|
||||
|
||||
// We can do boolean operations on the current signal value
|
||||
if count.value() > 5 {
|
||||
rsx!{ h2 { "High five!" } }
|
||||
}
|
||||
|
||||
// We can cleanly map signals with iterators
|
||||
for value in saved_values.read().iter() {
|
||||
h3 { "Saved value: {value}" }
|
||||
}
|
||||
|
||||
// We can also use the signal value as a slice
|
||||
if let [ref first, .., ref last] = saved_values.read().as_slice() {
|
||||
rsx! { li { "First and last: {first}, {last}" } }
|
||||
} else {
|
||||
rsx! { "No saved values" }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -91,9 +91,9 @@ pub mod prelude {
|
|||
consume_context, consume_context_from_scope, current_scope_id, fc_to_builder, has_context,
|
||||
provide_context, provide_context_to_scope, provide_root_context, push_future,
|
||||
remove_future, schedule_update_any, spawn, spawn_forever, suspend, throw, AnyValue,
|
||||
Component, Element, Event, EventHandler, Fragment, IntoAttributeValue, LazyNodes,
|
||||
Properties, Runtime, RuntimeGuard, Scope, ScopeId, ScopeState, Scoped, TaskId, Template,
|
||||
TemplateAttribute, TemplateNode, Throw, VNode, VirtualDom,
|
||||
Component, Element, Event, EventHandler, Fragment, IntoAttributeValue, IntoDynNode,
|
||||
LazyNodes, Properties, Runtime, RuntimeGuard, Scope, ScopeId, ScopeState, Scoped, TaskId,
|
||||
Template, TemplateAttribute, TemplateNode, Throw, VNode, VirtualDom,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -125,7 +125,10 @@ impl ToTokens for BodyNode {
|
|||
__cx.text_node(#txt)
|
||||
}),
|
||||
BodyNode::RawExpr(exp) => tokens.append_all(quote! {
|
||||
__cx.make_node(#exp)
|
||||
{
|
||||
let ___nodes = (#exp).into_vnode(__cx);
|
||||
___nodes
|
||||
}
|
||||
}),
|
||||
BodyNode::ForLoop(exp) => {
|
||||
let ForLoop {
|
||||
|
@ -137,16 +140,23 @@ impl ToTokens for BodyNode {
|
|||
location: None,
|
||||
};
|
||||
|
||||
// Signals expose an issue with temporary lifetimes
|
||||
// We need to directly render out the nodes first to collapse their lifetime to <'a>
|
||||
// And then we can return them into the dyn loop
|
||||
tokens.append_all(quote! {
|
||||
__cx.make_node(
|
||||
(#expr).into_iter().map(|#pat| { #renderer })
|
||||
)
|
||||
{
|
||||
let ___nodes =(#expr).into_iter().map(|#pat| { #renderer }).into_vnode(__cx);
|
||||
___nodes
|
||||
}
|
||||
})
|
||||
}
|
||||
BodyNode::IfChain(chain) => {
|
||||
if is_if_chain_terminated(chain) {
|
||||
tokens.append_all(quote! {
|
||||
__cx.make_node(#chain)
|
||||
{
|
||||
let ___nodes = (#chain).into_vnode(__cx);
|
||||
___nodes
|
||||
}
|
||||
});
|
||||
} else {
|
||||
let ExprIf {
|
||||
|
@ -200,7 +210,10 @@ impl ToTokens for BodyNode {
|
|||
});
|
||||
|
||||
tokens.append_all(quote! {
|
||||
__cx.make_node(#body)
|
||||
{
|
||||
let ___nodes = (#body).into_vnode(__cx);
|
||||
___nodes
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -264,6 +264,13 @@ impl<T: Clone + 'static> Signal<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl Signal<bool> {
|
||||
/// Invert the boolean value of the signal. This will trigger an update on all subscribers.
|
||||
pub fn toggle(&self) {
|
||||
self.set(!self.value());
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: 'static> PartialEq for Signal<T> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.inner == other.inner
|
||||
|
|
Loading…
Reference in a new issue