implement use_async_memo with reactive context

This commit is contained in:
Jonathan Kelley committed 2024-02-01 13:21:53 -08:00
1 parent 7c2947a131
commit dd06705ff1
7 files changed
+68 -58

No files matched your search

+1 -1
View File
@@ -1,7 +1,7 @@
use crate::use_hook_did_run;
use dioxus_core::prelude::*;
use dioxus_signals::{CopyValue, Effect, ReactiveContext, Writable};
use futures_util::select;
// use futures_util::select;
/// Create a new effect. The effect will be run immediately and whenever any signal it reads changes.
/// The signal will be owned by the current component and will be dropped when the component is dropped.
-5
View File
@@ -57,13 +57,8 @@ pub fn use_maybe_sync_memo<R: PartialEq, S: Storage<SignalData<R>>>(
spawn(async move {
loop {
rc.changed().await;
println!("change triggered in memo");
let new = rc.run_in(|| f());
if new != *state.peek() {
println!("change sett in memo");
*state.write() = new;
}
}
+39 -26
View File
@@ -1,8 +1,8 @@
#![allow(missing_docs)]
use crate::use_signal;
use crate::{use_callback, use_signal};
use dioxus_core::{
prelude::{spawn, suspend},
prelude::{spawn, suspend, use_hook},
Task,
};
use dioxus_signals::*;
@@ -19,31 +19,44 @@ where
F: Future<Output = T> + 'static,
{
let mut value = use_signal(|| None);
let state = use_signal(|| UseResourceState::Pending);
let mut state = use_signal(|| UseResourceState::Pending);
let rc = use_hook(|| ReactiveContext::new(None));
let task = use_signal(|| {
let mut cb = use_callback(move || {
// Create the user's task
let fut = future();
let fut = rc.run_in(|| future());
// Spawn a wrapper task that polls the innner future and watch its dependencies
let task = spawn(async move {
// // move the future here and pin it so we can poll it
// let fut = fut;
// pin_mut!(fut);
spawn(async move {
// move the future here and pin it so we can poll it
let fut = fut;
pin_mut!(fut);
// let res = future::poll_fn(|cx| {
// // Set the effect stack properly
// // add any dependencies to the effect stack that we need to watch when restarting the future
// // Poll the inner future
// fut.poll_unpin(cx)
// })
// .await;
// Run each poll in the context of the reactive scope
// This ensures the scope is properly subscribed to the future's dependencies
let res = future::poll_fn(|cx| rc.run_in(|| fut.poll_unpin(cx))).await;
// // Set the value
// value.set(Some(Signal::new(res)));
});
// Set the value and state
state.set(UseResourceState::Complete);
value.set(Some(Signal::new(res)));
})
});
Some(task)
let mut task = use_hook(|| Signal::new(cb.call()));
use_hook(|| {
spawn(async move {
loop {
// Wait for the dependencies to change
rc.changed().await;
// Stop the old task
task.write().cancel();
// Start a new task
task.set(cb.call());
}
})
});
AsyncMemo { task, value, state }
@@ -52,8 +65,8 @@ where
#[allow(unused)]
pub struct AsyncMemo<T: 'static> {
value: Signal<Option<Signal<T>>>,
task: Signal<Option<Task>>,
state: Signal<UseResourceState<T>>,
task: Signal<Task>,
state: Signal<UseResourceState>,
}
impl<T> AsyncMemo<T> {
@@ -93,7 +106,7 @@ impl<T> AsyncMemo<T> {
}
/// Get the current state of the future.
pub fn state(&self) -> UseResourceState<T> {
pub fn state(&self) -> UseResourceState {
todo!()
// match (&self.task.get(), &self.value()) {
// // If we have a task and an existing value, we're reloading
@@ -121,8 +134,8 @@ impl<T> AsyncMemo<T> {
}
}
pub enum UseResourceState<T: 'static> {
pub enum UseResourceState {
Pending,
Complete(Signal<T>),
Regenerating(Signal<T>), // the old value
Complete,
Regenerating, // the old value
}