1use crate::*;
2
3#[derive(Clone, Debug)]
5pub enum Profile {
6 Common(ProfileCommon),
9 CG(ProfileCG),
12 GLES(ProfileGLES),
15 GLSL(ProfileGLSL),
18}
19
20impl From<ProfileCommon> for Profile {
21 fn from(v: ProfileCommon) -> Self {
22 Self::Common(v)
23 }
24}
25
26impl From<ProfileCG> for Profile {
27 fn from(v: ProfileCG) -> Self {
28 Self::CG(v)
29 }
30}
31
32impl From<ProfileGLES> for Profile {
33 fn from(v: ProfileGLES) -> Self {
34 Self::GLES(v)
35 }
36}
37
38impl From<ProfileGLSL> for Profile {
39 fn from(v: ProfileGLSL) -> Self {
40 Self::GLSL(v)
41 }
42}
43
44impl Profile {
45 pub fn parse(e: &Element) -> Result<Option<Self>> {
47 Ok(Some(match e.name() {
48 ProfileCommon::NAME => Self::Common(ProfileCommon::parse(e)?),
49 ProfileCG::NAME => Self::CG(ProfileCG::parse(e)?),
50 ProfileGLES::NAME => Self::GLES(ProfileGLES::parse(e)?),
51 ProfileGLSL::NAME => Self::GLSL(ProfileGLSL::parse(e)?),
52 _ => return Ok(None),
53 }))
54 }
55
56 pub fn as_common(&self) -> Option<&ProfileCommon> {
58 match self {
59 Profile::Common(p) => Some(p),
60 _ => None,
61 }
62 }
63}
64
65impl XNodeWrite for Profile {
66 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
67 match self {
68 Self::Common(e) => e.write_to(w),
69 Self::CG(e) => e.write_to(w),
70 Self::GLES(e) => e.write_to(w),
71 Self::GLSL(e) => e.write_to(w),
72 }
73 }
74}
75
76#[derive(Clone, Debug)]
78pub struct ProfileCommon {
79 pub asset: Option<Box<Asset>>,
81 pub image: Vec<Image>,
83 pub new_param: Vec<NewParam>,
86 pub technique: TechniqueFx<CommonData>,
88 pub extra: Vec<Extra>,
90}
91
92impl XNode for ProfileCommon {
93 const NAME: &'static str = "profile_COMMON";
94 fn parse(element: &Element) -> Result<Self> {
95 debug_assert_eq!(element.name(), Self::NAME);
96 let mut it = element.children().peekable();
97 let asset = Asset::parse_opt_box(&mut it)?;
98 let image_param = ImageParam::parse_list(&mut it)?;
99 let mut image = vec![];
100 let mut new_param = vec![];
101 for ip in image_param {
102 match ip {
103 ImageParam::Image(e) => image.push(e),
104 ImageParam::NewParam(e) => new_param.push(e),
105 }
106 }
107 Ok(ProfileCommon {
108 asset,
109 image,
110 new_param,
111 technique: TechniqueFx::parse_one(&mut it)?,
112 extra: Extra::parse_many(it)?,
113 })
114 }
115}
116
117impl XNodeWrite for ProfileCommon {
118 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
119 let e = Self::elem().start(w)?;
120 self.asset.write_to(w)?;
121 self.image.write_to(w)?;
122 self.new_param.write_to(w)?;
123 self.technique.write_to(w)?;
124 self.extra.write_to(w)?;
125 e.end(w)
126 }
127}
128
129impl ProfileCommon {
130 pub fn new(technique: TechniqueFx<CommonData>) -> Self {
132 Self {
133 asset: None,
134 image: vec![],
135 new_param: vec![],
136 technique,
137 extra: vec![],
138 }
139 }
140
141 pub fn get_param<'a>(&'a self, parent: &'a Effect, sid: &str) -> Option<&'a NewParam> {
144 for p in self.technique.data.image_param.iter().rev() {
145 if let ImageParam::NewParam(p) = p {
146 if p.sid == sid {
147 return Some(p);
148 }
149 }
150 }
151 for p in self.new_param.iter().rev() {
152 if p.sid == sid {
153 return Some(p);
154 }
155 }
156 parent.get_param(sid)
157 }
158}
159
160#[derive(Clone, Default, Debug)]
162pub struct CommonData {
163 pub image_param: Vec<ImageParam>,
165 pub shaders: Vec<Shader>,
167}
168
169impl ProfileData for CommonData {
170 fn parse(it: &mut ElementIter<'_>) -> Result<Self> {
171 Ok(CommonData {
172 image_param: ImageParam::parse_list(it)?,
173 shaders: parse_list_many(it, Shader::parse)?,
174 })
175 }
176}
177
178impl XNodeWrite for CommonData {
179 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
180 self.image_param.write_to(w)?;
181 self.shaders.write_to(w)
182 }
183}
184
185impl CommonData {
186 pub fn shader(shader: impl Into<Shader>) -> Self {
188 Self {
189 image_param: vec![],
190 shaders: vec![shader.into()],
191 }
192 }
193
194 pub fn on_textures<'a, E>(
196 &'a self,
197 mut f: impl FnMut(&'a Texture) -> Result<(), E>,
198 ) -> Result<(), E> {
199 for s in &self.shaders {
200 s.on_textures(&mut f)?
201 }
202 Ok(())
203 }
204}
205
206#[derive(Clone, Debug)]
209pub struct ProfileCG(pub Element); impl XNode for ProfileCG {
212 const NAME: &'static str = "profile_CG";
213 fn parse(element: &Element) -> Result<Self> {
214 Ok(ProfileCG(element.clone()))
215 }
216}
217
218impl XNodeWrite for ProfileCG {
219 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
220 XNodeWrite::write_to(&self.0, w)
221 }
222}
223
224#[derive(Clone, Debug)]
227pub struct ProfileGLES(pub Element); impl XNode for ProfileGLES {
230 const NAME: &'static str = "profile_GLES";
231 fn parse(element: &Element) -> Result<Self> {
232 Ok(ProfileGLES(element.clone()))
233 }
234}
235
236impl XNodeWrite for ProfileGLES {
237 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
238 XNodeWrite::write_to(&self.0, w)
239 }
240}
241
242#[derive(Clone, Debug)]
245pub struct ProfileGLSL(pub Element); impl XNode for ProfileGLSL {
248 const NAME: &'static str = "profile_GLSL";
249 fn parse(element: &Element) -> Result<Self> {
250 Ok(ProfileGLSL(element.clone()))
251 }
252}
253
254impl XNodeWrite for ProfileGLSL {
255 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
256 XNodeWrite::write_to(&self.0, w)
257 }
258}