internal PiVar GetVar(Topic t, bool create) { PiVar v; if(!_vars.TryGetValue(t, out v)) { if(create) { v=new PiVar(t); _vars[t]=v; } else { v=null; } } return v; }
public void Start() { Queue<PiVar> vQu=new Queue<PiVar>(_vars.Values); PiVar v1, v2; while(vQu.Count>0) { v1=vQu.Dequeue(); if(v1._owner.vType==typeof(Topic)) { if(!_vars.TryGetValue(v1._owner.As<Topic>(), out v2)) { v2=new PiVar(v1._owner.As<Topic>()); _vars[v1._owner.As<Topic>()]=v2; vQu.Enqueue(v2); } v1.gray=true; var l=new PiLink(v2, v1); v1._links.Add(l); v2._links.Add(l); } else if(v1.dir==true) { v1.gray=true; } } vQu=new Queue<PiVar>(_vars.Values.Where(z => z.gray==false)); do { while(vQu.Count>0) { v1=vQu.Dequeue(); if(v1.layer==0) { v1.layer=1; v1.calcPath=new PiBlock[0]; } foreach(var l in v1._links.Where(z => z.input==v1)) { l.layer=v1.layer; l.output.layer=l.layer; l.output.calcPath=v1.calcPath; vQu.Enqueue(l.output); } if(v1.dir==false && v1.block!=null) { if(v1.calcPath.Contains(v1.block)) { if(v1.layer>0) { v1.layer=-v1.layer; } X13.lib.Log.Debug("{0} make loop", v1._owner.path); } else if(v1.block._pins.Where(z => z.Value.dir==false).All(z => z.Value.layer>=0)) { v1.block.layer=v1.block._pins.Where(z => z.Value.dir==false).Max(z => z.Value.layer)+1; v1.block.calcPath=v1.block.calcPath.Union(v1.calcPath).ToArray(); foreach(var v3 in v1.block._pins.Where(z => z.Value.dir==true).Select(z => z.Value)) { v3.layer=v1.block.layer; v3.calcPath=v1.block.calcPath; if(!vQu.Contains(v3)) { vQu.Enqueue(v3); } } } } } if(vQu.Count==0 && _blocks.Any(z => z.layer==0)) { // break a one loop in the graph var bl=_blocks.Where(z => z.layer<0).Min(); foreach(var ip in bl._pins.Select(z => z.Value).Where(z => z.dir==false && z.layer>0)) { bl.calcPath=bl.calcPath.Union(ip.calcPath).ToArray(); } bl.layer=bl._pins.Select(z => z.Value).Where(z => z.dir==false && z.layer>0).Max(z => z.layer)+1; foreach(var v3 in bl._pins.Select(z => z.Value).Where(z => z.dir==true)) { v3.layer=bl.layer; v3.calcPath=bl.calcPath; if(!vQu.Contains(v3)) { vQu.Enqueue(v3); } } } } while(vQu.Count>0); }