feat: separate dirty rendering with flag resource

This commit is contained in:
2025-08-15 14:19:39 -05:00
parent 2f0c734d13
commit b88895e82f
3 changed files with 23 additions and 8 deletions

View File

@@ -14,13 +14,13 @@ use crate::systems::{
collision::collision_system,
components::{
Collider, CollisionLayer, DeltaTime, DirectionalAnimated, EntityType, GlobalState, ItemBundle, ItemCollider,
PacmanCollider, PlayerBundle, PlayerControlled, Renderable, Score, ScoreResource,
PacmanCollider, PlayerBundle, PlayerControlled, RenderDirty, Renderable, Score, ScoreResource,
},
control::player_system,
input::input_system,
movement::movement_system,
profiling::{profile, SystemTimings},
render::{directional_render_system, render_system, BackbufferResource, MapTextureResource},
render::{directional_render_system, dirty_render_system, render_system, BackbufferResource, MapTextureResource},
};
use crate::texture::animated::AnimatedTexture;
use bevy_ecs::schedule::IntoScheduleConfigs;
@@ -175,6 +175,7 @@ impl Game {
world.insert_resource(SystemTimings::default());
world.insert_resource(Bindings::default());
world.insert_resource(DeltaTime(0f32));
world.insert_resource(RenderDirty::default());
world.add_observer(
|event: Trigger<GameEvent>, mut state: ResMut<GlobalState>, _score: ResMut<ScoreResource>| match *event {
@@ -199,7 +200,7 @@ impl Game {
)
.chain(),
);
schedule.add_systems(profile("render", render_system));
schedule.add_systems((profile("dirty_render", dirty_render_system), profile("render", render_system)).chain());
// Spawn player
world.spawn(player);

View File

@@ -109,3 +109,6 @@ pub struct ScoreResource(pub u32);
#[derive(Resource)]
pub struct DeltaTime(pub f32);
#[derive(Resource, Default)]
pub struct RenderDirty(pub bool);

View File

@@ -1,15 +1,25 @@
use crate::error::{GameError, TextureError};
use crate::map::builder::Map;
use crate::systems::components::{DeltaTime, DirectionalAnimated, Renderable};
use crate::systems::components::{DeltaTime, DirectionalAnimated, RenderDirty, Renderable};
use crate::systems::movement::{Movable, MovementState, Position};
use crate::texture::sprite::SpriteAtlas;
use bevy_ecs::entity::Entity;
use bevy_ecs::event::EventWriter;
use bevy_ecs::prelude::{Changed, Or, RemovedComponents};
use bevy_ecs::system::{NonSendMut, Query, Res};
use bevy_ecs::system::{NonSendMut, Query, Res, ResMut};
use sdl2::render::{Canvas, Texture};
use sdl2::video::Window;
pub fn dirty_render_system(
mut dirty: ResMut<RenderDirty>,
changed_renderables: Query<(), Or<(Changed<Renderable>, Changed<Position>)>>,
removed_renderables: RemovedComponents<Renderable>,
) {
if !changed_renderables.is_empty() || !removed_renderables.is_empty() {
dirty.0 = true;
}
}
/// Updates the directional animated texture of an entity.
///
/// This runs before the render system so it can update the sprite based on the current direction of travel, as well as whether the entity is moving.
@@ -55,12 +65,11 @@ pub fn render_system(
mut backbuffer: NonSendMut<BackbufferResource>,
mut atlas: NonSendMut<SpriteAtlas>,
map: Res<Map>,
mut dirty: ResMut<RenderDirty>,
renderables: Query<(Entity, &Renderable, &Position)>,
changed_renderables: Query<(), Or<(Changed<Renderable>, Changed<Position>)>>,
removed_renderables: RemovedComponents<Renderable>,
mut errors: EventWriter<GameError>,
) {
if changed_renderables.is_empty() && removed_renderables.is_empty() {
if !dirty.0 {
return;
}
// Clear the main canvas first
@@ -111,4 +120,6 @@ pub fn render_system(
.map(|e| errors.write(TextureError::RenderFailed(e.to_string()).into()));
canvas.present();
dirty.0 = false;
}