using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Concurrent;
using System.Reflection;
using Aitex.Core.Util;
using System.Threading.Tasks;
using Aitex.Core.Account;
using Aitex.Core.RT.ConfigCenter;
using Aitex.Core.RT.DBCore;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.OperationCenter;
using Aitex.Core.RT.SCCore;
using Aitex.Core.WCF;
using MECF.Framework.Common.DataCenter;
using MECF.Framework.Common.FAServices;
using MECF.Framework.Common.Log;
namespace Aitex.Core.RT.DataCenter
{
///
///
/// 数据项命名规则:
///
/// 一般数据项: 模块名.数据项名
///
/// 设备类型数据项:模块名.设备类型.数据项名
///
/// 界面显示设备数据项:模块名.数据项名
///
///
public class DataManager : ICommonData
{
ConcurrentDictionary> _keyValueMap;
SortedDictionary> _dbRecorderList;
Func _isSubscriptionAttribute;
Func _hasSubscriptionAttribute;
object _locker = new object();
private LogCleaner logCleaner=new LogCleaner();
private DiskManager diskManager = new DiskManager();
public DataManager()
{
}
public void Initialize()
{
Initialize(true, true);
}
public void Initialize(bool enableService, bool enableStats=true)
{
_dbRecorderList = new SortedDictionary>();
_keyValueMap = new ConcurrentDictionary>();
_isSubscriptionAttribute = attribute => attribute is SubscriptionAttribute;
_hasSubscriptionAttribute = mi => mi.GetCustomAttributes(false).Any(_isSubscriptionAttribute);
DATA.InnerDataManager = this;
if (enableService)
{
Singleton.Instance.Initialize(new Type[]
{
typeof(QueryDataService)
});
}
if (enableStats)
{
StatsDataManager.Instance.Initialize();
}
CONFIG.Subscribe("System", "NumericDataList", ()=>NumericDataList);
logCleaner.Run();
diskManager.Run();
OP.Subscribe("System.DBExecute", DatabaseExecute);
}
private bool DatabaseExecute(string arg1, object[] arg2)
{
try
{
string sql = (string)arg2[0];
DB.Insert(sql);
LOG.Write($"execute sql: {sql}");
}
catch (Exception ex)
{
LOG.Write(ex);
}
return true;
}
public void Terminate()
{
logCleaner.Stop();
diskManager.Stop();
}
public List NumericDataList
{
get
{
List result = new List();
foreach (var dataItem in _keyValueMap)
{
object o = dataItem.Value.Value;
if (o == null)
continue;
Type dataType = o.GetType();
if (dataType == typeof(Boolean) || dataType == typeof(double) || dataType == typeof(float) || dataType == typeof(bool) ||
dataType == typeof(int) || dataType == typeof(ushort) || dataType == typeof(short))
result.Add(dataItem.Key);
}
return result;
}
}
public List VidDataList
{
get
{
List result = new List();
foreach (var dataItem in _keyValueMap)
{
object o = dataItem.Value.Value;
if (o == null)
continue;
Type dataType = o.GetType();
if (dataType == typeof(Boolean) || dataType == typeof(double) || dataType == typeof(float) ||
dataType == typeof(bool) ||
dataType == typeof(int) || dataType == typeof(ushort) || dataType == typeof(short))
{
result.Add(new VIDItem()
{
DataType = dataType.ToString(),
Description = "",
Index = 0,
Name = dataItem.Key,
Unit = "",
});
}
}
return result;
}
}
public List BuiltInDataList
{
get
{
List result = new List();
foreach (var dataItem in _keyValueMap)
{
object o = dataItem.Value.Value;
if (o == null)
continue;
Type dataType = o.GetType();
if (dataType == typeof(Boolean) || dataType == typeof(double) || dataType == typeof(float) || dataType == typeof(bool) ||
dataType == typeof(int) || dataType == typeof(ushort) || dataType == typeof(short) || dataType == typeof(string))
result.Add(dataItem.Key);
}
return result;
}
}
public List FullDataList
{
get
{
return _keyValueMap.Keys.ToList();
}
}
public Type GetDataType(string name)
{
if (_keyValueMap.ContainsKey(name))
{
object o = _keyValueMap[name].Value;
if (o != null)
return o.GetType();
}
return null;
}
public SortedDictionary> GetDBRecorderList()
{
SortedDictionary> result;
lock (_locker)
{
result = new SortedDictionary>(_dbRecorderList);
}
return result;
}
public void Subscribe(T instance, string keyPrefix = null) where T : class
{
if (instance == null)
throw new ArgumentNullException("instance");
Traverse(instance, keyPrefix);
}
public void Subscribe(string key, Func getter, SubscriptionAttribute.FLAG flag)
{
Subscribe(key, new DataItem(getter), flag);
if (flag != SubscriptionAttribute.FLAG.IgnoreSaveDB)
{
lock (_locker)
{
_dbRecorderList[key] = getter;
}
}
}
public void Subscribe(string key, DataItem dataItem, SubscriptionAttribute.FLAG flag)
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentNullException("key");
if (_keyValueMap.ContainsKey(key))
throw new Exception(string.Format("Duplicated Key:{0}", key));
if (dataItem == null)
throw new ArgumentNullException("dataItem");
_keyValueMap.TryAdd(key, dataItem);
}
public Dictionary Poll(IEnumerable keys)
{
Dictionary data = new Dictionary();
foreach (string name in keys)
{
if (_keyValueMap.ContainsKey(name))
data[name] =_keyValueMap[name].Value;
}
return data;
}
public object Poll(string key)
{
return _keyValueMap.ContainsKey(key) ? _keyValueMap[key].Value : null;
}
public void Traverse(object instance, string keyPrefix)
{
Parallel.ForEach(instance.GetType().GetFields().Where(_hasSubscriptionAttribute), fi =>
{
string key = Parse(fi);
key = string.IsNullOrWhiteSpace(keyPrefix) ? key : string.Format("{0}.{1}", keyPrefix, key);
Subscribe(key, () => fi.GetValue(instance), 0);
});
Parallel.ForEach(instance.GetType().GetProperties().Where(_hasSubscriptionAttribute), property =>
{
string key = Parse(property);
key = string.IsNullOrWhiteSpace(keyPrefix) ? key : string.Format("{0}.{1}", keyPrefix, key);
Subscribe(key, () => property.GetValue(instance, null), 0);
});
}
string Parse(MemberInfo member)
{
return _hasSubscriptionAttribute(member) ? (member.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute).Key : null;
}
public Dictionary PollData(IEnumerable keys)
{
Dictionary result = new Dictionary();
foreach (string key in keys)
{
if (_keyValueMap.ContainsKey(key))
result[key] = _keyValueMap[key].Value;
else
{
//LOG.Error("未定义的DataItem:" + key);
}
}
return result;
}
}
}