1use crate::*;
2
3#[derive(Clone, Debug)]
6pub struct NewParam {
7 pub sid: String,
9 pub annotate: Vec<Annotate>,
11 pub semantic: Option<String>,
13 pub modifier: Option<Modifier>,
15 pub ty: ParamType,
17}
18
19impl NewParam {
20 pub fn new(sid: impl Into<String>, ty: impl Into<ParamType>) -> Self {
22 Self {
23 sid: sid.into(),
24 annotate: vec![],
25 semantic: None,
26 modifier: None,
27 ty: ty.into(),
28 }
29 }
30}
31
32impl XNode for NewParam {
33 const NAME: &'static str = "newparam";
34 fn parse(element: &Element) -> Result<Self> {
35 debug_assert_eq!(element.name(), Self::NAME);
36 let mut it = element.children().peekable();
37 let res = NewParam {
38 sid: element.attr("sid").ok_or("expecting sid attr")?.into(),
39 annotate: Annotate::parse_list(&mut it)?,
40 semantic: parse_opt("semantic", &mut it, parse_text)?,
41 modifier: parse_opt("modifier", &mut it, parse_elem)?,
42 ty: parse_one_many(&mut it, ParamType::parse)?,
43 };
44 finish(res, it)
45 }
46}
47
48impl XNodeWrite for NewParam {
49 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
50 let mut e = Self::elem();
51 e.attr("sid", &self.sid);
52 let e = e.start(w)?;
53 self.annotate.write_to(w)?;
54 opt(&self.semantic, |e| ElemBuilder::print_str("semantic", e, w))?;
55 ElemBuilder::opt_print("modifier", &self.modifier, w)?;
56 self.ty.write_to(w)?;
57 e.end(w)
58 }
59}
60
61#[derive(Clone, Debug)]
66pub struct EffectSetParam {
67 pub ref_: String,
69 pub value: AnnotType,
73}
74
75impl EffectSetParam {
76 pub fn new(ref_: impl Into<String>, value: impl Into<AnnotType>) -> Self {
78 Self {
79 ref_: ref_.into(),
80 value: value.into(),
81 }
82 }
83}
84
85impl XNode for EffectSetParam {
86 const NAME: &'static str = "setparam";
87 fn parse(element: &Element) -> Result<Self> {
88 debug_assert_eq!(element.name(), Self::NAME);
89 let mut it = element.children().peekable();
90 let res = EffectSetParam {
91 ref_: element.attr("ref").ok_or("expected ref attr")?.into(),
92 value: parse_one_many(&mut it, AnnotType::parse)?,
93 };
94 finish(res, it)
95 }
96}
97
98impl XNodeWrite for EffectSetParam {
99 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
100 let mut e = Self::elem();
101 e.attr("ref", &self.ref_);
102 let e = e.start(w)?;
103 self.value.write_to(w)?;
104 e.end(w)
105 }
106}
107
108#[derive(Clone, Debug)]
110pub struct Annotate {
111 pub name: String,
114 pub value: AnnotType,
118}
119
120impl Annotate {
121 pub fn new(name: impl Into<String>, value: impl Into<AnnotType>) -> Self {
123 Self {
124 name: name.into(),
125 value: value.into(),
126 }
127 }
128}
129
130impl XNode for Annotate {
131 const NAME: &'static str = "annotate";
132 fn parse(element: &Element) -> Result<Self> {
133 debug_assert_eq!(element.name(), Self::NAME);
134 let mut it = element.children().peekable();
135 let res = Annotate {
136 name: element.attr("name").ok_or("expecting name attr")?.into(),
137 value: parse_one_many(&mut it, AnnotType::parse)?,
138 };
139 finish(res, it)
140 }
141}
142
143impl XNodeWrite for Annotate {
144 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
145 let mut e = Self::elem();
146 e.attr("name", &self.name);
147 let e = e.start(w)?;
148 self.value.write_to(w)?;
149 e.end(w)
150 }
151}
152
153mk_extensible_enum! {
154 pub enum Modifier {
156 Const = "CONST",
158 Uniform = "UNIFORM",
160 Varying = "VARYING",
162 Static = "STATIC",
164 Volatile = "VOLATILE",
166 Extern = "EXTERN",
168 Shared = "SHARED",
170 }
171}
172
173#[derive(Clone, Debug)]
175pub enum AnnotType {
176 Bool(bool),
178 Bool2([bool; 2]),
180 Bool3([bool; 3]),
182 Bool4([bool; 4]),
184 Int(u32),
186 Int2([u32; 2]),
188 Int3(Box<[u32; 3]>),
190 Int4(Box<[u32; 4]>),
192 Float(f32),
194 Float2([f32; 2]),
196 Float3(Box<[f32; 3]>),
198 Float4(Box<[f32; 4]>),
200 Float2x2(Box<[f32; 2 * 2]>),
202 Float3x3(Box<[f32; 3 * 3]>),
204 Float4x4(Box<[f32; 4 * 4]>),
206 String(Box<str>),
208}
209
210impl From<&str> for AnnotType {
211 fn from(v: &str) -> Self {
212 Self::String(v.into())
213 }
214}
215
216impl From<Box<str>> for AnnotType {
217 fn from(v: Box<str>) -> Self {
218 Self::String(v)
219 }
220}
221
222impl From<bool> for AnnotType {
223 fn from(v: bool) -> Self {
224 Self::Bool(v)
225 }
226}
227
228impl From<f32> for AnnotType {
229 fn from(v: f32) -> Self {
230 Self::Float(v)
231 }
232}
233
234impl From<u32> for AnnotType {
235 fn from(v: u32) -> Self {
236 Self::Int(v)
237 }
238}
239
240impl AnnotType {
241 pub fn parse(e: &Element) -> Result<Option<Self>> {
243 Ok(Some(match e.name() {
244 "bool" => Self::Bool(parse_elem(e)?),
245 "bool2" => Self::Bool2(*parse_array_n(e)?),
246 "bool3" => Self::Bool3(*parse_array_n(e)?),
247 "bool4" => Self::Bool4(*parse_array_n(e)?),
248 "int" => Self::Int(parse_elem(e)?),
249 "int2" => Self::Int2(*parse_array_n(e)?),
250 "int3" => Self::Int3(parse_array_n(e)?),
251 "int4" => Self::Int4(parse_array_n(e)?),
252 "float" => Self::Float(parse_elem(e)?),
253 "float2" => Self::Float2(*parse_array_n(e)?),
254 "float3" => Self::Float3(parse_array_n(e)?),
255 "float4" => Self::Float4(parse_array_n(e)?),
256 "float2x2" => Self::Float2x2(parse_array_n(e)?),
257 "float3x3" => Self::Float3x3(parse_array_n(e)?),
258 "float4x4" => Self::Float4x4(parse_array_n(e)?),
259 "string" => Self::String(parse_text(e)?.into()),
260 _ => return Ok(None),
261 }))
262 }
263}
264
265impl XNodeWrite for AnnotType {
266 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
267 match self {
268 AnnotType::Bool(e) => ElemBuilder::print("bool", e, w),
269 AnnotType::Bool2(e) => ElemBuilder::print_arr("bool2", e, w),
270 AnnotType::Bool3(e) => ElemBuilder::print_arr("bool3", e, w),
271 AnnotType::Bool4(e) => ElemBuilder::print_arr("bool4", e, w),
272 AnnotType::Int(e) => ElemBuilder::print("int", e, w),
273 AnnotType::Int2(e) => ElemBuilder::print_arr("int2", e, w),
274 AnnotType::Int3(e) => ElemBuilder::print_arr("int3", &**e, w),
275 AnnotType::Int4(e) => ElemBuilder::print_arr("int4", &**e, w),
276 AnnotType::Float(e) => ElemBuilder::print("float", e, w),
277 AnnotType::Float2(e) => ElemBuilder::print_arr("float2", e, w),
278 AnnotType::Float3(e) => ElemBuilder::print_arr("float3", &**e, w),
279 AnnotType::Float4(e) => ElemBuilder::print_arr("float4", &**e, w),
280 AnnotType::Float2x2(e) => ElemBuilder::print_arr("float2x2", &**e, w),
281 AnnotType::Float3x3(e) => ElemBuilder::print_arr("float3x3", &**e, w),
282 AnnotType::Float4x4(e) => ElemBuilder::print_arr("float4x4", &**e, w),
283 AnnotType::String(e) => ElemBuilder::print_str("string", e, w),
284 }
285 }
286}
287#[derive(Clone, Debug)]
290pub enum ParamType {
291 Float(f32),
293 Float2([f32; 2]),
295 Float3(Box<[f32; 3]>),
297 Float4(Box<[f32; 4]>),
299 Surface(Box<Surface>),
301 Sampler2D(Box<Sampler2D>),
303 Other(Box<Element>),
305}
306
307impl From<f32> for ParamType {
308 fn from(v: f32) -> Self {
309 Self::Float(v)
310 }
311}
312
313impl ParamType {
314 pub fn parse(e: &Element) -> Result<Option<Self>> {
316 Ok(Some(match e.name() {
317 "float" => Self::Float(parse_elem(e)?),
318 "float2" => Self::Float2(*parse_array_n(e)?),
319 "float3" => Self::Float3(parse_array_n(e)?),
320 "float4" => Self::Float4(parse_array_n(e)?),
321 Surface::NAME => Self::Surface(Surface::parse_box(e)?),
322 Sampler2D::NAME => Self::Sampler2D(Sampler2D::parse_box(e)?),
323 _ => Self::Other(Box::new(e.clone())),
324 }))
325 }
326
327 pub fn as_surface(&self) -> Option<&Surface> {
329 match self {
330 ParamType::Surface(s) => Some(s),
331 _ => None,
332 }
333 }
334
335 pub fn as_sampler2d(&self) -> Option<&Sampler2D> {
337 match self {
338 ParamType::Sampler2D(s) => Some(s),
339 _ => None,
340 }
341 }
342}
343
344impl XNodeWrite for ParamType {
345 fn write_to<W: Write>(&self, w: &mut XWriter<W>) -> Result<()> {
346 match self {
347 ParamType::Float(e) => ElemBuilder::print("float", e, w),
348 ParamType::Float2(e) => ElemBuilder::print_arr("float2", e, w),
349 ParamType::Float3(e) => ElemBuilder::print_arr("float3", &**e, w),
350 ParamType::Float4(e) => ElemBuilder::print_arr("float4", &**e, w),
351 ParamType::Surface(e) => e.write_to(w),
352 ParamType::Sampler2D(e) => e.write_to(w),
353 ParamType::Other(e) => XNodeWrite::write_to(e, w),
354 }
355 }
356}