Merge branch 'master' into intigrate-collect-assets
This commit is contained in:
1 parent
ffb5de91d1
commit
f976e08f71
379 files changed
+1962
-13517
No files matched your search
@@ -9,7 +9,7 @@ edition = "2018"
|
||||
[dependencies]
|
||||
dioxus-core = { workspace = true }
|
||||
generational-box = { workspace = true }
|
||||
log.workspace = true
|
||||
tracing = { workspace = true }
|
||||
simple_logger = "4.2.0"
|
||||
serde = { version = "1", features = ["derive"], optional = true }
|
||||
|
||||
|
||||
@@ -10,7 +10,8 @@ All signals implement Copy, even if the inner value does not implement copy. Thi
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_signals::*;
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
#[component]
|
||||
fn App(cx: Scope) -> Element {
|
||||
let signal = use_signal(cx, || "hello world".to_string());
|
||||
|
||||
spawn(async move {
|
||||
@@ -32,7 +33,8 @@ Signals will only subscribe to components when you read from the signal in that
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_signals::*;
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
#[component]
|
||||
fn App(cx: Scope) -> Element {
|
||||
// Because signal is never read in this component, this component will not rerun when the signal changes
|
||||
let signal = use_signal(cx, || 0);
|
||||
|
||||
@@ -56,6 +58,7 @@ struct ChildProps {
|
||||
signal: Signal<usize>,
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn Child(cx: Scope<ChildProps>) -> Element {
|
||||
// This component does read from the signal, so when the signal changes it will rerun
|
||||
render! {
|
||||
@@ -70,15 +73,17 @@ Because subscriptions happen when you read from (not create) the data, you can p
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_signals::*;
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
#[component]
|
||||
fn App(cx: Scope) -> Element {
|
||||
// Because signal is never read in this component, this component will not rerun when the signal changes
|
||||
use_context_provider(cx, || Signal::new(0));
|
||||
|
||||
|
||||
render! {
|
||||
Child {}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn Child(cx: Scope) -> Element {
|
||||
let signal: Signal<i32> = *use_context(cx).unwrap();
|
||||
// This component does read from the signal, so when the signal changes it will rerun
|
||||
@@ -92,13 +97,14 @@ fn Child(cx: Scope) -> Element {
|
||||
|
||||
In addition to local subscriptions in components, `dioxus-signals` provides a way to derive data with local subscriptions.
|
||||
|
||||
The use_selector hook will only rerun when any signals inside of the hook change:
|
||||
The use_selector hook will only rerun when any signals inside the hook change:
|
||||
|
||||
```rust
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_signals::*;
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
#[component]
|
||||
fn App(cx: Scope) -> Element {
|
||||
let signal = use_signal(cx, || 0);
|
||||
let doubled = use_selector(cx, || signal * 2);
|
||||
|
||||
@@ -113,7 +119,7 @@ fn app(cx: Scope) -> Element {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn Child(cx: Scope, signal: ReadOnlySignal<usize>) -> Element {
|
||||
render! {
|
||||
"{signal}"
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_signals::*;
|
||||
|
||||
fn main() {
|
||||
dioxus_desktop::launch(app);
|
||||
dioxus_desktop::launch(App);
|
||||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
#[component]
|
||||
fn App(cx: Scope) -> Element {
|
||||
let signal = use_signal(cx, || 0);
|
||||
let doubled = use_selector(cx, move || signal * 2);
|
||||
|
||||
@@ -22,7 +21,7 @@ fn app(cx: Scope) -> Element {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn Child(cx: Scope, signal: ReadOnlySignal<usize>) -> Element {
|
||||
render! {
|
||||
"{signal}"
|
||||
|
||||
@@ -18,7 +18,8 @@ pub(crate) fn get_effect_stack() -> EffectStack {
|
||||
Some(rt) => rt,
|
||||
None => {
|
||||
let store = EffectStack::default();
|
||||
provide_root_context(store).expect("in a virtual dom")
|
||||
provide_root_context(store.clone());
|
||||
store
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,6 +55,7 @@ pub fn use_effect_with_dependencies<D: Dependency>(
|
||||
/// Effects allow you to run code when a signal changes. Effects are run immediately and whenever any signal it reads changes.
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub struct Effect {
|
||||
pub(crate) source: ScopeId,
|
||||
pub(crate) callback: CopyValue<Box<dyn FnMut()>>,
|
||||
}
|
||||
|
||||
@@ -73,6 +75,7 @@ impl Effect {
|
||||
/// The signal will be owned by the current component and will be dropped when the component is dropped.
|
||||
pub fn new(callback: impl FnMut() + 'static) -> Self {
|
||||
let myself = Self {
|
||||
source: current_scope_id().expect("in a virtual dom"),
|
||||
callback: CopyValue::new(Box::new(callback)),
|
||||
};
|
||||
|
||||
|
||||
@@ -2,14 +2,13 @@ use std::cell::{Ref, RefMut};
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
use dioxus_core::prelude::{
|
||||
consume_context, consume_context_from_scope, current_scope_id, provide_context,
|
||||
provide_context_to_scope, provide_root_context,
|
||||
};
|
||||
use dioxus_core::prelude::*;
|
||||
use dioxus_core::ScopeId;
|
||||
|
||||
use generational_box::{GenerationalBox, Owner, Store};
|
||||
|
||||
use crate::Effect;
|
||||
|
||||
fn current_store() -> Store {
|
||||
match consume_context() {
|
||||
Some(rt) => rt,
|
||||
@@ -21,12 +20,20 @@ fn current_store() -> Store {
|
||||
}
|
||||
|
||||
fn current_owner() -> Rc<Owner> {
|
||||
match consume_context() {
|
||||
Some(rt) => rt,
|
||||
None => {
|
||||
let owner = Rc::new(current_store().owner());
|
||||
provide_context(owner).expect("in a virtual dom")
|
||||
match Effect::current() {
|
||||
// If we are inside of an effect, we should use the owner of the effect as the owner of the value.
|
||||
Some(effect) => {
|
||||
let scope_id = effect.source;
|
||||
owner_in_scope(scope_id)
|
||||
}
|
||||
// Otherwise either get an owner from the current scope or create a new one.
|
||||
None => match has_context() {
|
||||
Some(rt) => rt,
|
||||
None => {
|
||||
let owner = Rc::new(current_store().owner());
|
||||
provide_context(owner).expect("in a virtual dom")
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@ pub fn selector<R: PartialEq>(mut f: impl FnMut() -> R + 'static) -> ReadOnlySig
|
||||
inner: CopyValue::invalid(),
|
||||
};
|
||||
let effect = Effect {
|
||||
source: current_scope_id().expect("in a virtual dom"),
|
||||
callback: CopyValue::invalid(),
|
||||
};
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ use crate::{CopyValue, Effect};
|
||||
/// render! { Child { state: count } }
|
||||
/// }
|
||||
///
|
||||
/// #[inline_props]
|
||||
/// #[component]
|
||||
/// fn Child(cx: Scope, state: Signal<u32>) -> Element {
|
||||
/// let state = *state;
|
||||
///
|
||||
@@ -89,6 +89,7 @@ pub(crate) struct SignalData<T> {
|
||||
/// use dioxus::prelude::*;
|
||||
/// use dioxus_signals::*;
|
||||
///
|
||||
/// #[component]
|
||||
/// fn App(cx: Scope) -> Element {
|
||||
/// let mut count = use_signal(cx, || 0);
|
||||
///
|
||||
@@ -97,7 +98,7 @@ pub(crate) struct SignalData<T> {
|
||||
/// render! { Child { state: count } }
|
||||
/// }
|
||||
///
|
||||
/// #[inline_props]
|
||||
/// #[component]
|
||||
/// fn Child(cx: Scope, state: Signal<u32>) -> Element {
|
||||
/// let state = *state;
|
||||
///
|
||||
@@ -177,7 +178,7 @@ impl<T: 'static> Signal<T> {
|
||||
} else if let Some(current_scope_id) = current_scope_id() {
|
||||
// only subscribe if the vdom is rendering
|
||||
if dioxus_core::vdom_is_rendering() {
|
||||
log::trace!(
|
||||
tracing::trace!(
|
||||
"{:?} subscribed to {:?}",
|
||||
self.inner.value,
|
||||
current_scope_id
|
||||
@@ -209,7 +210,7 @@ impl<T: 'static> Signal<T> {
|
||||
{
|
||||
let inner = self.inner.read();
|
||||
for &scope_id in &*inner.subscribers.borrow() {
|
||||
log::trace!(
|
||||
tracing::trace!(
|
||||
"Write on {:?} triggered update on {:?}",
|
||||
self.inner.value,
|
||||
scope_id
|
||||
@@ -224,7 +225,7 @@ impl<T: 'static> Signal<T> {
|
||||
std::mem::take(&mut *effects)
|
||||
};
|
||||
for effect in subscribers {
|
||||
log::trace!(
|
||||
tracing::trace!(
|
||||
"Write on {:?} triggered effect {:?}",
|
||||
self.inner.value,
|
||||
effect
|
||||
|
||||
Reference in new issue
Block a user