Sic.Framework/MECF.Framework.UI.Client/ClientBase/UIViewModelBase.cs

297 lines
9.1 KiB
C#
Raw Normal View History

2023-04-13 11:51:03 +08:00
using Aitex.Core.RT.Log;
using Aitex.Core.UI.MVVM;
using Aitex.Core.Util;
using Aitex.Core.Utilities;
using MECF.Framework.Common.DataCenter;
using OpenSEMI.Ctrlib.Controls;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace MECF.Framework.UI.Client.ClientBase
{
public class UIViewModelBase : BaseModel
{
public string SystemName { get; set; }
private PeriodicJob _timer;
public bool ActiveUpdateData;
protected Func<object, bool> _isSubscriptionAttribute;
protected Func<MemberInfo, bool> _hasSubscriptionAttribute;
protected ConcurrentBag<string> _subscribedKeys = new ConcurrentBag<string>();
public UIViewModelBase()
{
_timer = new PeriodicJob(1000, OnTimer, "UIUpdateThread-" + GetType().Name);
_isSubscriptionAttribute = attribute => attribute is SubscriptionAttribute;
_hasSubscriptionAttribute = mi => mi.GetCustomAttributes(false).Any(_isSubscriptionAttribute);
}
protected override void OnActivate()
{
base.OnActivate();
EnableTimer(true);
}
protected override void OnDeactivate(bool close)
{
base.OnDeactivate(close);
if(ActiveUpdateData)
{
EnableTimer(false);
}
}
public virtual void EnableTimer(bool enable)
{
if (enable)
{
_timer.Start();
}
else
{
_timer.Pause();
}
}
protected override void OnInitialize()
{
base.OnInitialize();
SubscribeKeys();
}
protected void Subscribe(string key)
{
if (!string.IsNullOrEmpty(key))
{
_subscribedKeys.Add(key);
}
}
public virtual void SubscribeKeys()
{
SubscribeKeys(this);
}
public void SubscribeKeys(UIViewModelBase vm)
{
Parallel.ForEach(vm.GetType().GetProperties().Where(_hasSubscriptionAttribute),
property =>
{
SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
string key = subscription.ModuleKey;
if (!string.IsNullOrEmpty(SystemName))
{
key = $"{SystemName}.{key}";
subscription.SetModule(SystemName);
}
if (!_subscribedKeys.Contains(key))
{
_subscribedKeys.Add(key);
}
});
Parallel.ForEach(vm.GetType().GetFields().Where(_hasSubscriptionAttribute),
field =>
{
SubscriptionAttribute subscription = field.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
string key = subscription.ModuleKey;
if (!string.IsNullOrEmpty(SystemName))
{
key = $"{SystemName}.{key}";
subscription.SetModule(SystemName);
}
if (!_subscribedKeys.Contains(key))
{
_subscribedKeys.Add(key);
}
});
}
protected virtual bool OnTimer()
{
try
{
Poll();
return true;
}
catch (Exception)
{
return false;
}
}
protected virtual void Poll()
{
if (_subscribedKeys.Count > 0)
{
Dictionary<string, object> data = QueryDataClient.Instance.Service.PollData(_subscribedKeys);
if (data == null)
{
LOG.Error("获取RT数据失败");
return;
}
if (data.Count != _subscribedKeys.Count)
{
string unknowKeys = string.Empty;
foreach (string key in _subscribedKeys)
{
if (!data.ContainsKey(key))
{
unknowKeys += key + "\r\n";
}
}
LOG.Error("获取如下SubscribeKey数据失败" + unknowKeys);
}
InvokeBeforeUpdateProperty(data);
UndateData(data);
Application.Current?.Dispatcher.Invoke(new Action(() =>
{
InvokePropertyChanged();
InvokeAfterUpdateProperty(data);
}));
}
}
protected virtual void InvokeBeforeUpdateProperty(Dictionary<string, object> data)
{
}
protected virtual void InvokeAfterUpdateProperty(Dictionary<string, object> data)
{
}
protected virtual void InvokePropertyChanged()
{
Refresh();
}
private void UndateData(Dictionary<string, object> data)
{
if (data != null)
{
UpdateSubscribe(data, this);
}
}
public void UpdateSubscribe(Dictionary<string, object> data, object vm)
{
Parallel.ForEach(vm.GetType().GetProperties().Where(_hasSubscriptionAttribute),
property =>
{
PropertyInfo pi = (PropertyInfo)property;
SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
string key = SystemName == null ? subscription.ModuleKey : $"{SystemName}.{subscription.ModuleKey}";
if (_subscribedKeys.Contains(key) && data.ContainsKey(key))
{
try
{
var convertedValue = Convert.ChangeType(data[key], pi.PropertyType);
var originValue = Convert.ChangeType(pi.GetValue(vm, null), pi.PropertyType);
if (originValue != convertedValue)
{
pi.SetValue(vm, convertedValue, null);
}
}
catch (Exception ex)
{
LOG.Error("由RT返回的数据更新失败" + key, ex);
}
}
});
Parallel.ForEach(vm.GetType().GetFields().Where(_hasSubscriptionAttribute),
field =>
{
FieldInfo fi = (FieldInfo)field;
SubscriptionAttribute subscription = field.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
string key = SystemName == null ? subscription.ModuleKey : $"{SystemName}.{subscription.ModuleKey}";
if (_subscribedKeys.Contains(key) && data.ContainsKey(key))
{
try
{
var convertedValue = Convert.ChangeType(data[key], fi.FieldType);
var originValue = Convert.ChangeType(fi.GetValue(vm), fi.FieldType);
if (originValue != convertedValue)
{
fi.SetValue(vm, convertedValue);
}
}
catch (Exception ex)
{
LOG.Error("由RT返回的数据更新失败" + key, ex);
}
}
});
}
public virtual void OnWaferTransfer(DragDropEventArgs args)
{
try
{
WaferMoveManager.Instance.TransferWafer(args.TranferFrom, args.TranferTo);
}
catch (Exception ex)
{
LOG.Write(ex);
}
}
public void OnMouseUp(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton != MouseButton.Right)
return;
if (sender is Slot slot)
{
ContextMenu cm = ContextMenuManager.Instance.GetSlotMenus(slot);
if (cm != null)
{
((FrameworkElement)e.Source).ContextMenu = cm;
}
return;
}
if (sender is CarrierContentControl carrier)
{
ContextMenu cm = ContextMenuManager.Instance.GetCarrierMenus(carrier);
if (cm != null)
{
((FrameworkElement)e.Source).ContextMenu = cm;
}
return;
}
}
}
}