diff --git a/examples/compose.rs b/examples/compose.rs index 4206383d3..4b6a7450c 100644 --- a/examples/compose.rs +++ b/examples/compose.rs @@ -19,8 +19,7 @@ fn app(cx: Scope) -> Element { emails_sent.write().push(message); } } - }) - .unwrap(); + }); cx.render(rsx! { div { diff --git a/packages/core/src/scheduler/task.rs b/packages/core/src/scheduler/task.rs index 7f6ae8021..bf1075688 100644 --- a/packages/core/src/scheduler/task.rs +++ b/packages/core/src/scheduler/task.rs @@ -33,11 +33,7 @@ impl Scheduler { /// /// Spawning a future onto the root scope will cause it to be dropped when the root component is dropped - which /// will only occur when the VirtuaalDom itself has been dropped. - pub fn spawn( - &self, - scope: ScopeId, - task: impl Future + 'static, - ) -> Option { + pub fn spawn(&self, scope: ScopeId, task: impl Future + 'static) -> TaskId { let mut tasks = self.tasks.borrow_mut(); let entry = tasks.vacant_entry(); @@ -53,9 +49,7 @@ impl Scheduler { }; let mut cx = std::task::Context::from_waker(&task.waker); - if task.task.borrow_mut().as_mut().poll(&mut cx).is_ready() { - return None; - } + let _ = task.task.borrow_mut().as_mut().poll(&mut cx); entry.insert(task); @@ -63,7 +57,7 @@ impl Scheduler { .unbounded_send(SchedulerMsg::TaskNotified(task_id)) .expect("Scheduler should exist"); - Some(task_id) + task_id } /// Drop the future with the given TaskId diff --git a/packages/core/src/scope_context.rs b/packages/core/src/scope_context.rs index 45df068f4..59bed3b1f 100644 --- a/packages/core/src/scope_context.rs +++ b/packages/core/src/scope_context.rs @@ -214,10 +214,10 @@ impl ScopeContext { } /// Pushes the future onto the poll queue to be polled after the component renders. - pub fn push_future(&self, fut: impl Future + 'static) -> Option { - let id = self.tasks.spawn(self.id, fut)?; + pub fn push_future(&self, fut: impl Future + 'static) -> TaskId { + let id = self.tasks.spawn(self.id, fut); self.spawned_tasks.borrow_mut().insert(id); - Some(id) + id } /// Spawns the future but does not return the [`TaskId`] @@ -228,9 +228,9 @@ impl ScopeContext { /// Spawn a future that Dioxus won't clean up when this component is unmounted /// /// This is good for tasks that need to be run after the component has been dropped. - pub fn spawn_forever(&self, fut: impl Future + 'static) -> Option { + pub fn spawn_forever(&self, fut: impl Future + 'static) -> TaskId { // The root scope will never be unmounted so we can just add the task at the top of the app - let id = self.tasks.spawn(ScopeId::ROOT, fut)?; + let id = self.tasks.spawn(ScopeId::ROOT, fut); // wake up the scheduler if it is sleeping self.tasks @@ -240,7 +240,7 @@ impl ScopeContext { self.spawned_tasks.borrow_mut().insert(id); - Some(id) + id } /// Informs the scheduler that this task is no longer needed and should be removed. @@ -339,7 +339,7 @@ pub fn throw(error: impl Debug + 'static) -> Option<()> { /// Pushes the future onto the poll queue to be polled after the component renders. pub fn push_future(fut: impl Future + 'static) -> Option { - with_current_scope(|cx| cx.push_future(fut)).flatten() + with_current_scope(|cx| cx.push_future(fut)) } /// Spawns the future but does not return the [`TaskId`] @@ -351,7 +351,7 @@ pub fn spawn(fut: impl Future + 'static) { /// /// This is good for tasks that need to be run after the component has been dropped. pub fn spawn_forever(fut: impl Future + 'static) -> Option { - with_current_scope(|cx| cx.spawn_forever(fut)).flatten() + with_current_scope(|cx| cx.spawn_forever(fut)) } /// Informs the scheduler that this task is no longer needed and should be removed. diff --git a/packages/core/src/scopes.rs b/packages/core/src/scopes.rs index 463217370..f0bbd776c 100644 --- a/packages/core/src/scopes.rs +++ b/packages/core/src/scopes.rs @@ -309,7 +309,7 @@ impl<'src> ScopeState { } /// Pushes the future onto the poll queue to be polled after the component renders. - pub fn push_future(&self, fut: impl Future + 'static) -> Option { + pub fn push_future(&self, fut: impl Future + 'static) -> TaskId { self.context().push_future(fut) } @@ -321,7 +321,7 @@ impl<'src> ScopeState { /// Spawn a future that Dioxus won't clean up when this component is unmounted /// /// This is good for tasks that need to be run after the component has been dropped. - pub fn spawn_forever(&self, fut: impl Future + 'static) -> Option { + pub fn spawn_forever(&self, fut: impl Future + 'static) -> TaskId { self.context().spawn_forever(fut) } diff --git a/packages/fullstack/src/hooks/server_future.rs b/packages/fullstack/src/hooks/server_future.rs index 8d9f09f71..f8eaef963 100644 --- a/packages/fullstack/src/hooks/server_future.rs +++ b/packages/fullstack/src/hooks/server_future.rs @@ -76,7 +76,7 @@ where cx.remove_future(current); } - state.task.set(cx.push_future(async move { + state.task.set(Some(cx.push_future(async move { let data; #[cfg(feature = "ssr")] { @@ -94,7 +94,7 @@ where *value.borrow_mut() = Some(Box::new(data)); schedule_update(); - })); + }))); } if first_run { diff --git a/packages/hooks/src/use_coroutine.rs b/packages/hooks/src/use_coroutine.rs index 6de43a667..8d2212162 100644 --- a/packages/hooks/src/use_coroutine.rs +++ b/packages/hooks/src/use_coroutine.rs @@ -63,15 +63,15 @@ use std::future::Future; /// } /// }) /// ``` -pub fn use_coroutine(cx: &ScopeState, init: G) -> Option<&Coroutine> +pub fn use_coroutine(cx: &ScopeState, init: G) -> &Coroutine where M: 'static, G: FnOnce(UnboundedReceiver) -> F, F: Future + 'static, { let (tx, rx) = futures_channel::mpsc::unbounded(); - let task = cx.push_future(init(rx))?; - Some(cx.use_hook(|| cx.provide_context(Coroutine { tx, task }))) + let task = cx.push_future(init(rx)); + cx.use_hook(|| cx.provide_context(Coroutine { tx, task })) } /// Get a handle to a coroutine higher in the tree diff --git a/packages/hooks/src/use_effect.rs b/packages/hooks/src/use_effect.rs index 49d8c6dd4..72744e8ae 100644 --- a/packages/hooks/src/use_effect.rs +++ b/packages/hooks/src/use_effect.rs @@ -99,9 +99,8 @@ where // Create the new future let return_value = future(dependencies.out()); - if let Some(task) = return_value.apply(state.cleanup.clone(), cx) { - state.task.set(Some(task)); - } + let task = return_value.apply(state.cleanup.clone(), cx); + state.task.set(Some(task)); } } @@ -109,14 +108,14 @@ type UseEffectCleanup = Rc>>>; /// Something that can be returned from a `use_effect` hook. pub trait UseEffectReturn { - fn apply(self, oncleanup: UseEffectCleanup, cx: &ScopeState) -> Option; + fn apply(self, oncleanup: UseEffectCleanup, cx: &ScopeState) -> TaskId; } impl UseEffectReturn<()> for T where T: Future + 'static, { - fn apply(self, _: UseEffectCleanup, cx: &ScopeState) -> Option { + fn apply(self, _: UseEffectCleanup, cx: &ScopeState) -> TaskId { cx.push_future(self) } } @@ -128,7 +127,7 @@ where T: Future + 'static, F: FnOnce() + 'static, { - fn apply(self, oncleanup: UseEffectCleanup, cx: &ScopeState) -> Option { + fn apply(self, oncleanup: UseEffectCleanup, cx: &ScopeState) -> TaskId { cx.push_future(async move { let cleanup = self.await; *oncleanup.borrow_mut() = Some(Box::new(cleanup) as Box); diff --git a/packages/hooks/src/use_future.rs b/packages/hooks/src/use_future.rs index d3fdac1bc..b9aa20c31 100644 --- a/packages/hooks/src/use_future.rs +++ b/packages/hooks/src/use_future.rs @@ -49,10 +49,10 @@ where let val = val.clone(); let task = state.task.clone(); - state.task.set(cx.push_future(async move { + state.task.set(Some(cx.push_future(async move { val.set(Some(fut.await)); task.take(); - })); + }))); // Mark that we don't need to regenerate state.needs_regen.set(false);