1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
use crate::{ component::{CompositeRenderable, CompositeSurfaceCache}, composite_renderer::{Command, CompositeRenderer, Image}, }; use core::ecs::{life_cycle::EntityChanges, Comp, Entity, Universe, WorldRef}; use std::collections::HashMap; #[derive(Debug, Default)] pub struct CompositeSurfaceCacheSystemCache { cached_surfaces: HashMap<Entity, String>, } pub type CompositeSurfaceCacheSystemResources<'a, CR> = ( WorldRef, &'a mut CR, &'a EntityChanges, &'a mut CompositeSurfaceCacheSystemCache, Comp<&'a mut CompositeSurfaceCache>, Comp<&'a mut CompositeRenderable>, ); pub fn composite_surface_cache_system<CR>(universe: &mut Universe) where CR: CompositeRenderer + 'static, { let (world, mut renderer, changes, mut cache, ..) = universe.query_resources::<CompositeSurfaceCacheSystemResources<CR>>(); for entity in changes.despawned() { if let Some(name) = cache.cached_surfaces.remove(&entity) { renderer.destroy_surface(&name); } } for (entity, (surface, renderable)) in world .query::<(&mut CompositeSurfaceCache, &mut CompositeRenderable)>() .iter() { if surface.dirty { surface.dirty = false; if !renderer.has_surface(surface.name()) { renderer.create_surface(surface.name(), surface.width(), surface.height()); cache .cached_surfaces .insert(entity, surface.name().to_owned()); } else if let Some((width, height)) = renderer.get_surface_size(surface.name()) { if width != surface.width() || height != surface.height() { renderer.destroy_surface(surface.name()); renderer.create_surface(surface.name(), surface.width(), surface.height()); cache .cached_surfaces .insert(entity, surface.name().to_owned()); } } let commands = vec![ Command::Store, Command::Draw(renderable.0.clone()), Command::Restore, ]; if renderer.update_surface(surface.name(), commands).is_ok() { renderable.0 = Image { image: surface.name().to_owned().into(), source: None, destination: None, alignment: 0.0.into(), } .into(); } } } }