makepad_shader_compiler/
shader_registry.rs

1use {
2    std::{
3        collections::{BTreeMap, HashSet, HashMap},
4        cell::{Cell, RefCell},
5    },
6    crate::{
7        //makepad_error_log::*,
8        makepad_live_compiler::*,
9        makepad_live_id::*,
10        shader_ast::*,
11        analyse::*,
12        shader_parser::{ShaderParser, ShaderParserDep},
13        builtin::{Builtin, generate_builtins},
14    }
15};
16
17
18pub struct ShaderRegistry {
19    pub all_fns: HashMap<FnPtr, FnDef>,
20    pub draw_shader_defs: HashMap<DrawShaderPtr, DrawShaderDef>,
21    pub structs: HashMap<StructPtr, StructDef>,
22    pub builtins: HashMap<Ident, Builtin>,
23    pub enums: HashMap<LiveType, ShaderEnum>,
24    pub const_gather_active: bool
25}
26
27pub struct ShaderEnum {
28    pub enum_name: LiveId,
29    pub variants: Vec<LiveId>
30}
31
32impl ShaderRegistry {
33    pub fn new(const_gather_active: bool) -> Self {
34        Self {
35            const_gather_active,
36            structs: HashMap::new(),
37            enums: HashMap::new(),
38            draw_shader_defs: HashMap::new(),
39            all_fns: HashMap::new(),
40            builtins: generate_builtins()
41        }
42    }
43}
44
45#[derive(Debug)]
46pub enum LiveNodeFindResult {
47    NotFound,
48    Component(LivePtr),
49    Struct(StructPtr),
50    Function(FnPtr),
51    PossibleStatic(StructPtr, FnPtr),
52    LiveValue(ValuePtr, TyLit),
53    Error(LiveError)
54}
55
56pub enum DrawShaderQuery {
57    DrawShader,
58    Geometry,
59}
60
61impl ShaderRegistry {
62    
63    pub fn flush_registry(&mut self){
64        self.all_fns.clear();
65        self.draw_shader_defs.clear();
66        self.structs.clear();
67    }
68    
69    pub fn register_enum(&mut self, live_type: LiveType, shader_enum: ShaderEnum) {
70        self.enums.insert(live_type, shader_enum);
71    }
72    
73    pub fn compute_const_table(&self, draw_shader_ptr: DrawShaderPtr/*, filter_file_id: LiveFileId*/) -> DrawShaderConstTable {
74        
75        let draw_shader_def = self.draw_shader_defs.get(&draw_shader_ptr).unwrap();
76        
77        let mut offsets = BTreeMap::new();
78        let mut table = Vec::new();
79        let mut offset = 0;
80        let mut table_index = BTreeMap::new();
81        
82        for callee in draw_shader_def.all_fns.borrow().iter() {
83            let fn_decl = self.all_fns.get(callee).unwrap();
84            //if fn_decl.span.file_id == filter_file_id {
85            let sub_table = fn_decl.const_table.borrow();
86            table.extend(sub_table.as_ref().unwrap().iter());
87            
88            for ct_span in fn_decl.const_table_spans.borrow().as_ref().unwrap().iter() {
89                table_index.insert(
90                    ct_span.token_id,
91                    ConstTableItem {
92                        offset: offset + ct_span.offset,
93                        slots: ct_span.slots
94                    }
95                );
96            }
97            offsets.insert(*callee, offset);
98            offset += sub_table.as_ref().unwrap().len();
99        }
100        
101        let size = table.len();
102        let align_gap = 4 - (size - ((size >> 2) << 2));
103        for _ in 0..align_gap {
104            table.push(0.0);
105        }
106        DrawShaderConstTable {
107            table,
108            offsets,
109            table_index
110        }
111    }
112    
113    pub fn fn_ident_from_ptr(&self, live_registry: &LiveRegistry, fn_node_ptr: FnPtr) -> Ident {
114        let node = live_registry.ptr_to_node(fn_node_ptr.0);
115        Ident(node.id)
116    }
117    
118    pub fn draw_shader_method_ptr_from_ident(&self, draw_shader_def: &DrawShaderDef, ident: Ident) -> Option<FnPtr> {
119        for fn_node_ptr in &draw_shader_def.methods {
120            let fn_decl = self.all_fns.get(fn_node_ptr).unwrap();
121            if fn_decl.ident == ident {
122                return Some(*fn_node_ptr);
123            }
124        }
125        None
126    }
127    
128    pub fn struct_method_ptr_from_ident(&self, struct_def: &StructDef, ident: Ident) -> Option<FnPtr> {
129        for fn_node_ptr in &struct_def.methods {
130            let fn_decl = self.all_fns.get(fn_node_ptr).unwrap();
131            if fn_decl.ident == ident {
132                return Some(*fn_node_ptr);
133            }
134        }
135        None
136    }
137    
138    pub fn draw_shader_method_decl_from_ident(&self, draw_shader_def: &DrawShaderDef, ident: Ident) -> Option<&FnDef> {
139        for fn_node_ptr in &draw_shader_def.methods {
140            let fn_decl = self.all_fns.get(fn_node_ptr).unwrap();
141            if fn_decl.ident == ident {
142                return Some(fn_decl)
143            }
144        }
145        None
146    }
147    
148    pub fn struct_method_decl_from_ident(&self, struct_def: &StructDef, ident: Ident) -> Option<&FnDef> {
149        for fn_node_ptr in &struct_def.methods {
150            let fn_decl = self.all_fns.get(fn_node_ptr).unwrap();
151            if fn_decl.ident == ident {
152                return Some(fn_decl)
153            }
154        }
155        None
156    }
157    
158    pub fn find_live_node_by_path(&self, live_registry: &LiveRegistry, base_ptr: LivePtr, ids: &[LiveId]) -> LiveNodeFindResult {
159        
160        let doc = &live_registry.ptr_to_doc(base_ptr);
161        
162        let ret = walk_recur(live_registry, None, base_ptr.file_id, base_ptr.generation, base_ptr.index as usize, &doc.nodes, ids);
163        return ret;
164        // ok so we got a node. great. now what
165        fn walk_recur(live_registry: &LiveRegistry, struct_ptr: Option<LivePtr>, file_id: LiveFileId, generation:LiveFileGeneration, index: usize, nodes: &[LiveNode], ids: &[LiveId]) -> LiveNodeFindResult {
166            let node = &nodes[index];
167            
168            if ids.len() != 0 && !node.value.is_class() && !node.value.is_clone() && !node.value.is_object() {
169                return LiveNodeFindResult::NotFound;
170            }
171            
172            let now_ptr = LivePtr {file_id, index: index as u32, generation};
173            //let first_def = node.origin.first_def().unwrap();
174            match node.value {
175                LiveValue::Bool(_) => {
176                    return LiveNodeFindResult::LiveValue(ValuePtr(now_ptr), TyLit::Bool)
177                },
178                LiveValue::Int64(_)=> {
179                    return LiveNodeFindResult::LiveValue(ValuePtr(now_ptr), TyLit::Int)
180                }
181                LiveValue::Float32(_)  => {
182                    return LiveNodeFindResult::LiveValue(ValuePtr(now_ptr), TyLit::Float)
183                }
184                LiveValue::Float64(_)  => {
185                    return LiveNodeFindResult::LiveValue(ValuePtr(now_ptr), TyLit::Float)
186                }
187                LiveValue::Color(_)  => {
188                    return LiveNodeFindResult::LiveValue(ValuePtr(now_ptr), TyLit::Vec4)
189                }
190                LiveValue::Vec2(_)  => {
191                    return LiveNodeFindResult::LiveValue(ValuePtr(now_ptr), TyLit::Vec2)
192                }
193                LiveValue::Vec3(_)  => {
194                    return LiveNodeFindResult::LiveValue(ValuePtr(now_ptr), TyLit::Vec3)
195                }
196                LiveValue::Vec4(_) => {
197                    return LiveNodeFindResult::LiveValue(ValuePtr(now_ptr), TyLit::Vec4)
198                }
199                LiveValue::Expr{..} => {
200                    // ok lets eval the expr to get a type
201                    
202                    if let Ok(ty) = Ty::from_live_node(live_registry, index, nodes){
203                        if let Some(ty_lit) = ty.maybe_ty_lit(){
204                            return LiveNodeFindResult::LiveValue(ValuePtr(now_ptr), ty_lit)
205                        }
206                    }
207                    return LiveNodeFindResult::Error(
208                        LiveError {
209                            origin: live_error_origin!(),
210                            message: format!("Type of eval result not valid for shader"),
211                            span: nodes[index].origin.token_id().unwrap().into()
212                        }
213                    );
214                }
215                LiveValue::DSL {token_start, ..} => {
216                    // lets get the first token
217                    let origin_doc = live_registry.token_id_to_origin_doc(node.origin.token_id().unwrap());
218                    match origin_doc.tokens[token_start as usize].token {
219                        LiveToken::Ident(live_id!(fn)) => {
220                            if let Some(struct_ptr) = struct_ptr {
221                                return LiveNodeFindResult::PossibleStatic(StructPtr(struct_ptr), FnPtr(now_ptr));
222                            }
223                            return LiveNodeFindResult::Function(FnPtr(now_ptr));
224                        }
225                        _ => LiveNodeFindResult::NotFound
226                    }
227                }
228                LiveValue::Class {..} => {
229                    if ids.len() == 0 {
230                        return LiveNodeFindResult::Component(now_ptr);
231                    }
232                    match nodes.child_by_name(index, ids[0].as_instance()) {
233                        Some(child_index) => {
234                            return walk_recur(live_registry, None, file_id, generation, child_index, nodes, &ids[1..])
235                        }
236                        None => {
237                            return LiveNodeFindResult::NotFound;
238                        }
239                    }
240                }
241                LiveValue::Clone{clone,..} => {
242                    if ids.len() == 0 {
243                        if clone == live_id!(struct) {
244                            return LiveNodeFindResult::Struct(StructPtr(now_ptr));
245                        }
246                        return LiveNodeFindResult::Component(now_ptr);
247                    }
248                    match nodes.child_by_name(index, ids[0].as_instance()) {
249                        Some(child_index) => {
250                            let struct_ptr = if clone == live_id!(struct) {
251                                Some(now_ptr)
252                            }
253                            else {
254                                None
255                            };
256                            return walk_recur(live_registry, struct_ptr, file_id,  generation, child_index, nodes, &ids[1..])
257                        }
258                        None => {
259                            return LiveNodeFindResult::NotFound;
260                        }
261                    }
262                }
263                LiveValue::Object => {
264                    if ids.len() == 0 {
265                        return LiveNodeFindResult::NotFound;
266                    }
267                    match nodes.child_by_name(index, ids[0].as_instance()) {
268                        Some(child_index) => {
269                            return walk_recur(live_registry, None, file_id,  generation,  child_index, nodes, &ids[1..])
270                        }
271                        None => {
272                            return LiveNodeFindResult::NotFound;
273                        }
274                    }
275                }
276                _ => {
277                    return LiveNodeFindResult::NotFound;
278                }
279            }
280        }
281    }
282    
283    pub fn analyse_deps(&mut self, live_registry: &LiveRegistry, deps: &[ShaderParserDep]) -> Result<(), LiveError> {
284        // recur on used types
285        for dep in deps {
286            match dep {
287                /*ShaderParserDep::Const(dep) => {
288                    self.analyse_const(live_registry, *dep) ?;
289                },*/
290                ShaderParserDep::Struct(dep) => {
291                    self.analyse_struct(live_registry, *dep) ?;
292                },
293                ShaderParserDep::Function(struct_ptr, fn_ptr) => {
294                    self.analyse_plain_fn(live_registry, *struct_ptr, *fn_ptr) ?
295                }
296            }
297        }
298        Ok(())
299    }
300    
301    
302    // lets compile the thing
303    pub fn analyse_plain_fn(&mut self, live_registry: &LiveRegistry, struct_ptr: Option<StructPtr>, fn_ptr: FnPtr) -> Result<(), LiveError> {
304        
305        if self.all_fns.get(&fn_ptr).is_some() {
306            return Ok(());
307        }
308        // alright lets parse and analyse a plain fn
309        let fn_node = live_registry.ptr_to_node(fn_ptr.0);
310        match fn_node.value {
311            LiveValue::DSL {token_start, token_count, expand_index} => {
312                let id = fn_node.id;
313                let mut parser_deps = Vec::new();
314                // lets parse this thing
315                let origin_doc = &live_registry.token_id_to_origin_doc(fn_node.origin.token_id().unwrap());
316                
317                let parser = ShaderParser::new(
318                    live_registry,
319                    self,
320                    origin_doc.get_tokens(token_start as usize, token_count as usize),
321                    &mut parser_deps,
322                    if let Some(struct_ptr) = struct_ptr {Some(FnSelfKind::Struct(struct_ptr))}else {None},
323                    expand_index.unwrap() as usize,
324                    fn_node.origin.token_id().unwrap().file_id().unwrap(),
325                    token_start as usize
326                    //Some(struct_full_ptr)
327                );
328                
329                let fn_def = parser.expect_plain_fn_def(
330                    fn_ptr,
331                    Ident(id),
332                ) ?;
333                self.all_fns.insert(fn_ptr, fn_def);
334                
335                self.analyse_deps(live_registry, &parser_deps) ?;
336                
337                // ok analyse the struct methods now.
338                let mut fa = FnDefAnalyser {
339                    live_registry,
340                    closure_return_ty: None,
341                    fn_def: self.all_fns.get(&fn_ptr).unwrap(),
342                    scopes: &mut Scopes::new(),
343                    shader_registry: self,
344                    is_inside_loop: false,
345                    options: ShaderAnalyseOptions {
346                        no_const_collapse: true,
347                        const_gather_active: self.const_gather_active
348                    }
349                };
350                fa.analyse_fn_decl() ?;
351                fa.analyse_fn_def() ?;
352                
353                Ok(())
354            }
355            _ => panic!()
356        }
357    }
358    
359    
360    // lets compile the thing
361    pub fn analyse_struct(&mut self, live_registry: &LiveRegistry, struct_ptr: StructPtr) -> Result<(), LiveError> {
362        
363        if self.structs.get(&struct_ptr).is_some() {
364            return Ok(());
365        }
366        
367        let (doc, struct_node) = live_registry.ptr_to_doc_node(struct_ptr.0);
368        
369        match struct_node.value {
370            LiveValue::Clone{clone,..} => {
371                if clone != live_id!(struct) {
372                    panic!()
373                }
374                let mut struct_def = StructDef {
375                    span: struct_node.origin.token_id().unwrap().into(),
376                    struct_refs: RefCell::new(None),
377                    fields: Vec::new(),
378                    methods: Vec::new()
379                };
380                
381                let mut parser_deps = Vec::new();
382                
383                // ok how do we iterate children of this node
384                let mut node_iter = doc.nodes.first_child(struct_ptr.node_index());
385                while let Some(node_index) = node_iter {
386                    let prop_ptr = struct_ptr.with_index(node_index);
387                    let prop = &doc.nodes[node_index];
388                    
389                    match prop.value {
390                        LiveValue::DSL {token_start, token_count, expand_index} => {
391                            let id = prop.id;
392                            let origin_doc = &live_registry.token_id_to_origin_doc(prop.origin.token_id().unwrap());
393                            
394                            let parser = ShaderParser::new(
395                                live_registry,
396                                self,
397                                origin_doc.get_tokens(token_start as usize, token_count as usize),
398                                &mut parser_deps,
399                                Some(FnSelfKind::Struct(struct_ptr)),
400                                expand_index.unwrap() as usize,
401                                prop.origin.token_id().unwrap().file_id().unwrap(),
402                                token_start as usize
403                                //Some(struct_full_ptr)
404                            );
405                            match origin_doc.tokens[token_start as usize].token {
406                                LiveToken::Ident(live_id!(fn)) => {
407                                    
408                                    let fn_def = parser.expect_method_def(
409                                        FnPtr(prop_ptr),
410                                        Ident(id),
411                                    ) ?;
412                                    // if we get false, this was not a method but could be static.
413                                    // statics need a pointer to their struct to resolve Self
414                                    // so we can't treat them purely as loose methods
415                                    if let Some(fn_def) = fn_def {
416                                        struct_def.methods.push(fn_def.fn_ptr);
417                                        self.all_fns.insert(fn_def.fn_ptr, fn_def);
418                                    }
419                                }
420                                _ => {
421                                    return Err(LiveError {
422                                        origin: live_error_origin!(),
423                                        span: prop.origin.token_id().unwrap().into(),
424                                        message: format!("Unexpected DSL node")
425                                    })
426                                    /*
427                                    let def = parser.expect_field(Ident(id), VarDefPtr(prop_ptr)) ?;
428                                    if let Some(def) = def {
429                                        struct_def.fields.push(def);
430                                    }*/
431                                }
432                            }
433                        },
434                        LiveValue::Id(type_name) if live_registry.get_node_prefix(prop.origin) == Some(live_id!(field)) => {
435                            // lets fetch the span
436                            
437                            if let Some(ty_lit) = TyLit::from_id(type_name) {
438                                struct_def.fields.push(StructFieldDef {
439                                    var_def_ptr: VarDefPtr(prop_ptr),
440                                    span:prop.origin.token_id().unwrap().into(),
441                                    ident: Ident(prop.id),
442                                    ty_expr: ty_lit.to_ty().to_ty_expr()
443                                })
444                            }
445                            else {
446                                // TODO support structs as fields here
447                                return Err(LiveError {
448                                    origin: live_error_origin!(),
449                                    span: prop.origin.token_id().unwrap().into(),
450                                    message: format!("Type not found for struct field {}", type_name)
451                                })
452                            }
453                        },
454                        _ => {
455                            return Err(LiveError {
456                                origin: live_error_origin!(),
457                                span: prop.origin.token_id().unwrap().into(),
458                                message: format!("Cannot use {:?} in struct", prop.value)
459                            })
460                        }
461                    }
462                    node_iter = doc.nodes.next_child(node_index);
463                }
464                // we should store the structs
465                self.structs.insert(struct_ptr, struct_def);
466                
467                self.analyse_deps(live_registry, &parser_deps) ?;
468                
469                // ok analyse the struct methods now.
470                let mut sa = StructAnalyser {
471                    live_registry,
472                    struct_def: self.structs.get(&struct_ptr).unwrap(),
473                    scopes: &mut Scopes::new(),
474                    shader_registry: self,
475                    options: ShaderAnalyseOptions {
476                        no_const_collapse: true,
477                        const_gather_active: self.const_gather_active
478                    }
479                };
480                sa.analyse_struct() ?;
481                //println!("STRUCT");
482                
483            }
484            _ => ()
485        }
486        
487        Ok(())
488    }
489    
490    // lets compile the thing
491    pub fn analyse_draw_shader<F>(&mut self, live_registry: &LiveRegistry, draw_shader_ptr: DrawShaderPtr, mut ext_self: F) -> Result<(),
492        LiveError>
493    where F: FnMut(&LiveRegistry, &ShaderRegistry, TokenSpan, DrawShaderQuery, LiveType, &mut DrawShaderDef)
494    {
495        let mut draw_shader_def = DrawShaderDef::default();
496        
497        // lets insert the 2D drawshader uniforms
498        draw_shader_def.add_uniform(id_lut!(camera_projection), id_lut!(pass), Ty::Mat4, TokenSpan::default());
499        draw_shader_def.add_uniform(id_lut!(camera_projection_r), id_lut!(pass), Ty::Mat4, TokenSpan::default());
500        draw_shader_def.add_uniform(id_lut!(camera_view), id_lut!(pass), Ty::Mat4, TokenSpan::default());
501        draw_shader_def.add_uniform(id_lut!(camera_view_r), id_lut!(pass), Ty::Mat4, TokenSpan::default());
502        draw_shader_def.add_uniform(id_lut!(depth_projection), id_lut!(pass), Ty::Mat4, TokenSpan::default());
503        draw_shader_def.add_uniform(id_lut!(depth_projection_r), id_lut!(pass), Ty::Mat4, TokenSpan::default());
504        draw_shader_def.add_uniform(id_lut!(depth_view), id_lut!(pass), Ty::Mat4, TokenSpan::default());
505        draw_shader_def.add_uniform(id_lut!(depth_view_r), id_lut!(pass), Ty::Mat4, TokenSpan::default());
506        draw_shader_def.add_uniform(id_lut!(camera_inv), id_lut!(pass), Ty::Mat4, TokenSpan::default());
507        draw_shader_def.add_uniform(id_lut!(dpi_factor), id_lut!(pass), Ty::Float, TokenSpan::default());
508        draw_shader_def.add_uniform(id_lut!(dpi_dilate), id_lut!(pass), Ty::Float, TokenSpan::default());
509        draw_shader_def.add_uniform(id_lut!(time), id_lut!(pass), Ty::Float, TokenSpan::default());
510        draw_shader_def.add_uniform(id_lut!(view_transform), id_lut!(draw_list), Ty::Mat4, TokenSpan::default());
511        draw_shader_def.add_uniform(id_lut!(view_clip), id_lut!(draw_list), Ty::Vec4, TokenSpan::default());
512        draw_shader_def.add_uniform(id_lut!(view_shift), id_lut!(draw_list), Ty::Vec2, TokenSpan::default());
513        draw_shader_def.add_uniform(id_lut!(draw_zbias), id_lut!(draw_call), Ty::Float, TokenSpan::default());
514        
515        
516        draw_shader_def.ignore_idents = vec![Ident(live_id!(camera_projection_r)), Ident(live_id!(camera_view_r))];
517        
518        let (doc, class_node) = live_registry.ptr_to_doc_node(draw_shader_ptr.0);
519
520        match &class_node.value {
521            LiveValue::Class {live_type, ..} => {
522                
523                ext_self(
524                    live_registry,
525                    self,
526                    class_node.origin.token_id().unwrap().into(),
527                    DrawShaderQuery::DrawShader,
528                    *live_type,
529                    &mut draw_shader_def
530                );
531                
532                let mut parser_deps = Vec::new();
533                
534                let mut node_iter = doc.nodes.first_child(draw_shader_ptr.node_index());
535                let mut method_set = HashSet::new();
536                while let Some(node_index) = node_iter {
537                    let prop = &doc.nodes[node_index];
538                    let prop_ptr = draw_shader_ptr.with_index(node_index);
539                    if prop.id == live_id!(debug_id){
540                        node_iter = doc.nodes.next_child(node_index);
541                        continue;
542                    }
543                    match prop.value {
544                        LiveValue::Bool(_) |
545                        LiveValue::Id(_)  |
546                        LiveValue::Int64(_) |
547                        LiveValue::Float32(_) |
548                        LiveValue::Float64(_) |
549                        LiveValue::Color(_) |
550                        LiveValue::Vec2(_) |
551                        LiveValue::Vec3(_) |
552                        LiveValue::Vec4(_) | 
553                        LiveValue::Expr{..} => {
554                            //let before = live_registry.get_node_prefix(prop.origin);
555                            if prop.origin.prop_type() != LivePropType::Field{
556                                /*if before == Some(live_id!(const)){
557                                    node_iter = doc.nodes.next_child(node_index);
558                                    continue;
559                                }*/
560                                return Err(LiveError {
561                                    origin: live_error_origin!(),
562                                    span: prop.origin.token_id().unwrap().into(),
563                                    message: format!("Can only support field colon : values don't use =")
564                                })
565                            }
566                            if prop.id == live_id!(size){
567                                
568                            }
569                            let first_def = prop.origin.first_def().unwrap();
570                            let before = live_registry.get_node_prefix(prop.origin);
571                           
572                            let ty = match ShaderTy::from_live_node(live_registry, node_index, &doc.nodes){
573                                Ok(ty)=>ty,
574                                Err(_)=>{
575                                    // just ignore it
576                                    node_iter = doc.nodes.next_child(node_index);
577                                    continue;
578                                    //return Err(err)
579                                }
580                            };
581                            let ty_expr = ty.to_ty_expr();
582                            match before {
583                                Some(live_id!(geometry)) => {
584                                    draw_shader_def.fields.push(DrawShaderFieldDef {
585                                        kind: DrawShaderFieldKind::Geometry {
586                                            is_used_in_pixel_shader: Cell::new(false),
587                                            var_def_ptr: Some(VarDefPtr(prop_ptr)),
588                                        },
589                                        span: first_def.into(),
590                                        ident: Ident(prop.id),
591                                        ty_expr
592                                    });
593                                },
594                                Some(live_id!(instance)) => {
595                                    let decl = DrawShaderFieldDef {
596                                        kind: DrawShaderFieldKind::Instance {
597                                            is_used_in_pixel_shader: Cell::new(false),
598                                            live_field_kind: LiveFieldKind::Live,
599                                            var_def_ptr: Some(VarDefPtr(prop_ptr)),
600                                        },
601                                        span: first_def.into(),
602                                        ident: Ident(prop.id),
603                                        ty_expr
604                                    };
605                                    // find from the start the first instancefield
606                                    // without a var_def_node_prt
607                                    if let Some(index) = draw_shader_def.fields.iter().position( | field | {
608                                        if let DrawShaderFieldKind::Instance {var_def_ptr, ..} = field.kind {
609                                            if var_def_ptr.is_none() {
610                                                return true
611                                            }
612                                        }
613                                        false
614                                    }) {
615                                        draw_shader_def.fields.insert(index, decl);
616                                    }
617                                    else {
618                                        draw_shader_def.fields.push(decl);
619                                    }
620                                    
621                                },
622                                Some(live_id!(uniform)) => {
623                                    draw_shader_def.fields.push(DrawShaderFieldDef {
624                                        kind: DrawShaderFieldKind::Uniform {
625                                            var_def_ptr: Some(VarDefPtr(prop_ptr)),
626                                            block_ident: Ident(live_id!(user)),
627                                        },
628                                        span: first_def.into(),
629                                        ident: Ident(prop.id),
630                                        ty_expr
631                                    });
632                                },
633                                Some(live_id!(varying)) => {
634                                    draw_shader_def.fields.push(DrawShaderFieldDef {
635                                        kind: DrawShaderFieldKind::Varying {
636                                            var_def_ptr: VarDefPtr(prop_ptr),
637                                        },
638                                        span: first_def.into(),
639                                        ident: Ident(prop.id),
640                                        ty_expr
641                                    });
642                                },
643                                Some(live_id!(texture)) => {
644                                    draw_shader_def.fields.push(DrawShaderFieldDef {
645                                        kind: DrawShaderFieldKind::Texture {
646                                            var_def_ptr: Some(VarDefPtr(prop_ptr)),
647                                        },
648                                        span: first_def.into(),
649                                        ident: Ident(prop.id),
650                                        ty_expr
651                                    });
652                                }
653                                None => {
654                                    if let LiveValue::Bool(val) = prop.value {
655                                        match prop.id {
656                                            live_id!(debug) => {
657                                                draw_shader_def.flags.debug = val;
658                                            }
659                                            live_id!(draw_call_compare) => {
660                                                draw_shader_def.flags.draw_call_nocompare = val;
661                                            }
662                                            live_id!(draw_call_always) => {
663                                                draw_shader_def.flags.draw_call_always = val;
664                                            }
665                                            _ => {} // could be input value
666                                        }
667                                    }
668                                },
669                                _ => {
670                                    return Err(LiveError {
671                                        origin: live_error_origin!(),
672                                        span: first_def.into(),
673                                        message: format!("Unexpected variable prefix {:?}", before)
674                                    })
675                                }
676                            };
677                        }
678                        LiveValue::Class {live_type, ..} => {
679                            if prop.id == live_id!(geometry) {
680                                ext_self(
681                                    live_registry,
682                                    self,
683                                    prop.origin.token_id().unwrap().into(),
684                                    DrawShaderQuery::Geometry,
685                                    live_type,
686                                    &mut draw_shader_def
687                                );
688                            }
689                        }
690                        LiveValue::DSL {token_start, token_count, expand_index} => {
691                            let origin_doc = live_registry.token_id_to_origin_doc(prop.origin.token_id().unwrap());
692                            
693                            let parser = ShaderParser::new(
694                                live_registry,
695                                self,
696                                origin_doc.get_tokens(token_start as usize, token_count as usize),
697                                &mut parser_deps,
698                                Some(FnSelfKind::DrawShader(draw_shader_ptr)),
699                                expand_index.unwrap() as usize,
700                                prop.origin.token_id().unwrap().file_id().unwrap(),
701                                token_start as usize
702                                //None
703                            );
704                            
705                            let token = &origin_doc.tokens[token_start as usize];
706                            match token.token {
707                                LiveToken::Ident(live_id!(fn)) => {
708                                    let fn_def = parser.expect_method_def(
709                                        FnPtr(prop_ptr),
710                                        Ident(prop.id),
711                                    ) ?;
712                                    if let Some(fn_def) = fn_def {
713                                        method_set.insert(prop.id);
714                                        draw_shader_def.methods.push(fn_def.fn_ptr);
715                                        self.all_fns.insert(fn_def.fn_ptr, fn_def);
716                                    }
717                                }
718                                _ => {
719                                    return Err(LiveError {
720                                        origin: live_error_origin!(),
721                                        span: token.span.into(),
722                                        message: format!("Unexpected in shader body {}", token)
723                                    })
724                                    /*
725                                    let decl = parser.expect_self_decl(Ident(prop.id), prop_ptr) ?;
726                                    if let Some(decl) = decl {
727                                        // lets see where to inject this.
728                                        // if its an instance var it needs to
729                                        // go above the var_def_node_ptr one
730                                        if let DrawShaderFieldKind::Instance {..} = decl.kind {
731                                            // find from the start the first instancefield
732                                            // without a var_def_node_prt
733                                            if let Some(index) = draw_shader_def.fields.iter().position( | field | {
734                                                if let DrawShaderFieldKind::Instance {var_def_ptr, ..} = field.kind {
735                                                    if var_def_ptr.is_none() {
736                                                        return true
737                                                    }
738                                                }
739                                                false
740                                            }) {
741                                                draw_shader_def.fields.insert(index, decl);
742                                            }
743                                            else {
744                                                draw_shader_def.fields.push(decl);
745                                            }
746                                        }
747                                        else {
748                                            draw_shader_def.fields.push(decl);
749                                        }
750                                    }*/
751                                }
752                            }
753                            
754                        },
755                        _ => ()
756                    }
757                    node_iter = doc.nodes.next_child(node_index);
758                }
759                // lets check for duplicate fields
760                for i in 0..draw_shader_def.fields.len() {
761                    for j in (i + 1)..draw_shader_def.fields.len() {
762                        let field_a = &draw_shader_def.fields[i];
763                        let field_b = &draw_shader_def.fields[j];
764                        if field_a.ident == field_b.ident && !field_a.ident.0.is_empty() && 
765                            !draw_shader_def.ignore_idents.contains(&field_a.ident){
766                            //let doc = live_registry.ptr_to_doc(draw_shader_ptr.0);
767                            //doc.nodes.to_string(draw_shader_ptr.index as usize,100)
768                            
769                            return Err(LiveError {
770                                origin: live_error_origin!(),
771                                span: field_a.span.into(),
772                                message: format!("Field double declaration  {}",field_a.ident)
773                            })
774                        }
775                    }
776                }
777                
778                self.draw_shader_defs.insert(draw_shader_ptr, draw_shader_def);
779                
780                if !method_set.contains(&live_id!(vertex)) {
781                    return Err(LiveError {
782                        origin: live_error_origin!(),
783                        span: class_node.origin.token_id().unwrap().into(),
784                        message: format!("analyse_draw_shader missing vertex method")
785                    })
786                }
787                
788                if !method_set.contains(&live_id!(fragment)) {
789                    return Err(LiveError {
790                        origin: live_error_origin!(),
791                        span: class_node.origin.token_id().unwrap().into(),
792                        message: format!("analyse_draw_shader missing fragment method")
793                    })
794                }
795                
796                self.analyse_deps(live_registry, &parser_deps) ?;
797                
798                let draw_shader_def = self.draw_shader_defs.get(&draw_shader_ptr).unwrap();
799                let mut sa = DrawShaderAnalyser {
800                    live_registry,
801                    shader_registry: self,
802                    draw_shader_def: draw_shader_def,
803                    scopes: &mut Scopes::new(),
804                    options: ShaderAnalyseOptions {
805                        no_const_collapse: true,
806                        const_gather_active: self.const_gather_active
807                    }
808                };
809                sa.analyse_shader() ?;
810                // ok we have all structs
811                return Ok(())
812            }
813            x => return Err(LiveError {
814                origin: live_error_origin!(),
815                span: class_node.origin.token_id().unwrap().into(),
816                message: format!("analyse_draw_shader could not find shader class {:?}", x)
817            })
818        }
819    }
820    
821}