Пример #1
0
        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);
        }
Пример #2
0
 internal void DelVar(PiVar v) {
   _vars.Remove(v.owner);
 }
Пример #3
0
 internal PiVar GetVar(Topic t, bool create, bool refresh = false) {
   PiVar v;
   if(!_vars.TryGetValue(t, out v)) {
     if(create) {
       v = new PiVar(t);
       _vars[t] = v;
       _rLayerVars.Add(v);
     } else {
       v = null;
     }
   } else if(refresh) {
     _rLayerVars.Add(v);
   }
   return v;
 }
Пример #4
0
        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);
        }
Пример #5
0
 internal PiLink(PiVar ip, PiVar op)
 {
     input  = ip;
     output = op;
 }
Пример #6
0
 public void changed(SubRec sr, Perform p) {
   if(_owner == null) {
     return;
   }
   if(p.art == Perform.Art.remove) {
     _owner.Remove(p.prim);
   } else if(p.art == Perform.Art.changed || p.art==Perform.Art.subscribe) {
     if(p.src.vType == typeof(PiAlias)) {
       PiAlias al = p.src.As<PiAlias>();
       if(p.src == _ipTopic) {
         input.DelCont(this);
         input = al.origin;
         al.AddLink(this);
         input.AddCont(this);
       } else if(p.src == _opTopic) {
         if(al.origin.ip) {
           throw new ArgumentException(string.Format("{0} already hat source", _opTopic.path));
         }
         output.DelCont(this);
         output = al.origin;
         al.AddLink(this);
         output.AddCont(this);
       } else {
         return;
       }
     } else if(p.src != input.owner) {
       return;
     }
     if(input.layer!=0 || input.owner._value.Defined) {
       output.owner._value=input.owner._value;
       if(p.src==input.owner) {
         var c=Perform.Create(output.owner, Perform.Art.changed, this.owner);
         c.o=input.owner._value;
         PLC.instance.DoCmd(c, true);
       }
     }
   }
 }