1pub use assets_manager;
2pub use frenderer;
3use frenderer::clock::{Clock, Instant};
4use frenderer::input::Input;
5use frenderer::Frenderer;
6pub use frenderer::FrendererEvents;
7use frenderer::{Driver, EventPhase};
8pub use winit::{self, window::WindowBuilder};
9
10#[cfg(not(target_arch = "wasm32"))]
12pub type AssetCache = assets_manager::AssetCache<assets_manager::source::FileSystem>;
13#[cfg(target_arch = "wasm32")]
14pub type AssetCache = assets_manager::AssetCache<assets_manager::source::Embedded<'static>>;
15
16pub trait App {
18 const DT: f32;
20 type Renderer: frenderer::Frenderer;
22 fn new(renderer: &mut Self::Renderer, assets: AssetCache) -> Self;
24 fn update(&mut self, renderer: &mut Self::Renderer, input: &Input);
26 fn render(&mut self, renderer: &mut Self::Renderer, dt: f32, input: &Input);
28}
29
30use std::marker::PhantomData;
31
32pub struct AppDriver<A: App + 'static>
34where
35 A::Renderer: From<frenderer::Renderer> + FrendererEvents<()>,
36{
37 cache: AssetCache,
38 _phantom: PhantomData<A>,
39}
40
41impl<A: App + 'static> AppDriver<A>
42where
43 A::Renderer: From<frenderer::Renderer> + FrendererEvents<()>,
44{
45 pub fn run(self, builder: winit::window::WindowBuilder, render_dims: Option<(u32, u32)>) {
47 let drv = Driver::new(builder, render_dims);
48 let mut clock = Clock::new(A::DT, 0.0002, 5);
49 let mut last_render = Instant::now();
50 drv.run_event_loop::<(), _>(
51 move |window, renderer| {
52 let input = Input::default();
53 let mut rend: A::Renderer = renderer.into();
54 let app = A::new(&mut rend, self.cache);
55 (window, app, rend, input)
56 },
57 move |event, target, (window, ref mut app, ref mut renderer, ref mut input)| {
58 match renderer.handle_event(&mut clock, window, &event, target, input) {
59 EventPhase::Run(steps) => {
60 for _ in 0..steps {
61 app.update(renderer, input);
62 input.next_frame();
63 }
64 app.render(renderer, last_render.elapsed().as_secs_f32(), input);
65 last_render = Instant::now();
66 renderer.render();
67 }
68 EventPhase::Quit => {
69 target.exit();
70 }
71 EventPhase::Wait => {}
72 }
73 },
74 )
75 .unwrap()
76 }
77 pub fn new(cache: AssetCache) -> Self {
79 Self {
80 cache,
81 _phantom: std::marker::PhantomData,
82 }
83 }
84}
85#[macro_export]
87macro_rules! app {
88 ($et:ty, $content:literal) => {{
89 use frapp::{assets_manager, AppDriver};
90 #[cfg(not(target_arch = "wasm32"))]
91 let source =
92 assets_manager::source::FileSystem::new($content).expect("Couldn't load resources");
93 #[cfg(target_arch = "wasm32")]
94 let source =
95 assets_manager::source::Embedded::from(assets_manager::source::embed!($content));
96 let cache = assets_manager::AssetCache::with_source(source);
97 AppDriver::<$et>::new(cache)
98 }};
99}