use time::{PreciseTime, Duration};
use EventDispatcher;
pub trait Frontend<M> {
fn process_events(&mut self, dispatcher: &mut EventDispatcher<M>, model: &mut M);
fn render(&mut self, model: &M);
}
pub struct UpdateEvent {
pub delta: f32
}
pub struct Framework<M, F> {
model: M,
frontend: F,
dispatcher: EventDispatcher<M>,
}
impl<M: 'static, F: Frontend<M>> Framework<M, F> {
pub fn new(model: M, frontend: F, dispatcher: EventDispatcher<M>) -> Self {
Framework {
model: model,
frontend: frontend,
dispatcher: dispatcher,
}
}
pub fn run<RC: Fn(&M) -> bool>(mut self, run_condition: RC) {
let mut last_update = PreciseTime::now();
while run_condition(&self.model) {
let now = PreciseTime::now();
let elapsed = last_update.to(now);
if elapsed > Duration::milliseconds(1) {
let delta = elapsed.num_nanoseconds().unwrap() as f32 / 1_000_000_000.0;
assert!(delta > 0.0);
last_update = now;
self.frontend.process_events(&mut self.dispatcher, &mut self.model);
self.dispatcher.dispatch(&mut self.model, UpdateEvent { delta: delta });
self.frontend.render(&self.model);
} else {
::std::thread::sleep(::std::time::Duration::from_millis(1));
}
}
}
}