using System; using System.IO; using System.Collections.Generic; using System.Xml; using System.Linq; using Aitex.Core.Util; using Aitex.Core.RT.SCCore; using Aitex.Core.RT.Log; namespace CyberX8_Simulator.Instances { public class SystemConfig : Singleton { private Dictionary _items = new Dictionary(); List paths = new List(); public void Initialize() { var current_path = Environment.CurrentDirectory; int nIndesx = current_path.LastIndexOf("CyberX8\\"); current_path = current_path.Substring(0, nIndesx + 8); GetConfigFilePath(current_path); string cfgPath = paths.Find(item => item.Contains("CyberX8_RT")); if (cfgPath != null) { string config_path = cfgPath; string system_cfg = config_path.Replace("_sc.data", "System.sccfg"); if(File.Exists(system_cfg)) { BuildItems(system_cfg); if (File.Exists(config_path)) { var cfg_stream = File.Open(config_path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); XmlDocument xmlData = new XmlDocument(); xmlData.Load(config_path); XmlNodeList scdatas = xmlData.SelectNodes("root/scdata"); foreach (XmlElement nodedata in scdatas) { string name = nodedata.GetAttribute("name"); if (_items.ContainsKey(name)) { InitializeItemValue(_items[name], nodedata.GetAttribute("value")); } } } } } } private bool InitializeItemValue(SCConfigItem item, string value) { bool changed = false; switch (item.Type) { case "Bool": bool boolValue; if (bool.TryParse(value, out boolValue) && boolValue != item.BoolValue) { item.BoolValue = boolValue; changed = true; } break; case "Integer": int intValue; if (int.TryParse(value, out intValue) && intValue != item.IntValue) { int.TryParse(item.Min, out int min); int.TryParse(item.Max, out int max); if (intValue < min || intValue > max) { //EV.PostWarningLog(ModuleNameString.System, $"SC {item.PathName} value {intValue} out of setting range ({item.Min}, {item.Max})"); break; } item.IntValue = intValue; changed = true; } break; case "Double": double doubleValue; if (double.TryParse(value, out doubleValue) && Math.Abs(doubleValue - item.DoubleValue) > 0.0001) { double.TryParse(item.Min, out double min); double.TryParse(item.Max, out double max); if (doubleValue < min || doubleValue > max) { //EV.PostWarningLog(ModuleNameString.System, $"SC {item.PathName} value {doubleValue} out of setting range ({item.Min}, {item.Max})"); break; } item.DoubleValue = doubleValue; changed = true; } break; case "String": if (value != item.StringValue) { item.StringValue = value; changed = true; } break; } return changed; } public T GetValue(string name) where T : struct { try { if (typeof(T) == typeof(bool)) return (T)(object)_items[name].BoolValue; if (typeof(T) == typeof(int)) return (T)(object)_items[name].IntValue; if (typeof(T) == typeof(double)) return (T)(object)_items[name].DoubleValue; } catch (KeyNotFoundException) { return default(T); } catch (Exception) { return default(T); } return default(T); } private void BuildItems(string xmlFile) { XmlDocument xml = new XmlDocument(); try { var stream = File.Open(xmlFile, FileMode.Open, FileAccess.ReadWrite); xml.Load(stream); XmlNodeList nodeConfigs = xml.SelectNodes("root/configs"); foreach (XmlElement nodeConfig in nodeConfigs) { BuildPathConfigs(nodeConfig.GetAttribute("name"), nodeConfig as XmlElement); } } catch (Exception ex) { LOG.WriteExeption(ex); } } private void BuildPathConfigs(string parentPath, XmlElement configElement) { XmlNodeList nodeConfigsList = configElement.SelectNodes("configs"); foreach (XmlElement nodeConfig in nodeConfigsList) { if (string.IsNullOrEmpty(parentPath)) { BuildPathConfigs(nodeConfig.GetAttribute("name"), nodeConfig as XmlElement); } else { BuildPathConfigs(parentPath + "." + nodeConfig.GetAttribute("name"), nodeConfig as XmlElement); } } XmlNodeList nodeConfigs = configElement.SelectNodes("config"); foreach (XmlElement nodeConfig in nodeConfigs) { SCConfigItem item = new SCConfigItem() { Default = nodeConfig.GetAttribute("default"), Name = nodeConfig.GetAttribute("name"), Description = nodeConfig.GetAttribute("description"), Max = nodeConfig.GetAttribute("max"), Min = nodeConfig.GetAttribute("min"), Parameter = nodeConfig.GetAttribute("paramter"), Path = parentPath, Tag = nodeConfig.GetAttribute("tag"), Type = nodeConfig.GetAttribute("type"), Unit = nodeConfig.GetAttribute("unit"), }; InitializeItemValue(item, item.Default); if (_items.ContainsKey(item.PathName)) { //LOG.Error("Duplicated SC item, "+ item.PathName); } _items[item.PathName] = item; } } private void SearchFileInPath(string path, string folderName, string fileName, ref List projectPaths) { var dirs = Directory.GetDirectories(path, "*.*", SearchOption.TopDirectoryOnly).ToList(); //获取当前路径下所有文件与文件夹 var desFolders = dirs.FindAll(x => x.Contains(folderName)); //在当前目录中查找目标文件夹 if (desFolders == null || desFolders.Count <= 0) { //当前目录未找到目标则递归 foreach (var dir in dirs) { SearchFileInPath(dir, folderName, fileName, ref projectPaths); } } else { //找到则添加至结果集 projectPaths.Add(path + "\\" + folderName + "\\" + fileName); } } public void GetConfigFilePath(string path) { DirectoryInfo dir = new DirectoryInfo(path); //找到该目录下的文件 FileInfo[] fi = dir.GetFiles(); foreach (FileInfo f in fi) { if (f.FullName.Contains("\\CyberX8_RT\\") && f.FullName.Contains("\\Config\\") && f.Name == "_sc.data") { paths.Add(f.FullName); return; } } //找到该目录下的所有目录再递归 DirectoryInfo[] subDir = dir.GetDirectories(); foreach (DirectoryInfo d in subDir) { GetConfigFilePath(d.FullName); } } } }