Skip to main content

buttery_engine/
engine.rs

1use std::time::Duration;
2use web_time::Instant;
3
4use crate::{
5    game::ButteryGame,
6    key_event::KeyEvent,
7    renderer::{ButteryRenderer, FallbackRenderer},
8    windowing::ButteryWindowingSystem,
9    world_model::ButteryWorldModel,
10};
11
12pub enum ButteryEvent {
13    Init,
14    Update,
15    KeyPress(String),
16}
17
18pub struct ButteryEngineState {
19    pub renderer: Box<dyn ButteryRenderer>,
20    last_frame_time: Instant,
21    pub delta_time: f32,
22    pub world_model: ButteryWorldModel,
23}
24
25pub struct ButteryEngine {
26    pub state: ButteryEngineState,
27    pub game: Box<dyn ButteryGame>,
28}
29
30impl ButteryEngine {
31    pub fn run(
32        windowing_system: Box<dyn ButteryWindowingSystem>,
33        game: Box<dyn ButteryGame>,
34    ) -> anyhow::Result<()> {
35        let engine = Self {
36            game,
37            state: ButteryEngineState {
38                renderer: Box::new(FallbackRenderer {}),
39                delta_time: 1.0 / 60.0,
40                last_frame_time: web_time::Instant::now(),
41                world_model: ButteryWorldModel::default(),
42            },
43        };
44
45        windowing_system.run(engine)
46    }
47
48    pub fn on_init(&mut self) {
49        self.game.on_init(&mut self.state);
50    }
51
52    pub fn on_update(&mut self) {
53        for object in self.state.world_model.objects.iter_mut() {
54            object.update();
55        }
56
57        self.game.on_update(&mut self.state);
58
59        self.state.renderer.on_update(&self.state.world_model);
60    }
61
62    pub fn on_key_event(&mut self, key_event: KeyEvent) {
63        self.game.on_key_event(&mut self.state, key_event);
64    }
65
66    pub fn calc_delta_time(&mut self) {
67        let now = web_time::Instant::now();
68        let delta = now
69            .checked_duration_since(self.state.last_frame_time)
70            .unwrap_or(Duration::from_millis(16))
71            .as_secs_f32();
72
73        self.state.last_frame_time = now;
74        self.state.delta_time = delta;
75    }
76}