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();
}
}
}
}