oxygengine_composite_renderer/system/
sprite_sheet.rs1use crate::{
2 component::{CompositeRenderable, CompositeSprite},
3 composite_renderer::Image,
4 math::Rect,
5 sprite_sheet_asset_protocol::SpriteSheetAsset,
6};
7use core::{
8 assets::{asset::AssetId, database::AssetsDatabase},
9 ecs::{Comp, Universe, WorldRef},
10};
11use std::collections::HashMap;
12
13#[derive(Debug, Default)]
14pub struct CompositeSpriteSheetSystemCache {
15 images_cache: HashMap<String, String>,
16 atlas_table: HashMap<AssetId, String>,
17 frames_cache: HashMap<String, HashMap<String, Rect>>,
18}
19
20pub type CompositeSpriteSheetSystemResources<'a> = (
21 WorldRef,
22 &'a AssetsDatabase,
23 &'a mut CompositeSpriteSheetSystemCache,
24 Comp<&'a mut CompositeRenderable>,
25 Comp<&'a mut CompositeSprite>,
26);
27
28pub fn composite_sprite_sheet_system(universe: &mut Universe) {
29 let (world, assets, mut cache, ..) =
30 universe.query_resources::<CompositeSpriteSheetSystemResources>();
31
32 for id in assets.lately_loaded_protocol("atlas") {
33 let id = *id;
34 let asset = assets
35 .asset_by_id(id)
36 .expect("trying to use not loaded atlas asset");
37 let path = asset.path().to_owned();
38 let asset = asset
39 .get::<SpriteSheetAsset>()
40 .expect("trying to use non-atlas asset");
41 let image = asset.info().meta.image_name();
42 let frames = asset
43 .info()
44 .frames
45 .iter()
46 .map(|(k, v)| (k.to_owned(), v.frame))
47 .collect();
48 cache.images_cache.insert(path.clone(), image);
49 cache.atlas_table.insert(id, path.clone());
50 cache.frames_cache.insert(path, frames);
51 }
52 for id in assets.lately_unloaded_protocol("atlas") {
53 if let Some(path) = cache.atlas_table.remove(id) {
54 cache.images_cache.remove(&path);
55 cache.frames_cache.remove(&path);
56 }
57 }
58
59 for (_, (renderable, sprite)) in world
60 .query::<(&mut CompositeRenderable, &mut CompositeSprite)>()
61 .iter()
62 {
63 if sprite.dirty {
64 if let Some((sheet, frame)) = sprite.sheet_frame() {
65 if let (Some(name), Some(frames)) =
66 (cache.images_cache.get(sheet), cache.frames_cache.get(sheet))
67 {
68 renderable.0 = Image {
69 image: name.clone().into(),
70 source: frames.get(frame).copied(),
71 destination: None,
72 alignment: sprite.alignment,
73 }
74 .into();
75 sprite.dirty = false;
76 }
77 }
78 }
79 }
80}