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.RT.Log;
namespace Aitex.Core.RT.DataCenter
{
///
///
/// 数据项命名规则:
///
/// 一般数据项: 模块名.数据项名
///
/// 设备类型数据项:模块名.设备类型.数据项名
///
/// 界面显示设备数据项:模块名.数据项名
///
///
public class DataManager : ICommonData
{
ConcurrentDictionary> _keyValueMap;
SortedDictionary> _dbRecorderList;
Func _isSubscriptionAttribute;
Func _hasSubscriptionAttribute;
object _locker = new object();
public DataManager()
{
}
public void Initialize()
{
_dbRecorderList = new SortedDictionary>();
_keyValueMap = new ConcurrentDictionary>();
_isSubscriptionAttribute = attribute => attribute is SubscriptionAttribute;
_hasSubscriptionAttribute = mi => mi.GetCustomAttributes(false).Any(_isSubscriptionAttribute);
DATA.InnerDataManager = this;
}
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)
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentNullException("key");
if (_keyValueMap.ContainsKey(key))
throw new Exception(string.Format("Duplicated Key:{0}", key));
if (getter == null)
throw new ArgumentNullException("getter");
_keyValueMap.TryAdd(key, new DataItem(getter));
if (flag != SubscriptionAttribute.FLAG.IgnoreSaveDB)
{
lock (_locker)
{
_dbRecorderList[key] = getter;
}
}
}
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;
}
}
}