Сохранить ссылку на timer :: guard в структуре - PullRequest
0 голосов
/ 23 января 2019

Я пытаюсь реализовать структуру, которая отслеживает глобальный тик. В попытке изменить рефакторинг я переместил timer в структуру, но теперь я сталкиваюсь с проблемой потери ссылки timer guard и, следовательно, сброса таймера. Я думал о том, чтобы добавить охрану в качестве члена структуры, но я не уверен, как это сделать.

use timer;
use chrono;
use futures::Future;
use std::{process, thread};
use std::sync::{Arc, Mutex};

struct GlobalTime {
    tick_count: Arc<Mutex<u64>>,
    millis: Arc<Mutex<i64>>,
    timer: timer::Timer,
    guard: timer::Guard,
}

impl GlobalTime {
    fn new() -> GlobalTime {
        GlobalTime {
            tick_count: Arc::new(Mutex::new(0)),
            millis: Arc::new(Mutex::new(200)),
            timer: timer::Timer::new(),
            guard: ???, // what do I do here to init the guard??
        }
    }

    fn tick(&self) {
        *self.guard = {
            let global_tick = self.tick_count.clone();
            self.timer.schedule_repeating(
                chrono::Duration::milliseconds(*self.millis.lock().unwrap()),
                move || {
                    *global_tick.lock().unwrap() += 1;
                    println!("timer callback");
                },
            );
        }
    }
}

1 Ответ

0 голосов
/ 24 января 2019

Учитывая, что таймер не всегда работает в течение времени жизни GlobalTime, не всегда допустимое значение для guard.Мы обычно моделируем эту идею с помощью Option:

struct GlobalTime {
    tick_count: Arc<Mutex<u64>>,
    millis: Arc<Mutex<i64>>,
    timer: timer::Timer,
    guard: Option<timer::Guard>,
}

, которая также решает вашу проблему относительно начального значения, потому что оно Option::None:

impl GlobalTime {
    fn new() -> GlobalTime {
        GlobalTime {
            tick_count: Arc::new(Mutex::new(0)),
            millis: Arc::new(Mutex::new(200)),
            timer: timer::Timer::new(),
            guard: None,
        }
    }
}

tick метод становится:

fn tick(&mut self) {
    let global_tick = self.tick_count.clone();
    let guard = self.timer.schedule_repeating(
        chrono::Duration::milliseconds(*self.millis.lock().unwrap()),
        move || {
            *global_tick.lock().unwrap() += 1;
            println!("timer callback");
        },
    );
    self.guard = Some(guard);
}

Чтобы остановить таймер, вы можете просто установить значение защиты на Option::None:

fn stop(&mut self) {
    self.guard = None;
}
...