use crate::base::PrependErrorString;
mod audio;
mod config;
mod input;
mod random;
mod time;
mod video;
mod sys_audio;
mod sys_input;
mod sys_random;
mod sys_time;
mod sys_video;
pub use self::{
audio::{
Music,
Sound
},
input::{
Button,
Key
},
};
pub struct System {
config: Box<self::config::Config>,
time: Box<self::time::System>,
random: Box<self::random::System>,
video: Box<self::video::System>,
draw_suspended: bool,
draw_locked: bool,
last_show_time: i128,
fps: Vec<f64>,
fps_i: usize,
audio: Box<self::audio::System>,
input: Box<self::input::System>
}
impl System {
pub fn init() -> Result<System, String> {
let config = config::Config::load().pre_err("cannot load config")?;
let time = time::System::init().pre_err("cannot init time subsys")?;
let random = random::System::init(&config).pre_err("cannot init random subsys")?;
let sdl = sdl2::init().pre_err("cannot init SDL")?;
let video = video::System::init(&sdl, &config).pre_err("cannot init video subsys")?;
let draw_suspended: bool = false;
let draw_locked: bool = false;
let last_show_time = time.now();
let fps: Vec<f64> = vec![0.0; config.frame_rate as usize];
let fps_i: usize = 0;
let audio = audio::System::init(&config).pre_err("cannot init audio subsys")?;
let input = input::System::init(&sdl, &config).pre_err("cannot init input subsys")?;
Ok(System{
config: Box::new(config),
time: Box::new(time),
random: Box::new(random),
video: Box::new(video),
draw_suspended,
draw_locked,
last_show_time,
fps,
fps_i,
audio: Box::new(audio),
input: Box::new(input)
})
}
pub fn lang(&self) -> String {
self.config.lang.clone()
}
pub fn fps(&self) -> f64 {
self.fps.iter().sum::<f64>() / (self.config.frame_rate as f64)
}
pub fn sync(&mut self) -> Result<(), String> {
self.draw_locked = true;
let now = self.time.now();
let delta = now - self.last_show_time;
if !self.draw_suspended && (delta > 1000000i128 / (self.config.frame_rate as i128)) {
self.video.show().pre_err("cannot sync video")?;
self.fps[self.fps_i] = 1e6 / (delta as f64);
self.fps_i = (self.fps_i + 1) % (self.config.frame_rate as usize);
self.last_show_time = now;
self.draw_locked = false;
}
self.input.sync().pre_err("cannot sync input")?;
Ok(())
}
pub fn draw_suspended(&self) -> bool {
self.draw_suspended
}
pub fn set_draw_suspend(&mut self, suspended: bool) {
self.draw_suspended = suspended;
}
pub fn shut(&mut self) -> Result<(), String> {
self.input.shut().pre_err("cannot shut input subsys")?;
self.audio.shut().pre_err("cannot shut audio subsys")?;
self.video.shut().pre_err("cannot shut video subsys")?;
self.random.shut().pre_err("cannot shut random subsys")?;
self.time.shut().pre_err("cannot shut time subsys")?;
Ok(())
}
}