swamp_game_assets/
lib.rs

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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/swamp
 * Licensed under the MIT License. See LICENSE in the project root for license information.
 */

use int_math::UVec2;

use limnus_asset_id::{AssetName, Id};
use limnus_asset_registry::AssetRegistry;
use limnus_audio_mixer::{StereoSample, StereoSampleRef};
use limnus_resource::ResourceStorage;
use monotonic_time_rs::Millis;
use std::fmt::Debug;
use swamp_font::Font;
use swamp_font::Glyph;
use swamp_render_wgpu::{FixedAtlas, FontAndMaterial, Material, MaterialRef};

pub trait Assets {
    #[must_use]
    fn now(&self) -> Millis;

    #[must_use]
    fn material_png(&mut self, name: impl Into<AssetName>) -> MaterialRef;

    #[must_use]
    fn frame_fixed_grid_material_png(
        &mut self,
        name: impl Into<AssetName>,
        grid_size: UVec2,
        texture_size: UVec2,
    ) -> FixedAtlas;

    #[must_use]
    fn bm_font(&mut self, name: impl Into<AssetName>) -> FontAndMaterial;

    #[must_use]
    fn text_glyphs(&self, text: &str, font_and_mat: &FontAndMaterial) -> Option<Vec<Glyph>>;

    #[must_use]
    fn font(&self, font_ref: &Id<Font>) -> Option<&Font>;
    #[must_use]
    fn audio_sample_wav(&mut self, name: impl Into<AssetName>) -> StereoSampleRef;
}

pub struct GameAssets<'a> {
    now: Millis,
    resource_storage: &'a mut ResourceStorage,
}

impl Debug for GameAssets<'_> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "assets")
    }
}

impl<'a> GameAssets<'a> {
    pub fn new(resource_storage: &'a mut ResourceStorage, now: Millis) -> Self {
        Self {
            resource_storage,
            now,
        }
    }
}

impl Assets for GameAssets<'_> {
    fn now(&self) -> Millis {
        self.now
    }

    fn material_png(&mut self, name: impl Into<AssetName>) -> MaterialRef {
        let asset_loader = self
            .resource_storage
            .get_mut::<AssetRegistry>()
            .expect("should exist registry");
        asset_loader.load::<Material>(name.into().with_extension("png"))
    }

    fn frame_fixed_grid_material_png(
        &mut self,
        name: impl Into<AssetName>,
        grid_size: UVec2,
        texture_size: UVec2,
    ) -> FixedAtlas {
        let material_ref = self.material_png(name);

        FixedAtlas::new(grid_size, texture_size, material_ref)
    }

    fn bm_font(&mut self, name: impl Into<AssetName>) -> FontAndMaterial {
        let asset_name = name.into();
        let asset_loader = self
            .resource_storage
            .get_mut::<AssetRegistry>()
            .expect("should exist registry");
        let font_ref = asset_loader.load::<Font>(asset_name.clone().with_extension("fnt"));
        let material_ref = asset_loader.load::<Material>(asset_name.clone().with_extension("png"));

        FontAndMaterial {
            font_ref,
            material_ref,
        }
    }

    fn text_glyphs(&self, text: &str, font_and_mat: &FontAndMaterial) -> Option<Vec<Glyph>> {
        if let Some(font) = self.font(&font_and_mat.font_ref) {
            let glyphs = font.draw(text);
            Some(glyphs)
        } else {
            None
        }
    }

    fn font(&self, font_ref: &Id<Font>) -> Option<&Font> {
        let font_assets = self
            .resource_storage
            .get::<limnus_assets::Assets<Font>>()
            .expect("font assets should be a thing");

        font_assets.get(font_ref)
    }

    fn audio_sample_wav(&mut self, name: impl Into<AssetName>) -> StereoSampleRef {
        let asset_loader = self
            .resource_storage
            .get_mut::<AssetRegistry>()
            .expect("should exist registry");
        asset_loader.load::<StereoSample>(name.into().with_extension("wav"))
    }
}