bevy_doryen/
render_schedule.rs

1use bevy_app::{App, Plugin};
2use bevy_ecs::schedule::{ExecutorKind, InternedScheduleLabel, Schedule, ScheduleLabel};
3use bevy_ecs::system::Resource;
4use bevy_ecs::world::{Mut, World};
5
6/// The schedule that contains the render logic that is evaluated each tick of [`doryen_rs::Engine::render`].
7///
8/// By default, it will run the following schedules in the given order:
9///
10/// * [`First`]
11/// * [`PreRender`]
12/// * [`Render`]
13/// * [`PostRender`]
14/// * [`Last`]
15#[derive(ScheduleLabel, Clone, Copy, Debug, Eq, Hash, PartialEq)]
16pub struct MainRender;
17
18/// Runs first in the schedule.
19/// This is run by the [`MainRender`] schedule.
20#[derive(ScheduleLabel, Clone, Copy, Debug, Eq, Hash, PartialEq)]
21pub struct First;
22
23/// The schedule that contains logic that must run before [`Render`].
24///
25/// This is run by the [`MainRender`] schedule.
26#[derive(ScheduleLabel, Clone, Copy, Debug, Eq, Hash, PartialEq)]
27pub struct PreRender;
28
29/// The schedule that contains render logic.
30///
31/// This is run by the [`MainRender`] schedule.
32#[derive(ScheduleLabel, Clone, Copy, Debug, Eq, Hash, PartialEq)]
33pub struct Render;
34
35/// The schedule that contains logic that must run after [`Render`].
36///
37/// This is run by the [`MainRender`] schedule.
38#[derive(ScheduleLabel, Clone, Copy, Debug, Eq, Hash, PartialEq)]
39pub struct PostRender;
40
41/// Runs last in the schedule.
42/// This is run by the [`MainRender`] schedule.
43#[derive(ScheduleLabel, Clone, Copy, Debug, Eq, Hash, PartialEq)]
44pub struct Last;
45
46/// Defines the schedules to be run for the [`Render`] schedule, including
47/// their order.
48#[derive(Debug, Resource)]
49pub struct MainRenderScheduleOrder {
50    /// The labels to run for the [`MainRender`] schedule (in the order they will be run).
51    pub labels: Vec<InternedScheduleLabel>,
52}
53
54impl Default for MainRenderScheduleOrder {
55    fn default() -> Self {
56        Self {
57            labels: vec![
58                First.intern(),
59                PreRender.intern(),
60                Render.intern(),
61                PostRender.intern(),
62                Last.intern(),
63            ],
64        }
65    }
66}
67
68impl MainRender {
69    /// A system that runs the "main render schedule"
70    pub fn run_main_render(world: &mut World) {
71        #[allow(clippy::shadow_unrelated)]
72        world.resource_scope(|world, order: Mut<'_, MainRenderScheduleOrder>| {
73            for &label in &order.labels {
74                let _ = world.try_run_schedule(label);
75            }
76        });
77    }
78}
79
80/// Initializes the [`Render`] schedule, sub schedules, and resources for a given [`App`].
81#[derive(Copy, Clone, Debug)]
82pub struct RenderSchedulePlugin;
83
84impl Plugin for RenderSchedulePlugin {
85    fn build(&self, app: &mut App) {
86        // simple "facilitator" schedules benefit from simpler single threaded scheduling
87        let mut render_schedule = Schedule::new(MainRender);
88        render_schedule.set_executor_kind(ExecutorKind::SingleThreaded);
89
90        app.add_schedule(render_schedule)
91            .init_resource::<MainRenderScheduleOrder>()
92            .add_systems(MainRender, MainRender::run_main_render);
93    }
94}