micro_games_kit/assets/
sound.rs

1use crate::{assets::name_from_path, context::GameContext, game::GameSubsystem};
2use anput::world::World;
3use keket::{
4    database::{handle::AssetHandle, path::AssetPathStatic},
5    protocol::AssetProtocol,
6};
7use kira::sound::static_sound::StaticSoundData;
8use std::{error::Error, io::Cursor};
9
10pub struct SoundAsset {
11    pub data: StaticSoundData,
12}
13
14pub struct SoundAssetSubsystem;
15
16impl GameSubsystem for SoundAssetSubsystem {
17    fn run(&mut self, context: GameContext, _: f32) {
18        for entity in context.assets.storage.added().iter_of::<SoundAsset>() {
19            if let Some((path, asset)) = context
20                .assets
21                .storage
22                .lookup_one::<true, (&AssetPathStatic, &SoundAsset)>(entity)
23            {
24                context
25                    .audio
26                    .sounds
27                    .insert(name_from_path(&path).to_owned(), asset.data.clone());
28            }
29        }
30        for entity in context.assets.storage.removed().iter_of::<SoundAsset>() {
31            if let Some(path) = context
32                .assets
33                .storage
34                .lookup_one::<true, &AssetPathStatic>(entity)
35            {
36                context.audio.sounds.remove(name_from_path(&path));
37            }
38        }
39    }
40}
41
42pub struct SoundAssetProtocol;
43
44impl AssetProtocol for SoundAssetProtocol {
45    fn name(&self) -> &str {
46        "sound"
47    }
48
49    fn process_bytes(
50        &mut self,
51        handle: AssetHandle,
52        storage: &mut World,
53        bytes: Vec<u8>,
54    ) -> Result<(), Box<dyn Error>> {
55        let path = storage.component::<true, AssetPathStatic>(handle.entity())?;
56        let data = StaticSoundData::from_cursor(Cursor::new(bytes))
57            .map_err(|_| format!("Failed to load sound: {:?}", path.path()))?;
58        drop(path);
59
60        storage.insert(handle.entity(), (SoundAsset { data },))?;
61
62        Ok(())
63    }
64}