mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-23 12:43:08 +00:00
fix use_future todos!
This commit is contained in:
parent
f44b72f5e1
commit
8a38a41512
2 changed files with 66 additions and 52 deletions
|
@ -24,7 +24,7 @@ where
|
||||||
flush_sync().await;
|
flush_sync().await;
|
||||||
state.set(UseFutureState::Pending);
|
state.set(UseFutureState::Pending);
|
||||||
fut.await;
|
fut.await;
|
||||||
state.set(UseFutureState::Complete);
|
state.set(UseFutureState::Ready);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ pub enum UseFutureState {
|
||||||
Paused,
|
Paused,
|
||||||
|
|
||||||
/// The future has completed
|
/// The future has completed
|
||||||
Complete,
|
Ready,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UseFuture {
|
impl UseFuture {
|
||||||
|
@ -118,7 +118,7 @@ impl UseFuture {
|
||||||
pub fn finished(&self) -> bool {
|
pub fn finished(&self) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
self.state.peek().clone(),
|
self.state.peek().clone(),
|
||||||
UseFutureState::Complete | UseFutureState::Stopped
|
UseFutureState::Ready | UseFutureState::Stopped
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#![allow(missing_docs)]
|
#![allow(missing_docs)]
|
||||||
|
|
||||||
use crate::{use_callback, use_signal};
|
use crate::{use_callback, use_signal, UseCallback};
|
||||||
use dioxus_core::{
|
use dioxus_core::{
|
||||||
prelude::{flush_sync, spawn, suspend, use_hook},
|
prelude::{spawn, suspend, use_hook},
|
||||||
Task,
|
Task,
|
||||||
};
|
};
|
||||||
use dioxus_signals::*;
|
use dioxus_signals::*;
|
||||||
|
@ -59,7 +59,12 @@ where
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
Resource { task, value, state }
|
Resource {
|
||||||
|
task,
|
||||||
|
value,
|
||||||
|
state,
|
||||||
|
callback: cb,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
@ -67,6 +72,24 @@ pub struct Resource<T: 'static> {
|
||||||
value: Signal<Option<Signal<T>>>,
|
value: Signal<Option<Signal<T>>>,
|
||||||
task: Signal<Task>,
|
task: Signal<Task>,
|
||||||
state: Signal<UseResourceState>,
|
state: Signal<UseResourceState>,
|
||||||
|
callback: UseCallback<Task>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A signal that represents the state of a future
|
||||||
|
// we might add more states (panicked, etc)
|
||||||
|
#[derive(Clone, Copy, PartialEq, Hash, Eq, Debug)]
|
||||||
|
pub enum UseResourceState {
|
||||||
|
/// The future is still running
|
||||||
|
Pending,
|
||||||
|
|
||||||
|
/// The future has been forcefully stopped
|
||||||
|
Stopped,
|
||||||
|
|
||||||
|
/// The future has been paused, tempoarily
|
||||||
|
Paused,
|
||||||
|
|
||||||
|
/// The future has completed
|
||||||
|
Ready,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Resource<T> {
|
impl<T> Resource<T> {
|
||||||
|
@ -74,71 +97,62 @@ impl<T> Resource<T> {
|
||||||
///
|
///
|
||||||
/// Will not cancel the previous future, but will ignore any values that it
|
/// Will not cancel the previous future, but will ignore any values that it
|
||||||
/// generates.
|
/// generates.
|
||||||
pub fn restart(&self) {
|
pub fn restart(&mut self) {
|
||||||
// self.needs_regen.set(true);
|
self.task.write().cancel();
|
||||||
// (self.update)();
|
let new_task = self.callback.call();
|
||||||
|
self.task.set(new_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Forcefully cancel a future
|
/// Forcefully cancel a future
|
||||||
pub fn cancel(&self) {
|
pub fn cancel(&mut self) {
|
||||||
// if let Some(task) = self.task.take() {
|
self.state.set(UseResourceState::Stopped);
|
||||||
// cx.remove_future(task);
|
self.task.write().cancel();
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Manually set the value in the future slot without starting the future over
|
/// Pause the future
|
||||||
pub fn set(&mut self, new_value: T) {
|
pub fn pause(&mut self) {
|
||||||
// if let Some(task) = self.task.take() {
|
self.state.set(UseResourceState::Paused);
|
||||||
// cx.remove_future(task);
|
self.task.write().pause();
|
||||||
// }
|
|
||||||
// self.value.set(Some(new_value));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return any value, even old values if the future has not yet resolved.
|
/// Resume the future
|
||||||
|
pub fn resume(&mut self) {
|
||||||
|
if self.finished() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.state.set(UseResourceState::Pending);
|
||||||
|
self.task.write().resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a handle to the inner task backing this future
|
||||||
|
/// Modify the task through this handle will cause inconsistent state
|
||||||
|
pub fn task(&self) -> Task {
|
||||||
|
self.task.cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Is the future currently finished running?
|
||||||
///
|
///
|
||||||
/// If the future has never completed, the returned value will be `None`.
|
/// Reading this does not subscribe to the future's state
|
||||||
pub fn value(&self) -> Option<ReadOnlySignal<T>> {
|
pub fn finished(&self) -> bool {
|
||||||
self.value.cloned().map(|sig| sig.into())
|
matches!(
|
||||||
}
|
self.state.peek().clone(),
|
||||||
|
UseResourceState::Ready | UseResourceState::Stopped
|
||||||
/// Get the ID of the future in Dioxus' internal scheduler
|
)
|
||||||
pub fn task(&self) -> Option<Task> {
|
|
||||||
todo!()
|
|
||||||
// self.task.get()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the current state of the future.
|
/// Get the current state of the future.
|
||||||
pub fn state(&self) -> UseResourceState {
|
pub fn state(&self) -> ReadOnlySignal<UseResourceState> {
|
||||||
todo!()
|
self.state.clone().into()
|
||||||
// match (&self.task.get(), &self.value()) {
|
|
||||||
// // If we have a task and an existing value, we're reloading
|
|
||||||
// (Some(_), Some(val)) => UseResourceState::Reloading(val),
|
|
||||||
|
|
||||||
// // no task, but value - we're done
|
|
||||||
// (None, Some(val)) => UseResourceState::Complete(val),
|
|
||||||
|
|
||||||
// // no task, no value - something's wrong? return pending
|
|
||||||
// (None, None) => UseResourceState::Pending,
|
|
||||||
|
|
||||||
// // Task, no value - we're still pending
|
|
||||||
// (Some(_), None) => UseResourceState::Pending,
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wait for this async memo to resolve, returning the inner signal value
|
/// Wait for this async memo to resolve, returning the inner signal value
|
||||||
/// If the value is pending, returns none and suspends the current component
|
/// If the value is pending, returns none and suspends the current component
|
||||||
pub fn suspend(&self) -> Option<ReadOnlySignal<T>> {
|
pub fn suspend(&self) -> Option<ReadOnlySignal<T>> {
|
||||||
let out = self.value();
|
let out = self.value.read().clone();
|
||||||
if out.is_none() {
|
if out.is_none() {
|
||||||
suspend();
|
suspend();
|
||||||
}
|
}
|
||||||
out.map(|sig| sig.into())
|
out.map(|sig| sig.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
|
||||||
pub enum UseResourceState {
|
|
||||||
Pending,
|
|
||||||
Ready,
|
|
||||||
Regenerating, // the old value
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue