use crate::{
base::PrependErrorString,
sys::Key
};
use super::{
ERR_ALREADY_SET,
ERR_NOT_SET_CANNOT_FINISH,
ERR_NOT_SET_CANNOT_RUN,
Context,
Master
};
const MID: &str = "Sync";
const AUTOSAVE_INTERVAL: i128 = 60 * 60 * 1_000_000;
pub enum MSync {
Unset,
Set {
time_before_last_pause: i128,
last_resume_instant: i128,
last_autosave_time: i128,
}
}
impl MSync {
pub fn new() -> Box<Self> {
Box::new(Self::Unset)
}
}
impl Master for MSync {
fn id(&self) -> String {
String::from(MID)
}
fn start(&mut self, Context{sys, state, ..}: &mut Context) -> Result<(), String> {
match self {
Self::Unset => {
*self = Self::Set {
time_before_last_pause: state.playtime,
last_resume_instant: sys.now(),
last_autosave_time: state.playtime
};
sys.resume_audio();
Ok(())
},
Self::Set{..} => Err(format!("{} {}", MID, ERR_ALREADY_SET))
}
}
fn run(&mut self, Context{sys, state, ether, ..}: &mut Context) -> Result<(), String> {
match self {
&mut Self::Set{ref mut time_before_last_pause, ref mut last_resume_instant, ref mut last_autosave_time} => {
if ether.paused { *time_before_last_pause = state.playtime;
*last_resume_instant = sys.now();
ether.paused = false;
sys.resume_audio();
}
sys.sync()?;
let time_after_last_resume = sys.now() - (*last_resume_instant);
state.playtime = (*time_before_last_pause) + time_after_last_resume;
if state.playtime - (*last_autosave_time) > AUTOSAVE_INTERVAL {
state.save().pre_err("cannot save state to autosave")?;
*last_autosave_time = state.playtime;
}
if sys.poll_key(Key::V) {
sys.set_draw_suspend(!sys.draw_suspended());
}
Ok(())
},
Self::Unset => Err(format!("{} {}", MID, ERR_NOT_SET_CANNOT_RUN))
}
}
fn finish(&mut self, Context{sys, ..}: &mut Context) -> Result<(), String> {
match self {
Self::Set{..} => {
sys.halt_audio();
Ok(())
},
Self::Unset => Err(format!("{} {}", MID, ERR_NOT_SET_CANNOT_FINISH))
}
}
}