1use pfx_core::clock::Tick;
2use pfx_core::modules::Reload;
3use pfx_gpu::wgpu;
4use pfx_input::{ActionSpec, Input};
5use pfx_live::renderer::Renderer;
6use pfx_load::scene::Cue;
7
8use crate::events::WorldEvent;
9use crate::paint::{PaintFrame, Warm, Warming};
10use crate::settings::Settings;
11use crate::ui::{Ui, UiFrame};
12use crate::world::{AnimationEvent, World};
13
14pub type GameError = Box<dyn std::error::Error + Send + Sync>;
15
16#[derive(Clone, Copy, Debug, Default, PartialEq)]
17pub struct FrameTime {
18 pub alpha: f32,
19 pub seconds: f32,
20 pub tick: Tick,
21}
22
23pub trait Game {
24 fn actions(&self) -> Vec<ActionSpec> {
25 Vec::new()
26 }
27
28 fn start(&mut self, world: &mut World);
29
30 fn tick(&mut self, _world: &mut World, _tick: &Tick, _input: &Input) {}
31
32 fn try_tick(&mut self, world: &mut World, tick: &Tick, input: &Input) -> Result<(), GameError> {
33 self.tick(world, tick, input);
34 Ok(())
35 }
36
37 fn events(&mut self, _world: &mut World, _events: &[WorldEvent]) {}
38
39 fn animated(&mut self, _world: &mut World, _events: &[AnimationEvent]) {}
40
41 fn frame(&mut self, _world: &World, _alpha: f32) {}
42
43 fn try_frame(&mut self, world: &World, time: FrameTime) -> Result<(), GameError> {
44 self.frame(world, time.alpha);
45 Ok(())
46 }
47
48 fn ui(&mut self, _world: &World, _frame: &UiFrame) -> Ui {
49 Ui::default()
50 }
51
52 fn warm(&mut self, _warm: &mut Warm<'_>) -> Result<Warming, GameError> {
53 Ok(Warming::Done)
54 }
55
56 fn paint(
57 &mut self,
58 _renderer: &mut Renderer,
59 _target: &wgpu::TextureView,
60 _frame: &PaintFrame,
61 ) -> Result<(), GameError> {
62 Ok(())
63 }
64
65 fn try_ui(&mut self, world: &World, frame: &UiFrame) -> Result<Ui, GameError> {
66 Ok(self.ui(world, frame))
67 }
68
69 fn settings(&self) -> Option<&Settings> {
70 None
71 }
72
73 fn stop(&mut self) {}
74
75 fn modules(&mut self) -> Option<&mut dyn Reload> {
76 None
77 }
78}
79
80#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
81pub struct SceneGame;
82
83impl Game for SceneGame {
84 fn start(&mut self, world: &mut World) {
85 world.pose_movers();
86 world.play_cued(Cue::Start);
87 }
88
89 fn tick(&mut self, world: &mut World, _tick: &Tick, _input: &Input) {
90 world.play_hits();
91 world.pose_movers();
92 }
93}