/// <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); }
/// <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); } }