Просмотр исходного кода

`once_global` and `once` accept FnOnce callbacks (#3383)

Jonas Kruckenberg 3 лет назад
Родитель
Сommit
d5400a3d62

+ 5 - 0
.changes/fix-once-fnonce.md

@@ -0,0 +1,5 @@
+---
+"tauri": patch
+---
+
+`Manager::once_global` and `Window::once` allow `FnOnce` callbacks.

+ 8 - 2
core/tauri/src/event.rs

@@ -4,6 +4,7 @@
 
 use std::{
   boxed::Box,
+  cell::Cell,
   collections::HashMap,
   fmt,
   hash::Hash,
@@ -170,16 +171,21 @@ impl Listeners {
   }
 
   /// Listen to a JS event and immediately unlisten.
-  pub(crate) fn once<F: Fn(Event) + Send + 'static>(
+  pub(crate) fn once<F: FnOnce(Event) + Send + 'static>(
     &self,
     event: String,
     window: Option<String>,
     handler: F,
   ) -> EventHandler {
     let self_ = self.clone();
+    let handler = Cell::new(Some(handler));
+
     self.listen(event, window, move |event| {
       self_.unlisten(event.id);
-      handler(event);
+      let handler = handler
+        .take()
+        .expect("attempted to call handler more than once");
+      handler(event)
     })
   }
 

+ 1 - 1
core/tauri/src/lib.rs

@@ -427,7 +427,7 @@ pub trait Manager<R: Runtime>: sealed::ManagerBase<R> {
   /// Listen to a global event only once.
   fn once_global<F>(&self, event: impl Into<String>, handler: F) -> EventHandler
   where
-    F: Fn(Event) + Send + 'static,
+    F: FnOnce(Event) + Send + 'static,
   {
     self.manager().once(event.into(), None, handler)
   }

+ 1 - 1
core/tauri/src/manager.rs

@@ -1176,7 +1176,7 @@ impl<R: Runtime> WindowManager<R> {
     self.inner.listeners.listen(event, window, handler)
   }
 
-  pub fn once<F: Fn(Event) + Send + 'static>(
+  pub fn once<F: FnOnce(Event) + Send + 'static>(
     &self,
     event: String,
     window: Option<String>,

+ 0 - 1
core/tauri/src/updater/mod.rs

@@ -480,7 +480,6 @@ pub(crate) fn listener<R: Runtime>(
             window.once(EVENT_INSTALL_UPDATE, move |_msg| {
               let window = window_isolation.clone();
               let updater = updater.clone();
-              let pubkey = pubkey.clone();
 
               // Start installation
               crate::async_runtime::spawn(async move {

+ 1 - 1
core/tauri/src/window.rs

@@ -321,7 +321,7 @@ impl<R: Runtime> Window<R> {
   /// Listen to an event on this window a single time.
   pub fn once<F>(&self, event: impl Into<String>, handler: F) -> EventHandler
   where
-    F: Fn(Event) + Send + 'static,
+    F: FnOnce(Event) + Send + 'static,
   {
     let label = self.window.label.clone();
     self.manager.once(event.into(), Some(label), handler)