Пример #1
0
        public void Analyse()
        {
            //利用并查集找出所有连通块,在逻辑上,对于每个连通块,块上所有点都属于同一端点,每一个连通块都属不同端点
            {
                Dictionary <G_Pin, G_Pin> Pre = new Dictionary <G_Pin, G_Pin>();              //这一段效率或许不高,暂时不进行处理,记录
                G_Pin find(G_Pin a)
                {
                    if (!Pre[a].Equals(a))
                    {
                        return(find(Pre[a]));
                    }
                    return(Pre[a]);                   //也就是自身
                }

                G_Pin find_compress(G_Pin a)                //压缩/查询并查集
                {
                    if (!Pre[a].Equals(a))
                    {
                        Pre[a] = find_compress(Pre[a]);
                    }
                    return(Pre[a]);
                }

                void join(G_Pin a, G_Pin b)                //连接
                {
                    G_Pin fa = find_compress(a);
                    G_Pin fb = find_compress(b);

                    if (!fa.Equals(fb))
                    {
                        Pre[fb] = fa;
                    }
                }

                void note(DCSimulator.Components.Node node, G_Pin pre)                //记录
                {
                    var r = Pre.Keys.Where(p => find(p).Equals(pre));

                    foreach (var c in r)
                    {
                        Ports[c] = node;
                    }
                }

                foreach (var cb in Components.ToArray())                //显式、用缆线连接
                {
                    foreach (var c in cb.Pins)
                    {
                        Pre[c] = c;
                    }
                }
                foreach (var c in Pre.Keys.ToArray())
                {
                    foreach (var cc in Pre.Keys.ToArray().Where(p => p.RingPosition == c.RingPosition && !p.Equals(c)))                    //隐式、引脚叠合连接
                    {
                        join(c, cc);
                    }
                }
                foreach (var cb in Cables.ToArray())
                {
                    join(cb.P1, cb.P2);
                }
                foreach (var pr in Pre.Keys)
                {
                    if (Pre[pr].Equals(pr))                    //连通块
                    {
                        note(Circuit.NewNode(), pr);           //新的块
                    }
                }
            }
            //加载控件
            {
                foreach (var c in Components.Where(c => c is G_Chip).ToArray())
                {
                    G_Chip  cc  = c as G_Chip;
                    Circuit tmp = null;
                    var     f   = new System.IO.BinaryReader(new System.IO.MemoryStream(cc.Data.Data));
                    tmp = Circuit.FromStream(f);
                    f.Close();
                    List <int> a = new List <int>();
                    foreach (var p in tmp.Nodes)
                    {
                        var t = cc.ToNodes.Where(y => y.Value == p.Index);
                        foreach (var tt in t)
                        {
                            a.Add(p.Index);
                            Ports[tt.Key].AllCombineTo(p);
                        }
                    }
                    for (int i = 0; i < tmp.Nodes.Count; i++)
                    {
                        if (a.Contains(i))
                        {
                            continue;
                        }
                        Circuit.Nodes.Add(tmp.Nodes[i]);
                    }
                    for (int i = 0; i < Circuit.Nodes.Count; i++)
                    {
                        Circuit.Nodes[i].Index = i;
                    }
                    Circuit.Components.AddRange(tmp.Components);
                }
                foreach (var c in Components.ToArray())
                {
                    /*if (c is G_Chip)
                     * {
                     *      G_Chip cc = c as G_Chip;
                     *      Circuit tmp = null;
                     *      var f = new System.IO.BinaryReader(new System.IO.MemoryStream(cc.Data.Data));
                     *      Dictionary<int, DCSimulator.Components.Node> a = new Dictionary<int, DCSimulator.Components.Node>();
                     *      foreach (var p in cc.Pins)
                     *      {
                     *              var t = cc.ToNodes[p];
                     *              a[t] = Ports[p];
                     *              //Ports[p].CombineTo(tmp.Nodes[t]);
                     *      }
                     *      tmp = Circuit.FromStream(f, a);
                     *      f.Close();
                     *      for (int i = 0; i < tmp.Nodes.Count; i++)
                     *      {
                     *              if (a.Keys.Contains(i)) continue;
                     *              Circuit.Nodes.Add(tmp.Nodes[i]);
                     *      }
                     *      for (int i = 0; i < Circuit.Nodes.Count; i++)
                     *      {
                     *              Circuit.Nodes[i].Index = i;
                     *      }
                     *      Circuit.Components.AddRange(tmp.Components);
                     * }
                     * else */
                    if (c is G_Switch)
                    {
                        var sc = c as G_Switch;
                        var sw = new DCSimulator.Components.Switch(Circuit);
                        if (Ports.ContainsKey(sc.Pin))
                        {
                            sw.Output = Ports[sc.Pin];
                        }
                        Circuit.Components.Add(sw);
                        sc.StateFlip = b =>
                        {
                            if (b)
                            {
                                sw.TurnON();
                            }
                            else
                            {
                                sw.TurnOff();
                            }
                        };
                    }
                    else if (c is G_Detector)
                    {
                        var sc = c as G_Detector;
                        var sw = new DCSimulator.Components.Detector(Circuit);
                        if (Ports.ContainsKey(sc.Pin))
                        {
                            sw.Input_1 = Ports[sc.Pin];
                        }
                        Circuit.Components.Add(sw);
                        sc.UpdateEvent = () =>
                        {
                            sc.Powered = sw.Input_1.Value;
                        };
                    }
                    else if (c is G_Pulse)
                    {
                        var sc = c as G_Pulse;
                        var sw = new DCSimulator.Components.Pulse(Circuit)
                        {
                            Delay = sc.Delay, Signal = sc.InitialEL
                        };
                        if (Ports.ContainsKey(sc.Pin))
                        {
                            sw.Output = Ports[sc.Pin];
                        }
                        Circuit.Components.Add(sw);
                    }
                    else if (c is G_Delayer)
                    {
                        var sc = c as G_Delayer;
                        var sw = new DCSimulator.Components.Delayer(Circuit)
                        {
                            Delay = sc.Delay
                        };
                        if (Ports.ContainsKey(sc.IN))
                        {
                            sw.Input = Ports[sc.IN];
                        }
                        if (Ports.ContainsKey(sc.OUT))
                        {
                            sw.Output = Ports[sc.OUT];
                        }
                        Circuit.Components.Add(sw);
                    }
                    else if (c is G_Gate)
                    {
                        var gc = c as G_Gate;
                        switch (gc.GateType)
                        {
                        case "OR":                                //或门
                        {
                            var g_or = gc as G_Gate_Binary;
                            var or   = new DCSimulator.Components.Gate_OR(Circuit, "OR_None");
                            if (Ports.ContainsKey(g_or.IN_1))
                            {
                                or.Input_1 = Ports[g_or.IN_1];
                            }
                            if (Ports.ContainsKey(g_or.IN_2))
                            {
                                or.Input_2 = Ports[g_or.IN_2];
                            }
                            if (Ports.ContainsKey(g_or.OUT))
                            {
                                or.Output = Ports[g_or.OUT];
                            }
                            Circuit.Components.Add(or);
                        }
                        break;

                        case "NOT":                                //非门
                        {
                            var g_not = gc as G_Gate_Unitary;
                            var not   = new DCSimulator.Components.Gate_NOT(Circuit, "NOT_None");

                            if (Ports.ContainsKey(g_not.IN))
                            {
                                not.Input_1 = Ports[g_not.IN];
                            }
                            if (Ports.ContainsKey(g_not.OUT))
                            {
                                not.Output = Ports[g_not.OUT];
                            }
                            Circuit.Components.Add(not);
                        }
                        break;

                        case "AND":                                //与门
                        {
                            var g_and = gc as G_Gate_Binary;
                            var and   = new DCSimulator.Components.Gate_AND(Circuit, "AND_None");

                            if (Ports.ContainsKey(g_and.IN_1))
                            {
                                and.Input_1 = Ports[g_and.IN_1];
                            }
                            if (Ports.ContainsKey(g_and.IN_2))
                            {
                                and.Input_2 = Ports[g_and.IN_2];
                            }
                            if (Ports.ContainsKey(g_and.OUT))
                            {
                                and.Output = Ports[g_and.OUT];
                            }
                            Circuit.Components.Add(and);
                        }
                        break;

                        case "NAND":                                //与非门
                        {
                            var g_and = gc as G_Gate_Binary;
                            var and   = new DCSimulator.Components.Gate_NAND(Circuit, "NAND_None");

                            if (Ports.ContainsKey(g_and.IN_1))
                            {
                                and.Input_1 = Ports[g_and.IN_1];
                            }
                            if (Ports.ContainsKey(g_and.IN_2))
                            {
                                and.Input_2 = Ports[g_and.IN_2];
                            }
                            if (Ports.ContainsKey(g_and.OUT))
                            {
                                and.Output = Ports[g_and.OUT];
                            }
                            Circuit.Components.Add(and);
                        }
                        break;

                        case "NOR":                                //或非门门
                        {
                            var g_and = gc as G_Gate_Binary;
                            var and   = new DCSimulator.Components.Gate_NOR(Circuit, "NOR_None");

                            if (Ports.ContainsKey(g_and.IN_1))
                            {
                                and.Input_1 = Ports[g_and.IN_1];
                            }
                            if (Ports.ContainsKey(g_and.IN_2))
                            {
                                and.Input_2 = Ports[g_and.IN_2];
                            }
                            if (Ports.ContainsKey(g_and.OUT))
                            {
                                and.Output = Ports[g_and.OUT];
                            }
                            Circuit.Components.Add(and);
                        }
                        break;

                        case "XOR":                                //或非门门
                        {
                            var g_and = gc as G_Gate_Binary;
                            var and   = new DCSimulator.Components.Gate_XOR(Circuit, "XOR_None");

                            if (Ports.ContainsKey(g_and.IN_1))
                            {
                                and.Input_1 = Ports[g_and.IN_1];
                            }
                            if (Ports.ContainsKey(g_and.IN_2))
                            {
                                and.Input_2 = Ports[g_and.IN_2];
                            }
                            if (Ports.ContainsKey(g_and.OUT))
                            {
                                and.Output = Ports[g_and.OUT];
                            }
                            Circuit.Components.Add(and);
                        }
                        break;
                        }
                    }
                }
            }
        }