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
72
73
74
75
76
77
78
79
80
use crate::{
component::{CompositeRenderable, CompositeSprite},
composite_renderer::Image,
math::Rect,
sprite_sheet_asset_protocol::SpriteSheetAsset,
};
use core::{
assets::{asset::AssetId, database::AssetsDatabase},
ecs::{Comp, Universe, WorldRef},
};
use std::collections::HashMap;
#[derive(Debug, Default)]
pub struct CompositeSpriteSheetSystemCache {
images_cache: HashMap<String, String>,
atlas_table: HashMap<AssetId, String>,
frames_cache: HashMap<String, HashMap<String, Rect>>,
}
pub type CompositeSpriteSheetSystemResources<'a> = (
WorldRef,
&'a AssetsDatabase,
&'a mut CompositeSpriteSheetSystemCache,
Comp<&'a mut CompositeRenderable>,
Comp<&'a mut CompositeSprite>,
);
pub fn composite_sprite_sheet_system(universe: &mut Universe) {
let (world, assets, mut cache, ..) =
universe.query_resources::<CompositeSpriteSheetSystemResources>();
for id in assets.lately_loaded_protocol("atlas") {
let id = *id;
let asset = assets
.asset_by_id(id)
.expect("trying to use not loaded atlas asset");
let path = asset.path().to_owned();
let asset = asset
.get::<SpriteSheetAsset>()
.expect("trying to use non-atlas asset");
let image = asset.info().meta.image_name();
let frames = asset
.info()
.frames
.iter()
.map(|(k, v)| (k.to_owned(), v.frame))
.collect();
cache.images_cache.insert(path.clone(), image);
cache.atlas_table.insert(id, path.clone());
cache.frames_cache.insert(path, frames);
}
for id in assets.lately_unloaded_protocol("atlas") {
if let Some(path) = cache.atlas_table.remove(id) {
cache.images_cache.remove(&path);
cache.frames_cache.remove(&path);
}
}
for (_, (renderable, sprite)) in world
.query::<(&mut CompositeRenderable, &mut CompositeSprite)>()
.iter()
{
if sprite.dirty {
if let Some((sheet, frame)) = sprite.sheet_frame() {
if let (Some(name), Some(frames)) =
(cache.images_cache.get(sheet), cache.frames_cache.get(sheet))
{
renderable.0 = Image {
image: name.clone().into(),
source: frames.get(frame).copied(),
destination: None,
alignment: sprite.alignment,
}
.into();
sprite.dirty = false;
}
}
}
}
}