gooey/presentation/fmod/
mod.rs1use {log, fmod, nsys};
7use key_vec::KeyVec;
8
9use crate::Tree;
10use crate::tree::NodeId;
11use crate::interface::{view, View};
12use super::{Audio, Presentation};
13
14pub mod remote;
15pub use self::remote::Remote;
16
17#[derive(Debug)]
18pub struct Fmod {
19 pub audition : nsys::fmod::Audition,
20 pub channel_group : fmod::ChannelGroup,
21 pub sfx : KeyVec <NodeId, nsys::fmod::voice::Id>
22}
23
24impl Fmod {
25 fn create_sfx (&mut self, node_id : NodeId) {
26 log::trace!("create sfx...");
27 let voice_id = self.audition.new_voice();
28 self.sfx.insert (node_id.clone(), voice_id.clone());
29 log::trace!("...create sfx");
30 }
31 fn update_sfx (&mut self, sfx : view::component::Sfx, node_id : NodeId) {
32 log::trace!("update sfx...");
33 let voice_id = self.sfx.get (&node_id).unwrap();
34 let voice = &mut self.audition.voices[voice_id.0 as usize];
35 if let Some ((sound_id, state)) = sfx.playback {
36 use view::component::sfx::State;
37 let sample_id = sound_id.into();
38 let mut sample = self.audition.sampler.get (sample_id).unwrap().clone();
39 let channel_group = Some (self.channel_group.clone());
40 match state {
41 State::Ready => voice.cue (&mut sample, channel_group),
42 State::Play => voice.play (&mut sample, channel_group),
43 State::Loop => voice.loop_ (&mut sample, channel_group),
44 State::PlayFrom (position) => voice.play_from (&mut sample,
45 channel_group, position),
46 State::LoopFrom (position) => voice.loop_from (&mut sample,
47 channel_group, position)
48 }
49 } else {
50 voice.stop();
51 }
52 log::trace!("...update sfx");
53 }
54 fn display_value (&mut self, node_id : NodeId, display : view::Display) {
55 match display {
56 view::Display::Create (
57 View { component: view::Component::Sfx (sfx), .. },
58 node_id,
59 ..
60 ) => {
61 self.create_sfx (node_id.clone());
62 self.update_sfx (sfx, node_id);
63 }
64 view::Display::Update (view::Update::View (view)) => {
65 if let Some (sound_id) = view.appearance.sound {
67 let sample_id = sound_id.clone().into();
68 let mode = Some (fmod::Mode::LOOP_OFF | fmod::Mode::_2D);
70 let _ = self.audition.sampler
71 .play (sample_id, mode, Some (&mut self.channel_group));
72 }
73 match view.component {
75 view::Component::Sfx (sfx) => {
76 if self.sfx.get (&node_id).is_none() {
77 self.create_sfx (node_id.clone());
78 }
79 self.update_sfx (sfx, node_id);
80 }
81 _ => {}
82 }
83 }
84 view::Display::Update (view::Update::FocusTop) => { }
85 view::Display::Create (_, _, _) => { }
86 view::Display::Destroy => {
87 if let Some (voice_id) = self.sfx.remove (&node_id) {
88 let _ = self.audition.remove_voice (voice_id).unwrap();
89 }
90 }
91 }
92 }
93}
94
95impl Default for Fmod {
96 fn default() -> Self {
97 let mut audition = nsys::fmod::Audition::default();
98 let channel_group = audition.system
99 .create_channel_group (Some ("gui")).unwrap();
100 let sfx = KeyVec::new();
101 Fmod { audition, channel_group, sfx }
102 }
103}
104
105impl Audio for Fmod { }
106impl Presentation for Fmod {
107 fn with_root (root : View, root_id : NodeId) -> Self {
108 let mut fmod = Fmod::default();
109 match &root.component {
110 view::Component::Sfx (sfx) => {
111 fmod.create_sfx (root_id.clone());
112 fmod.update_sfx (sfx.clone(), root_id);
113 }
114 _ => {}
115 }
116 fmod
117 }
118 fn get_input (&mut self, _ : &mut Vec <view::Input>) { }
119
120 fn display_view <V : AsRef <View>> (&mut self,
121 _view_tree : &Tree <V>,
122 display_values : std::vec::Drain <(NodeId, view::Display)>
123 ) {
124 log::trace!("display view...");
125 for (node_id, display) in display_values {
126 self.display_value (node_id, display);
127 }
128 self.audition.update();
129 log::trace!("...display view");
130 }
131}
132
133impl From <view::Sound> for nsys::fmod::sampler::Id {
134 fn from (sound : view::Sound) -> Self {
135 nsys::fmod::sampler::Id (sound.0)
136 }
137}