То, что вы хотите, настолько просто, что вам даже не нужно, чтобы оно было изменяемым каким-либо образом, и тогда становится простым делить его между потоками, если вы не хотите сбросить его. Вы сказали, что по той или иной причине вам необходимо покинуть поток, поэтому я предполагаю, что вас это не волнует.
Вместо этого вы можете опрашивать его каждый тик (большинство игр запускаются по тикам, поэтому яне думаю, что возникнут какие-либо проблемы с его реализацией).
Я приведу пример, который использует сон, так что это не самая точная вещь, это болезненно очевидно в последнюю секунду, но я не пытаюсьВ любом случае, делайте свою работу за вас, в Интернете достаточно ресурсов, которые помогут вам справиться с этим.
Вот так:
use std::{
sync::Arc,
thread::{self, Result},
time::{Duration, Instant},
};
struct Timer {
end: Instant,
}
impl Timer {
fn new(duration: Duration) -> Self {
// this code is valid for now, but might break in the future
// future so distant, that you really don't need to care unless
// you let your players draw for eternity
let end = Instant::now().checked_add(duration).unwrap();
Timer { end }
}
fn left(&self) -> Duration {
self.end.saturating_duration_since(Instant::now())
}
// more usable than above with fractional value being accounted for
fn secs_left(&self) -> u64 {
let span = self.left();
span.as_secs() + if span.subsec_millis() > 0 { 1 } else { 0 }
}
}
fn main() -> Result<()> {
let timer = Timer::new(Duration::from_secs(10));
let timer_main = Arc::new(timer);
let timer = timer_main.clone();
let t = thread::spawn(move || loop {
let seconds_left = timer.secs_left();
println!("[Worker] Seconds left: {}", seconds_left);
if seconds_left == 0 {
break;
}
thread::sleep(Duration::from_secs(1));
});
loop {
let seconds_left = timer_main.secs_left();
println!("[Main] Seconds left: {}", seconds_left);
if seconds_left == 5 {
println!("[Main] 5 seconds left, waiting for worker thread to finish work.");
break;
}
thread::sleep(Duration::from_secs(1));
}
t.join()?;
println!("[Main] worker thread finished work, shutting down!");
Ok(())
}
Кстати, такого рода реализация не будетбыть другим на любом другом языке, поэтому, пожалуйста, не вините в этом Руста. Это не самый простой язык, но он предоставляет более чем достаточно инструментов для создания чего угодно с нуля, если приложить к этому усилия.
Goodluck:)