| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 | 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 PunkHPX8_Simulator.Instances{        public class SystemConfig : Singleton<SystemConfig>    {        private Dictionary<string, SCConfigItem> _items = new Dictionary<string, SCConfigItem>();        List<string> paths = new List<string>();        public void Initialize()        {            var current_path = Environment.CurrentDirectory;            int nIndesx = current_path.LastIndexOf("PunkHPX8\\");            current_path = current_path.Substring(0, nIndesx + 8);                            GetConfigFilePath(current_path);            string cfgPath = paths.Find(item => item.Contains("PunkHPX8_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.Read);                        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<T>(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, FileShare.Read);                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<string> 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("\\PunkHPX8_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);            }        }    }}
 |