diff --git a/packages/desktop/src/hooks.rs b/packages/desktop/src/hooks.rs index b34bfe6e6..39f361950 100644 --- a/packages/desktop/src/hooks.rs +++ b/packages/desktop/src/hooks.rs @@ -71,13 +71,13 @@ pub fn use_asset_handler( /// Get a closure that executes any JavaScript in the WebView context. pub fn use_global_shortcut( accelerator: impl IntoAccelerator, - handler: impl FnMut() + 'static, + mut handler: impl FnMut() + 'static, ) -> Result { // wrap the user's handler in something that will carry the scope/runtime with it - let cb = use_callback(handler); + let cb = use_callback(move |_| handler()); use_hook_with_cleanup( - move || window().create_shortcut(accelerator.accelerator(), move || cb.call()), + move || window().create_shortcut(accelerator.accelerator(), move || cb.call(())), |handle| { if let Ok(handle) = handle { handle.remove(); diff --git a/packages/hooks/src/use_callback.rs b/packages/hooks/src/use_callback.rs index dfb90429e..954de11c5 100644 --- a/packages/hooks/src/use_callback.rs +++ b/packages/hooks/src/use_callback.rs @@ -10,7 +10,7 @@ use dioxus_signals::Writable; /// /// This API is in flux and might not remain. #[doc = include_str!("../docs/rules_of_hooks.md")] -pub fn use_callback(f: impl FnMut() -> O + 'static) -> UseCallback { +pub fn use_callback(f: impl FnMut(T) -> O + 'static) -> UseCallback { // Create a copyvalue with no contents // This copyvalue is generic over F so that it can be sized properly let mut inner = use_hook(|| CopyValue::new(None)); @@ -24,9 +24,10 @@ pub fn use_callback(f: impl FnMut() -> O + 'static) -> UseCallback { let rt = Runtime::current().unwrap(); UseCallback { - inner: CopyValue::new(Box::new(move || { + inner: CopyValue::new(Box::new(move |value| { // run this callback in the context of the scope it was created in. - let run_callback = || inner.with_mut(|f: &mut Option<_>| f.as_mut().unwrap()()); + let run_callback = + || inner.with_mut(|f: &mut Option<_>| f.as_mut().unwrap()(value)); rt.on_scope(cur_scope, run_callback) })), } @@ -36,17 +37,17 @@ pub fn use_callback(f: impl FnMut() -> O + 'static) -> UseCallback { /// This callback is not generic over a return type so you can hold a bunch of callbacks at once /// /// If you need a callback that returns a value, you can simply wrap the closure you pass in that sets a value in its scope -pub struct UseCallback { - inner: CopyValue O>>, +pub struct UseCallback { + inner: CopyValue O>>, } -impl PartialEq for UseCallback { +impl PartialEq for UseCallback { fn eq(&self, other: &Self) -> bool { self.inner == other.inner } } -impl std::fmt::Debug for UseCallback { +impl std::fmt::Debug for UseCallback { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("UseCallback") .field("inner", &self.inner.value()) @@ -54,23 +55,23 @@ impl std::fmt::Debug for UseCallback { } } -impl Clone for UseCallback { +impl Clone for UseCallback { fn clone(&self) -> Self { Self { inner: self.inner } } } -impl Copy for UseCallback {} +impl Copy for UseCallback {} -impl UseCallback { +impl UseCallback { /// Call the callback - pub fn call(&self) -> O { - (self.inner.write_unchecked())() + pub fn call(&self, value: T) -> O { + (self.inner.write_unchecked())(value) } } // This makes UseCallback callable like a normal function -impl std::ops::Deref for UseCallback { - type Target = dyn Fn() -> O; +impl std::ops::Deref for UseCallback { + type Target = dyn Fn(T) -> O; fn deref(&self) -> &Self::Target { use std::mem::MaybeUninit; @@ -80,7 +81,7 @@ impl std::ops::Deref for UseCallback { // First we create a closure that captures something with the Same in memory layout as Self (MaybeUninit). let uninit_callable = MaybeUninit::::uninit(); // Then move that value into the closure. We assume that the closure now has a in memory layout of Self. - let uninit_closure = move || Self::call(unsafe { &*uninit_callable.as_ptr() }); + let uninit_closure = move |value| Self::call(unsafe { &*uninit_callable.as_ptr() }, value); // Check that the size of the closure is the same as the size of Self in case the compiler changed the layout of the closure. let size_of_closure = std::mem::size_of_val(&uninit_closure); diff --git a/packages/hooks/src/use_effect.rs b/packages/hooks/src/use_effect.rs index cf911f63e..e88c2ee52 100644 --- a/packages/hooks/src/use_effect.rs +++ b/packages/hooks/src/use_effect.rs @@ -8,8 +8,8 @@ use crate::use_callback; #[doc = include_str!("../docs/side_effects.md")] #[doc = include_str!("../docs/rules_of_hooks.md")] #[track_caller] -pub fn use_effect(callback: impl FnMut() + 'static) -> Effect { - let callback = use_callback(callback); +pub fn use_effect(mut callback: impl FnMut() + 'static) -> Effect { + let callback = use_callback(move |_| callback()); let location = std::panic::Location::caller(); @@ -31,7 +31,7 @@ pub fn use_effect(callback: impl FnMut() + 'static) -> Effect { effect_queued.set(true); let effect_queued = effect_queued.clone(); queue_effect(move || { - rc.reset_and_run_in(&*callback); + rc.reset_and_run_in(|| callback(())); effect_queued.set(false); }); }; diff --git a/packages/hooks/src/use_future.rs b/packages/hooks/src/use_future.rs index 430b215de..ef0d2f868 100644 --- a/packages/hooks/src/use_future.rs +++ b/packages/hooks/src/use_future.rs @@ -48,7 +48,7 @@ where { let mut state = use_signal(|| UseFutureState::Pending); - let callback = use_callback(move || { + let callback = use_callback(move |_| { let fut = future(); spawn(async move { state.set(UseFutureState::Pending); @@ -58,7 +58,7 @@ where }); // Create the task inside a CopyValue so we can reset it in-place later - let task = use_hook(|| CopyValue::new(callback.call())); + let task = use_hook(|| CopyValue::new(callback(()))); // Early returns in dioxus have consequences for use_memo, use_resource, and use_future, etc // We *don't* want futures to be running if the component early returns. It's a rather weird behavior to have @@ -82,7 +82,7 @@ where pub struct UseFuture { task: CopyValue, state: Signal, - callback: UseCallback, + callback: UseCallback<(), Task>, } /// A signal that represents the state of a future @@ -109,7 +109,7 @@ impl UseFuture { /// generates. pub fn restart(&mut self) { self.task.write().cancel(); - let new_task = self.callback.call(); + let new_task = self.callback.call(()); self.task.set(new_task); } diff --git a/packages/hooks/src/use_memo.rs b/packages/hooks/src/use_memo.rs index 34586126d..467795a95 100644 --- a/packages/hooks/src/use_memo.rs +++ b/packages/hooks/src/use_memo.rs @@ -6,8 +6,8 @@ use dioxus_signals::{Memo, Signal}; #[doc = include_str!("../docs/rules_of_hooks.md")] #[doc = include_str!("../docs/moving_state_around.md")] #[track_caller] -pub fn use_memo(f: impl FnMut() -> R + 'static) -> Memo { - let callback = use_callback(f); +pub fn use_memo(mut f: impl FnMut() -> R + 'static) -> Memo { + let callback = use_callback(move |_| f()); #[allow(clippy::redundant_closure)] - use_hook(|| Signal::memo(move || callback())) + use_hook(|| Signal::memo(move || callback(()))) } diff --git a/packages/hooks/src/use_resource.rs b/packages/hooks/src/use_resource.rs index ed52d7029..c3f031640 100644 --- a/packages/hooks/src/use_resource.rs +++ b/packages/hooks/src/use_resource.rs @@ -28,7 +28,7 @@ where (rc, Rc::new(Cell::new(Some(changed)))) }); - let cb = use_callback(move || { + let cb = use_callback(move |_| { // Create the user's task let fut = rc.reset_and_run_in(&mut future); @@ -54,7 +54,7 @@ where }) }); - let mut task = use_hook(|| Signal::new(cb())); + let mut task = use_hook(|| Signal::new(cb(()))); use_hook(|| { let mut changed = changed.take().unwrap(); @@ -67,7 +67,7 @@ where task.write().cancel(); // Start a new task - task.set(cb()); + task.set(cb(())); } }) }); @@ -110,7 +110,7 @@ pub struct Resource { value: Signal>, task: Signal, state: Signal, - callback: UseCallback, + callback: UseCallback<(), Task>, } impl PartialEq for Resource { @@ -174,7 +174,7 @@ impl Resource { /// ``` pub fn restart(&mut self) { self.task.write().cancel(); - let new_task = self.callback.call(); + let new_task = self.callback.call(()); self.task.set(new_task); }