oxygengine_audio/
system.rs1use crate::{
2 audio_asset_protocol::AudioAsset,
3 component::{AudioSource, AudioSourceDirtyMode},
4 resource::{Audio, AudioPlayState},
5};
6use core::{
7 assets::database::AssetsDatabase,
8 ecs::{life_cycle::EntityChanges, Comp, Universe, WorldRef},
9};
10
11pub type AudioSystemResources<'a, A> = (
12 WorldRef,
13 &'a EntityChanges,
14 &'a AssetsDatabase,
15 &'a mut A,
16 Comp<&'a mut AudioSource>,
17);
18
19pub fn audio_system<A>(universe: &mut Universe)
20where
21 A: Audio + 'static,
22{
23 let (world, changes, assets, mut audio, ..) =
24 universe.query_resources::<AudioSystemResources<A>>();
25
26 audio.update_cache(&assets);
27
28 for entity in changes.despawned() {
29 audio.destroy_source(entity);
30 }
31
32 for (entity, source) in world.query::<&mut AudioSource>().iter() {
33 if source.dirty != AudioSourceDirtyMode::None {
34 if !audio.has_source(entity) {
35 if let Some(id) = audio.get_asset_id(source.audio()) {
36 if let Some(asset) = assets.asset_by_id(id) {
37 if let Some(asset) = asset.get::<AudioAsset>() {
38 audio.create_source(
39 entity,
40 asset.bytes(),
41 source.streaming(),
42 source.looped(),
43 source.playback_rate(),
44 source.volume(),
45 source.is_playing(),
46 source.ready.clone(),
47 );
48 source.dirty = AudioSourceDirtyMode::None;
49 }
50 }
51 }
52 } else {
53 audio.update_source(
54 entity,
55 source.looped(),
56 source.playback_rate(),
57 source.volume(),
58 if source.dirty == AudioSourceDirtyMode::All {
59 Some(source.is_playing())
60 } else {
61 None
62 },
63 );
64 source.dirty = AudioSourceDirtyMode::None;
65 }
66 }
67 if let Some(state) = audio.get_source_state(entity) {
68 source.current_time = state.current_time;
69 match state.is_playing {
70 AudioPlayState::Ended(v) => {
71 if v {
72 source.stop();
73 }
74 }
75 AudioPlayState::State(v) => {
76 if v != source.is_playing() {
77 if v {
78 source.play();
79 } else {
80 source.stop();
81 }
82 }
83 }
84 }
85 }
86 }
87}