Example #1
0
        /// <summary>
        /// 遍历所有的功能块,如果 loopFunc 返回 false,则停止遍历。
        /// </summary>
        /// <param name="loopFunc">功能块处理函数,如果返回 false,则停止遍历</param>
        /// <param name="pouSourceFilter">对嵌套的 Pou Source 对象进行过滤,如果返回 false,则该 Pou Source 对象就不遍历了。</param>
        /// <param name="child">子对象</param>
        /// <param name="loopedTypes">用于记录已经被遍历过的功能块信息</param>
        /// <returns>遍历是否没有被 loopFunc 函数终止?</returns>
        protected virtual bool LoopPOUs(Func <ViFirmBlockType, bool> loopFunc, Func <ViPouSource, bool> pouSourceFilter, ViNamedObject child, Dictionary <string, ViFirmBlockType> loopedTypes)
        {
            if (child is ViFirmBlockType)
            {
                ViFirmBlockType blockType = child as ViFirmBlockType;

                // 记录遍历过的功能块信息
                string key = blockType.Name.ToUpper();
                if (loopedTypes.ContainsKey(key))
                {
                    return(true);
                }
                loopedTypes[key] = blockType;

                // 遍历功能块
                if (!loopFunc(blockType))
                {
                    return(false);
                }
            }
            else if (child is ViPouSource)
            {
                ViPouSource pouSource = child as ViPouSource;
                if (pouSourceFilter == null || pouSourceFilter(pouSource))
                {
                    if (!pouSource.LoopPOUs(loopFunc, pouSourceFilter, loopedTypes))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Example #2
0
        /// <summary>
        /// 更新功能块数组列表。
        /// </summary>
        public override void UpdatePOUs()
        {
            this.DeleteAll();

            try
            {
                ViFirmBlockType blockType = null;
                ViConnType      connType  = null;

                if (File.Exists(this.SourceFile))
                {
                    int stage = 0x00;   // 0x00: 未开始
                    // 0x10: 开始 Proto Type
                    // 0x20: 开始 Function Block
                    // 0x3x: 开始 Function
                    // 0x21: 开始 INPUT
                    // 0x22: 开始 OUTPUT
                    // 0x23: 开始 IN_OUT
                    using (StreamReader reader = new StreamReader(this.SourceFile, Encoding.Default))
                    {
                        int lineIndex = 0;
                        while (true)
                        {
                            string line = reader.ReadLine();
                            if (line == null)
                            {
                                break;
                            }
                            ++lineIndex;

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

                            // 注释?
                            if (line.StartsWith(ViTextFile.CommentBegin))
                            {
                                continue;
                            }

                            if (stage == 0x00)
                            {
                                if (line.StartsWith("GLOBAL_PROTOTYP_BEGIN", StringComparison.OrdinalIgnoreCase))
                                {
                                    stage = 0x10;
                                }
                            }
                            else if (line.StartsWith("GLOBAL_PROTOTYP_END", StringComparison.OrdinalIgnoreCase))
                            {
                                stage = 0x00;
                            }
                            else if (stage == 0x10)
                            {
                                if (line.StartsWith("FUNCTION_BLOCK ", StringComparison.OrdinalIgnoreCase))
                                {
                                    connType = ViConnType.Parse(line.Substring(15), ViTypeCreation.CreateGlobal);
                                    if (connType != null && connType.Type == null)
                                    {
                                        stage = 0x20;
                                        //
                                        blockType         = new ViFirmBlockType(connType.Name, null);
                                        blockType.Comment = connType.Comment;
                                    }
                                    else
                                    {
                                        Trace.WriteLine(string.Format("{0}({1}): Invalid FUNCTION_BLOCK declaration!", this.SourceFile, lineIndex));
                                    }
                                }
                                else if (line.StartsWith("FUNCTION ", StringComparison.OrdinalIgnoreCase))
                                {
                                    connType = ViConnType.Parse(line.Substring(9), ViTypeCreation.CreateGlobal);
                                    if (connType != null && connType.Type != null)
                                    {
                                        stage = 0x30;
                                        //
                                        blockType         = new ViFirmBlockType(connType.Name, connType.Type);
                                        blockType.Comment = connType.Comment;
                                    }
                                    else
                                    {
                                        Trace.WriteLine(string.Format("{0}({1}): Invalid FUNCTION declaration!", this.SourceFile, lineIndex));
                                    }
                                }
                            }
                            else if (stage >= 0x20)
                            {
                                if (line.StartsWith("VAR_INPUT", StringComparison.OrdinalIgnoreCase))
                                {
                                    stage = (stage & 0xF0) | 0x01;
                                }
                                else if (line.StartsWith("VAR_OUTPUT", StringComparison.OrdinalIgnoreCase))
                                {
                                    stage = (stage & 0xF0) | 0x02;
                                }
                                else if (line.StartsWith("VAR_IN_OUT", StringComparison.OrdinalIgnoreCase))
                                {
                                    stage = (stage & 0xF0) | 0x03;
                                }
                                else if (line.StartsWith("END_VAR", StringComparison.OrdinalIgnoreCase))
                                {
                                    stage = (stage & 0xF0) | 0x00;
                                }
                                else if (line.StartsWith("END_FUNCTION", StringComparison.OrdinalIgnoreCase))
                                {
                                    if (blockType != null)
                                    {
                                        // 功能块后缀描述字符串
                                        blockType.SetSuffixDecl(line);

                                        if (ChildByName(blockType.Name) == null)
                                        {
                                            this.AddChild(blockType);
                                            //Trace.WriteLine("Block Type: \n" + blockType.ToString());
                                        }
                                        else
                                        {
                                            Trace.WriteLine(string.Format("{0}({1}): Duplicate POU name [{2}]!", this.SourceFile, lineIndex, blockType.Name));
                                        }
                                    }
                                    stage = 0x10;
                                }
                                else if ((stage & 0x0F) != 0x00)
                                {
                                    connType = ViConnType.Parse(line, ViTypeCreation.CreateGlobal);
                                    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!", this.SourceFile, lineIndex));
                                    }
                                }
                            }
                        }
                    }
                }

                // 从对应配置文件中读取功能块参数/属性信息
                if (File.Exists(this.InfoFile))
                {
                    IniFile iniFile = new IniFile(this.InfoFile);
                    blockType = null;
                    iniFile.LoopSections(
                        (section) =>
                    {
                        blockType = GetPOU(section);
                        return(blockType != null);
                    },
                        (key, value) =>
                    {
                        if (key.Equals("InitMode", StringComparison.OrdinalIgnoreCase) && value.ToBool())
                        {
                            blockType.Modes |= ViFirmBlockMode.Init;
                        }
                        else if (key.Equals("SystemMode", StringComparison.OrdinalIgnoreCase) && value.ToBool())
                        {
                            blockType.Modes |= ViFirmBlockMode.System;
                        }
                        else if (key.Equals("NormalMode", StringComparison.OrdinalIgnoreCase) && value.ToBool())
                        {
                            blockType.Modes |= ViFirmBlockMode.Normal;
                        }
                        else if (key.Equals("LibraryType", StringComparison.OrdinalIgnoreCase) ||
                                 key.Equals("Category", StringComparison.OrdinalIgnoreCase))
                        {
                            blockType.Category = value;
                        }
                        else if (key.Equals("FWLibraryName", StringComparison.OrdinalIgnoreCase))
                        {
                            blockType.FWLibraryName = value;
                        }
                        else if (key.Equals("FWLibraryVersion", StringComparison.OrdinalIgnoreCase))
                        {
                            blockType.FWLibraryVersion = value;
                        }
                        else if (key.Equals("BlockComment", StringComparison.OrdinalIgnoreCase))
                        {
                            blockType.Comment = value;
                        }
                        return(true);
                    });
                }
            }
            catch (Exception ee)
            {
                Trace.WriteLine("### [" + ee.Source + "] Exception: " + ee.Message);
                Trace.WriteLine("### " + ee.StackTrace);
            }
        }