Skip to main content

mireforge_advanced_game/
render.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/mireforge/mireforge
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5use crate::logic::GameLogic;
6use crate::{ApplicationLogic, ApplicationRender};
7use limnus_app::prelude::{App, Plugin};
8use limnus_default_stages::RenderUpdate;
9use limnus_local_resource::prelude::LocalResource;
10use limnus_resource::ResourceStorage;
11use limnus_system_params::{LoRe, LoReM, ReM};
12use mireforge_game_assets::GameAssets;
13use mireforge_render_wgpu::Render;
14use monotonic_time_rs::{InstantMonotonicClock, Millis, MonotonicClock};
15use std::fmt::{Debug, Formatter};
16use std::marker::PhantomData;
17use tracing::trace;
18
19#[derive(LocalResource)]
20pub struct GameRenderer<R: ApplicationRender<L>, L: ApplicationLogic> {
21    renderer: R,
22    clock: InstantMonotonicClock,
23    _phantom: PhantomData<L>,
24}
25
26impl<R: ApplicationRender<L>, L: ApplicationLogic> Debug for GameRenderer<R, L> {
27    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
28        write!(f, "GameAudioRender")
29    }
30}
31
32impl<R: ApplicationRender<L>, L: ApplicationLogic> GameRenderer<R, L> {
33    #[must_use]
34    pub fn new(all_resources: &mut ResourceStorage) -> Self {
35        let clock = InstantMonotonicClock::new();
36        let mut assets = GameAssets::new(all_resources, clock.now());
37        let renderer = R::new(&mut assets);
38
39        Self {
40            renderer,
41            clock,
42            _phantom: PhantomData,
43        }
44    }
45
46    pub fn render(&mut self, logic: &L, wgpu_render: &mut Render, now: Millis) {
47        wgpu_render.set_now(now);
48        self.renderer.render(wgpu_render, logic);
49    }
50}
51
52pub fn advanced_game_render_tick<R: ApplicationRender<L>, L: ApplicationLogic>(
53    mut game_render: LoReM<GameRenderer<R, L>>,
54    logic: LoRe<GameLogic<L>>,
55    mut wgpu_render: ReM<Render>,
56) {
57    let now = game_render.clock.now();
58    game_render.render(&logic.logic, &mut wgpu_render, now);
59}
60
61#[derive(Default)]
62pub struct GameRendererPlugin<R: ApplicationRender<L>, L: ApplicationLogic> {
63    _phantom: PhantomData<(R, L)>,
64}
65
66impl<A: ApplicationRender<L>, L: ApplicationLogic> GameRendererPlugin<A, L> {
67    #[must_use]
68    pub const fn new() -> Self {
69        Self {
70            _phantom: PhantomData,
71        }
72    }
73}
74
75impl<R: ApplicationRender<L>, L: ApplicationLogic> Plugin for GameRendererPlugin<R, L> {
76    fn post_initialization(&self, app: &mut App) {
77        trace!("GameRendererPlugin startup");
78        let all_resources = app.resources_mut();
79
80        let game_renderer = GameRenderer::<R, L>::new(all_resources);
81        app.insert_local_resource(game_renderer);
82
83        app.add_system(RenderUpdate, advanced_game_render_tick::<R, L>);
84    }
85}