micro_games_kit/assets/
sound.rs1use 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}