1use std::f32;
6
7use dom_struct::dom_struct;
8use servo_media::audio::node::AudioNodeType;
9use servo_media::audio::param::{ParamDir, ParamType};
10
11use crate::dom::audio::audioparam::AudioParam;
12use crate::dom::audio::baseaudiocontext::BaseAudioContext;
13use crate::dom::bindings::codegen::Bindings::AudioListenerBinding::AudioListenerMethods;
14use crate::dom::bindings::codegen::Bindings::AudioParamBinding::{
15 AudioParamMethods, AutomationRate,
16};
17use crate::dom::bindings::error::Fallible;
18use crate::dom::bindings::num::Finite;
19use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
20use crate::dom::bindings::root::{Dom, DomRoot};
21use crate::dom::window::Window;
22use crate::script_runtime::CanGc;
23
24#[dom_struct]
25pub(crate) struct AudioListener {
26 reflector_: Reflector,
27 position_x: Dom<AudioParam>,
28 position_y: Dom<AudioParam>,
29 position_z: Dom<AudioParam>,
30 forward_x: Dom<AudioParam>,
31 forward_y: Dom<AudioParam>,
32 forward_z: Dom<AudioParam>,
33 up_x: Dom<AudioParam>,
34 up_y: Dom<AudioParam>,
35 up_z: Dom<AudioParam>,
36}
37
38impl AudioListener {
39 fn new_inherited(window: &Window, context: &BaseAudioContext, can_gc: CanGc) -> AudioListener {
40 let node = context.listener();
41
42 let position_x = AudioParam::new(
43 window,
44 context,
45 node,
46 AudioNodeType::AudioListenerNode,
47 ParamType::Position(ParamDir::X),
48 AutomationRate::A_rate,
49 0., f32::MIN, f32::MAX, can_gc,
53 );
54 let position_y = AudioParam::new(
55 window,
56 context,
57 node,
58 AudioNodeType::AudioListenerNode,
59 ParamType::Position(ParamDir::Y),
60 AutomationRate::A_rate,
61 0., f32::MIN, f32::MAX, can_gc,
65 );
66 let position_z = AudioParam::new(
67 window,
68 context,
69 node,
70 AudioNodeType::AudioListenerNode,
71 ParamType::Position(ParamDir::Z),
72 AutomationRate::A_rate,
73 0., f32::MIN, f32::MAX, can_gc,
77 );
78 let forward_x = AudioParam::new(
79 window,
80 context,
81 node,
82 AudioNodeType::AudioListenerNode,
83 ParamType::Forward(ParamDir::X),
84 AutomationRate::A_rate,
85 0., f32::MIN, f32::MAX, can_gc,
89 );
90 let forward_y = AudioParam::new(
91 window,
92 context,
93 node,
94 AudioNodeType::AudioListenerNode,
95 ParamType::Forward(ParamDir::Y),
96 AutomationRate::A_rate,
97 0., f32::MIN, f32::MAX, can_gc,
101 );
102 let forward_z = AudioParam::new(
103 window,
104 context,
105 node,
106 AudioNodeType::AudioListenerNode,
107 ParamType::Forward(ParamDir::Z),
108 AutomationRate::A_rate,
109 -1., f32::MIN, f32::MAX, can_gc,
113 );
114 let up_x = AudioParam::new(
115 window,
116 context,
117 node,
118 AudioNodeType::AudioListenerNode,
119 ParamType::Up(ParamDir::X),
120 AutomationRate::A_rate,
121 0., f32::MIN, f32::MAX, can_gc,
125 );
126 let up_y = AudioParam::new(
127 window,
128 context,
129 node,
130 AudioNodeType::AudioListenerNode,
131 ParamType::Up(ParamDir::Y),
132 AutomationRate::A_rate,
133 1., f32::MIN, f32::MAX, can_gc,
137 );
138 let up_z = AudioParam::new(
139 window,
140 context,
141 node,
142 AudioNodeType::AudioListenerNode,
143 ParamType::Up(ParamDir::Z),
144 AutomationRate::A_rate,
145 0., f32::MIN, f32::MAX, can_gc,
149 );
150
151 AudioListener {
152 reflector_: Reflector::new(),
153 position_x: Dom::from_ref(&position_x),
154 position_y: Dom::from_ref(&position_y),
155 position_z: Dom::from_ref(&position_z),
156 forward_x: Dom::from_ref(&forward_x),
157 forward_y: Dom::from_ref(&forward_y),
158 forward_z: Dom::from_ref(&forward_z),
159 up_x: Dom::from_ref(&up_x),
160 up_y: Dom::from_ref(&up_y),
161 up_z: Dom::from_ref(&up_z),
162 }
163 }
164
165 #[cfg_attr(crown, allow(crown::unrooted_must_root))]
166 pub(crate) fn new(
167 window: &Window,
168 context: &BaseAudioContext,
169 can_gc: CanGc,
170 ) -> DomRoot<AudioListener> {
171 let node = AudioListener::new_inherited(window, context, can_gc);
172 reflect_dom_object(Box::new(node), window, can_gc)
173 }
174}
175
176#[allow(non_snake_case)]
177impl AudioListenerMethods<crate::DomTypeHolder> for AudioListener {
178 fn PositionX(&self) -> DomRoot<AudioParam> {
180 DomRoot::from_ref(&self.position_x)
181 }
182 fn PositionY(&self) -> DomRoot<AudioParam> {
184 DomRoot::from_ref(&self.position_y)
185 }
186 fn PositionZ(&self) -> DomRoot<AudioParam> {
188 DomRoot::from_ref(&self.position_z)
189 }
190
191 fn ForwardX(&self) -> DomRoot<AudioParam> {
193 DomRoot::from_ref(&self.forward_x)
194 }
195 fn ForwardY(&self) -> DomRoot<AudioParam> {
197 DomRoot::from_ref(&self.forward_y)
198 }
199 fn ForwardZ(&self) -> DomRoot<AudioParam> {
201 DomRoot::from_ref(&self.forward_z)
202 }
203
204 fn UpX(&self) -> DomRoot<AudioParam> {
206 DomRoot::from_ref(&self.up_x)
207 }
208 fn UpY(&self) -> DomRoot<AudioParam> {
210 DomRoot::from_ref(&self.up_y)
211 }
212 fn UpZ(&self) -> DomRoot<AudioParam> {
214 DomRoot::from_ref(&self.up_z)
215 }
216
217 fn SetOrientation(
219 &self,
220 x: Finite<f32>,
221 y: Finite<f32>,
222 z: Finite<f32>,
223 xUp: Finite<f32>,
224 yUp: Finite<f32>,
225 zUp: Finite<f32>,
226 ) -> Fallible<DomRoot<AudioListener>> {
227 self.forward_x.SetValue(x);
228 self.forward_y.SetValue(y);
229 self.forward_z.SetValue(z);
230 self.up_x.SetValue(xUp);
231 self.up_y.SetValue(yUp);
232 self.up_z.SetValue(zUp);
233 Ok(DomRoot::from_ref(self))
234 }
235
236 fn SetPosition(
238 &self,
239 x: Finite<f32>,
240 y: Finite<f32>,
241 z: Finite<f32>,
242 ) -> Fallible<DomRoot<AudioListener>> {
243 self.position_x.SetValue(x);
244 self.position_y.SetValue(y);
245 self.position_z.SetValue(z);
246 Ok(DomRoot::from_ref(self))
247 }
248}