예제 #1
0
        /// <summary>
        /// 得到指定 POE 文件的功能块描述信息。
        /// </summary>
        /// <param name="fileName">POE 文件名称</param>
        /// <param name="reader">文本文件读对象</param>
        /// <returns>功能块描述信息,null 表示失败。</returns>
        public static ViPOEBlockType GetBlockType(string fileName, TextReader reader)
        {
            ViPOEBlockType blockType = null;
            ViConnType     connType  = null;
            int            lineIndex = 0;
            // 0x00: 没有读取到功能块开始
            // 0x01: 读取到功能块开始
            // 0x21: 开始 INPUT
            // 0x22: 开始 OUTPUT
            // 0x23: 开始 IN_OUT
            int stage = 0;

            while (true)
            {
                string line = reader.ReadLine();
                if (line == null)
                {
                    break;
                }
                ++lineIndex;

                line = line.Trim();
                if (string.IsNullOrEmpty(line))
                {
                    continue;
                }

                if (stage == 0x00)
                {
                    if (line.StartsWith("FUNCTION_BLOCK ", StringComparison.OrdinalIgnoreCase))
                    {
                        connType = ViConnType.Parse(line.Substring(15), ViTypeCreation.None);
                        if (connType != null && connType.Type == null)
                        {
                            blockType         = new ViPOEBlockType(connType.Name, null);
                            blockType.Comment = connType.Comment;
                            //
                            stage = 0x01;
                        }
                        else
                        {
                            Trace.WriteLine(string.Format("{0}({1}): Invalid FUNCTION_BLOCK declaration!", fileName, lineIndex));
                        }
                    }
                    //else if (line.StartsWith("PROGRAM ", StringComparison.OrdinalIgnoreCase))
                    //{
                    //    connType = ViConnType.Parse(line.Substring(8), ViTypeCreation.None);
                    //    if (connType != null && connType.Type == null)
                    //    {
                    //        blockType = new ViPOEBlockType(connType.Name, null);
                    //        blockType.Comment = connType.Comment;
                    //        //
                    //        stage = 0x01;
                    //    }
                    //    else
                    //    {
                    //        Trace.WriteLine(string.Format("{0}({1}): Invalid PROGRAM declaration!", fileName, lineIndex));
                    //    }
                    //}
                    else if (line.StartsWith("FUNCTION ", StringComparison.OrdinalIgnoreCase))
                    {
                        connType = ViConnType.Parse(line.Substring(9), ViTypeCreation.Create);
                        if (connType != null && connType.Type != null)
                        {
                            blockType         = new ViPOEBlockType(connType.Name, connType.Type);
                            blockType.Comment = connType.Comment;
                            //
                            stage = 0x01;
                        }
                        else
                        {
                            Trace.WriteLine(string.Format("{0}({1}): Invalid FUNCTION declaration!", fileName, lineIndex));
                        }
                    }
                }
                else if (stage >= 0x01)
                {
                    if (stage == 0x01 && line.EndsWith("*)") &&
                        line.StartsWith("(* task usage:", StringComparison.OrdinalIgnoreCase))
                    {
                        blockType.ModesDecl = line.Substring(14, line.Length - 16);
                    }
                    else if (line.StartsWith(ViTextFile.CommentBegin))
                    {
                        // 注释行
                    }
                    else if (line.StartsWith("VAR_INPUT", StringComparison.OrdinalIgnoreCase))
                    {
                        stage = 0x21;
                    }
                    else if (line.StartsWith("VAR_OUTPUT", StringComparison.OrdinalIgnoreCase))
                    {
                        stage = 0x22;
                    }
                    else if (line.StartsWith("VAR_IN_OUT", StringComparison.OrdinalIgnoreCase))
                    {
                        stage = 0x23;
                    }
                    else if (line.StartsWith("END_VAR", StringComparison.OrdinalIgnoreCase))
                    {
                        stage = 0x01;
                    }
                    else if (line.StartsWith("LD ", StringComparison.OrdinalIgnoreCase))
                    {
                        break;
                    }
                    else if (line.StartsWith("END_FUNCTION", StringComparison.OrdinalIgnoreCase))
                    {
                        if (blockType != null)
                        {
                            // 功能块后缀描述字符串
                            blockType.SetSuffixDecl(line);
                        }
                        break;
                    }
                    else if (stage >= 0x21)
                    {
                        connType = ViConnType.Parse(line, ViTypeCreation.Create);
                        if (connType != null && connType.Type != null)
                        {
                            switch ((stage & 0x0F))
                            {
                            case 0x01:      // INPUT
                                connType.SetParent(blockType);
                                blockType.InputConnectors.Add(connType);
                                break;

                            case 0x02:      // OUTPUT
                                connType.SetParent(blockType);
                                blockType.OutputConnectors.Add(connType);
                                break;

                            case 0x03:      // IN_OUT
                                connType.SetParent(blockType);
                                blockType.InputConnectors.Insert(blockType.InOutConnectorCount, connType);
                                blockType.OutputConnectors.Insert(blockType.InOutConnectorCount, connType);
                                blockType.InOutConnectorCount = blockType.InOutConnectorCount + 1;
                                break;
                            }
                        }
                        else
                        {
                            Trace.WriteLine(string.Format("{0}({1}): Invalid connection declaration!", fileName, lineIndex));
                        }
                    }
                }
            }

            return(blockType);
        }
