Hi there! I'm building a timer application using Tauri, and I'm trying to run a future in background, but I'm having troubles with being able to (1) stop the future when I stop the timer, (2) use self inside the interval.
I'll paste my current code below, but I also want to understand if there's a better way of doing what I'm trying to do. My initial attempt was working, but I had a timer future running all the time and I'd pass it to my AppState, which was fine, but I wasn't able to synchronize the start with the UI (since the timer was always running, I could start counting the time in between seconds).
This is some sort of diagram of my app:
And here's my latest attempt at getting the timer running from inside the app state
use core::time::Duration;
use std::sync::Arc;
use tokio::task::JoinHandle;
use core::sync::atomic::AtomicI32;
pub struct AppState {
pub time: AtomicI32,
timer_handle: Option<JoinHandle<()>>,
}
impl AppState {
pub fn new() -> Self {
Self {
time: AtomicI32::new(0),
timer_handle: None,
}
}
pub async fn start(mut self) {
let handle = tokio::spawn(async move {
let mut interval = tokio::time::interval(Duration::from_secs(1));
loop {
interval.tick().await;
self.tick().await;
}
});
self.timer_handle = Some(handle);
}
pub async fn tick(self) {
println!("Ticking...")
}
}
fn main() {
println!("Hello, world!");
let app_state = AppState::new();
app_state.start();
}
Errors:
Compiling playground v0.0.1 (/playground)
warning: unused import: `std::sync::Arc`
--> src/main.rs:2:5
|
2 | use std::sync::Arc;
| ^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
error[E0382]: use of moved value: `self`
--> src/main.rs:26:17
|
26 | self.tick().await;
| ^^^^ ------ `self` moved due to this method call, in previous iteration of loop
|
note: this function takes ownership of the receiver `self`, which moves `self`
--> src/main.rs:33:23
|
33 | pub async fn tick(self) {
| ^^^^
= note: move occurs because `self` has type `AppState`, which does not implement the `Copy` trait
error[E0382]: assign to part of moved value: `self`
--> src/main.rs:30:9
|
19 | pub async fn start(mut self) {
| -------- move occurs because `self` has type `AppState`, which does not implement the `Copy` trait
20 | let handle = tokio::spawn(async move {
| ______________________________________________-
21 | | let mut interval = tokio::time::interval(Duration::from_secs(1));
22 | |
23 | | loop {
... |
26 | | self.tick().await;
| | ---- variable moved due to use in generator
27 | | }
28 | | });
| |_________- value moved here
29 |
30 | self.timer_handle = Some(handle);
| ^^^^^^^^^^^^^^^^^ value partially assigned here after move
For more information about this error, try `rustc --explain E0382`.
warning: `playground` (bin "playground") generated 1 warning
error: could not compile `playground` due to 2 previous errors; 1 warning emitted