1use crate::source::{generic::GenericSource, spatial::SpatialSource};
10use rg3d_core::inspect::{Inspect, PropertyInfo};
11use rg3d_core::visitor::{Visit, VisitError, VisitResult, Visitor};
12use std::ops::{Deref, DerefMut};
13
14pub mod generic;
15pub mod spatial;
16
17#[derive(Eq, PartialEq, Copy, Clone, Debug, Inspect)]
19#[repr(u32)]
20pub enum Status {
21 Stopped = 0,
24
25 Playing = 1,
27
28 Paused = 2,
31}
32
33#[derive(Debug, Clone)]
35pub enum SoundSource {
36 Generic(GenericSource),
38
39 Spatial(SpatialSource),
41}
42
43impl Inspect for SoundSource {
44 fn properties(&self) -> Vec<PropertyInfo<'_>> {
45 match self {
46 SoundSource::Generic(v) => v.properties(),
47 SoundSource::Spatial(v) => v.properties(),
48 }
49 }
50}
51
52impl SoundSource {
53 pub fn spatial(&self) -> &SpatialSource {
57 match self {
58 SoundSource::Generic(_) => panic!("Cast as spatial sound failed!"),
59 SoundSource::Spatial(ref spatial) => spatial,
60 }
61 }
62
63 pub fn spatial_mut(&mut self) -> &mut SpatialSource {
67 match self {
68 SoundSource::Generic(_) => panic!("Cast as spatial sound failed!"),
69 SoundSource::Spatial(ref mut spatial) => spatial,
70 }
71 }
72}
73
74impl Deref for SoundSource {
75 type Target = GenericSource;
76
77 fn deref(&self) -> &Self::Target {
80 match self {
81 SoundSource::Generic(v) => v,
82 SoundSource::Spatial(v) => v,
83 }
84 }
85}
86
87impl DerefMut for SoundSource {
88 fn deref_mut(&mut self) -> &mut Self::Target {
91 match self {
92 SoundSource::Generic(v) => v,
93 SoundSource::Spatial(v) => v,
94 }
95 }
96}
97
98impl Visit for Status {
99 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
100 let mut kind = *self as u8;
101
102 kind.visit(name, visitor)?;
103
104 if visitor.is_reading() {
105 *self = match kind {
106 0 => Status::Stopped,
107 1 => Status::Playing,
108 2 => Status::Paused,
109 _ => return Err(VisitError::User("invalid status".to_string())),
110 }
111 }
112
113 Ok(())
114 }
115}
116
117impl Visit for SoundSource {
118 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
119 visitor.enter_region(name)?;
120
121 let mut kind: u8 = match self {
122 SoundSource::Generic(_) => 0,
123 SoundSource::Spatial(_) => 1,
124 };
125
126 kind.visit("Id", visitor)?;
127
128 if visitor.is_reading() {
129 *self = match kind {
130 0 => SoundSource::Generic(GenericSource::default()),
131 1 => SoundSource::Spatial(SpatialSource::default()),
132 _ => return Err(VisitError::User("invalid source kind".to_string())),
133 }
134 }
135
136 match self {
137 SoundSource::Generic(generic) => generic.visit("Content", visitor)?,
138 SoundSource::Spatial(spatial) => spatial.visit("Content", visitor)?,
139 }
140
141 visitor.leave_region()
142 }
143}
144
145impl Default for SoundSource {
146 fn default() -> Self {
147 SoundSource::Generic(Default::default())
148 }
149}