예제 #2
0
        /// <summary>
        /// 更新功能块数组列表。
        /// </summary>
        public override void UpdatePOUs()
        {
            // 当CPU为null的时候,有可能当前类还未初始化完毕;
            if (this.CPU == null)
            {
                return;
            }

            this.DeleteAll();

            IniFile iniFile     = new IniFile(this.SourceFile);
            string  projectPath = FileName.GetFilePath(this.SourceFile);

            int sectionType = 0;    // 0 不关心;2 POE;9 LIBRARY

            iniFile.LoopSections((section) =>
            {
                if (section.EndsWith("_FUNCTIONBLOCK", StringComparison.OrdinalIgnoreCase) ||
                    section.EndsWith("_FUNCTION", StringComparison.OrdinalIgnoreCase))
                {
                    sectionType = 2;
                    return(true);
                }
                if (string.Equals(section, "LIBRARY", StringComparison.OrdinalIgnoreCase))
                {
                    sectionType = 9;
                    return(true);
                }

                sectionType = 0;
                return(false);
            }, (key, value) =>
            {
                if (!string.IsNullOrEmpty(value) && key.IsPrefixIndex("FILE"))
                {
                    string file, hardwareType;
                    switch (sectionType)
                    {
                    case 2:
                        // 工程本身的功能块
                        {
                            file         = FileName.GetAbsoluteFileName(projectPath, value);
                            file         = FileName.GetNewExtFileName(file, ".POE");
                            hardwareType = ViGlobal.GetPathHardwareName(projectPath, file);
                            // 没有硬件类型名称,或者硬件类型名称匹配的情况下,才将功能块加入
                            if (string.IsNullOrEmpty(hardwareType) ||
                                string.Equals(hardwareType, this.CPU.HardwareType, StringComparison.OrdinalIgnoreCase))
                            {
                                ViPOEBlockType blockType = ViIECPOEFile.GetBlockType(file);
                                if (blockType != null)
                                {
                                    blockType.PouSource = this;
                                    this.AddChild(blockType);
                                }
                            }
                        }
                        break;

                    case 9:
                        // 工程使用的 ViGET 库工程的功能块
                        {
                            file = FileName.GetAbsoluteFileName(ViGlobal.ProjODKPath, value);
                            file = FileName.GetNewExtFileName(file, ".VAR");

                            // 不能讲把自身作为一个库文件来使用,否则会造成死循环;
                            if (this.CPU.ProjectFile != null && !this.CPU.ProjectFile.Equals(file, StringComparison.OrdinalIgnoreCase))
                            {
                                ViPouSourceCPU cpu = new ViPouSourceCPU()
                                {
                                    ProjectFile  = file,
                                    HardwareType = this.CPU.HardwareType,
                                };

                                ViCPUPouSource cpuSource = new ViCPUPouSource(cpu, ViPouAttributes.ProjectLibrary | (this.PouAttributes & ViPouAttributes.Public));
                                if (cpuSource != null)
                                {
                                    this.AddChild(cpuSource);
                                }
                            }
                        }
                        break;
                    }
                }
                return(true);
            });

            // CPU 安装的硬件库的功能块
            if (!string.IsNullOrEmpty(this.CPU.CPUName))
            {
                string globProt = ViGlobal.GetCPUENVPath(projectPath, this.CPU.CPUName) + "GLOBPROT.INC";
                string infoFile = ViGlobal.GetCPUENVPath(projectPath, this.CPU.CPUName) + this.CPU.HardwareType + ".ini";
                this.AddChild(new ViIncPouSource(globProt, infoFile, ViPouAttributes.CPULibrary | (this.PouAttributes & ViPouAttributes.Public)));
            }

            // ViGET 全局的功能块。对于安装的库工程,就不要这些信息了,否则就重复了
            if (!string.IsNullOrEmpty(this.CPU.CPUName))
            {
                ArrayList alPouSources = ViGlobal.GetPouSources(this.CPU.HardwareType);
                if (alPouSources != null)
                {
                    foreach (ViPouSource source in alPouSources)
                    {
                        this.AddChild(source);
                    }
                }
            }
        }