优化了中断功能。

This commit is contained in:
fengjiayi
2024-09-22 17:37:32 +08:00
parent c930c870a6
commit eff0de410b
51 changed files with 5258 additions and 396 deletions

View File

@@ -1,10 +1,12 @@
using Serein.NodeFlow.Base;
using Serein.Library.Api;
using Serein.NodeFlow.Base;
using Serein.NodeFlow.Tool.SereinExpression;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
@@ -18,7 +20,6 @@ using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml.Linq;
using static Serein.WorkBench.Themes.TypeViewerWindow;
using static System.Collections.Specialized.BitVector32;
namespace Serein.WorkBench.Themes
{
@@ -55,36 +56,89 @@ namespace Serein.WorkBench.Themes
{
private object _objectInstance;
public string NodeGuid { get;set; }
// private NodeModelBase _nodeFlowData;
public string MonitorExpression { get => ExpressionTextBox.Text.ToString(); }
public IFlowEnvironment FlowEnvironment { get;set; }
public NodeModelBase NodeModel { get;set; }
public ObjectViewerControl()
{
InitializeComponent();
}
private DateTime _lastRefreshTime = DateTime.MinValue; // 上次刷新时间
private TimeSpan _refreshInterval = TimeSpan.FromSeconds(0.1); // 刷新间隔2秒
/// <summary>
/// 加载对象信息,展示其成员
/// </summary>
/// <param name="obj">要展示的对象</param>
//public void LoadObjectInformation(NodeModelBase nodeModel)
public void LoadObjectInformation(object obj)
{
if (obj == null)
return;
//IsTimerRefres = false;
//TimerRefreshButton.Content = "定时刷新";
// 当前时间
var currentTime = DateTime.Now;
// 如果上次刷新时间和当前时间之间的差值小于设定的间隔,则跳过
if (currentTime - _lastRefreshTime < _refreshInterval)
{
// 跳过过于频繁的刷新调用
return;
}
// 记录这次的刷新时间
_lastRefreshTime = currentTime;
_objectInstance = obj;
RefreshObjectTree(obj);
}
private void AddMonitorExpressionButton_Click(object sender, RoutedEventArgs e)
///// <summary>
///// 添加表达式
///// </summary>
///// <param name="sender"></param>
///// <param name="e"></param>
//private void AddMonitorExpressionButton_Click(object sender, RoutedEventArgs e)
//{
// OpenInputDialog((exp) =>
// {
// FlowEnvironment.AddInterruptExpression(NodeGuid, exp);
// });
//}
private void RefreshButton_Click(object sender, RoutedEventArgs e)
{
//RefreshObjectTree(_objectInstance);
FlowEnvironment.SetNodeFLowDataMonitorState(NodeGuid, true);
}
private void UpMonitorExpressionButton_Click(object sender, RoutedEventArgs e)
{
//MonitorExpression = ExpressionTextBox.Text.ToString();
if(FlowEnvironment.AddInterruptExpression(NodeGuid, MonitorExpression))
{
if (string.IsNullOrEmpty(MonitorExpression))
{
ExpressionTextBox.Text = "表达式已清空";
}
else
{
UpMonitorExpressionButton.Content = "更新监视表达式";
}
}
}
// 用于存储当前展开的节点路径
private HashSet<string> _expandedNodePaths = new HashSet<string>();
/// <summary>
/// 刷新对象属性树
/// </summary>
@@ -92,7 +146,19 @@ namespace Serein.WorkBench.Themes
{
if (obj is null)
return;
// _objectInstance = obj;
// 当前时间
var currentTime = DateTime.Now;
// 如果上次刷新时间和当前时间之间的差值小于设定的间隔,则跳过
if (currentTime - _lastRefreshTime < _refreshInterval)
{
// 跳过过于频繁的刷新调用
return;
}
// 记录这次的刷新时间
_lastRefreshTime = currentTime;
var objectType = obj.GetType();
FlowDataDetails flowDataDetails = new FlowDataDetails
@@ -124,9 +190,23 @@ namespace Serein.WorkBench.Themes
rootNode.Items.Clear();
AddMembersToTreeNode(rootNode, obj, objectType);
}
// 遍历节点,展开之前记录的节点
ExpandPreviouslyExpandedNodes(rootNode);
}
// 遍历并展开之前记录的节点
private void ExpandPreviouslyExpandedNodes(TreeViewItem node)
{
if (_expandedNodePaths.Contains(GetNodeFullPath(node)))
{
node.IsExpanded = true;
}
foreach (TreeViewItem child in node.Items)
{
ExpandPreviouslyExpandedNodes(child);
}
}
@@ -138,7 +218,7 @@ namespace Serein.WorkBench.Themes
/// 添加父节点
/// </summary>
/// <param name="node"></param>
private static void AddPlaceholderNode(TreeViewItem node)
private void AddPlaceholderNode(TreeViewItem node)
{
node.Items.Add(new TreeViewItem { Header = "Loading..." });
}
@@ -148,7 +228,7 @@ namespace Serein.WorkBench.Themes
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void TreeViewItem_Expanded(object sender, RoutedEventArgs e)
private void TreeViewItem_Expanded(object sender, RoutedEventArgs e)
{
var item = (TreeViewItem)sender;
@@ -157,6 +237,8 @@ namespace Serein.WorkBench.Themes
item.Items.Clear();
if (item.Tag is FlowDataDetails flowDataDetails) // FlowDataDetails flowDataDetails object obj
{
// 记录当前节点的路径
_expandedNodePaths.Add(GetNodeFullPath(item));
AddMembersToTreeNode(item, flowDataDetails.DataValue, flowDataDetails.DataType);
}
}
@@ -168,7 +250,7 @@ namespace Serein.WorkBench.Themes
/// <param name="treeViewNode"></param>
/// <param name="obj"></param>
/// <param name="type"></param>
private static void AddMembersToTreeNode(TreeViewItem treeViewNode, object obj, Type type)
private void AddMembersToTreeNode(TreeViewItem treeViewNode, object obj, Type type)
{
// 获取属性和字段
var members = type.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
@@ -176,11 +258,13 @@ namespace Serein.WorkBench.Themes
{
TreeViewItem memberNode = ConfigureTreeViewItem(obj, member);
treeViewNode.Items.Add(memberNode);
if (ConfigureTreeItemMenu(memberNode, member, out ContextMenu? contextMenu))
{
memberNode.ContextMenu = contextMenu; // 设置子项节点的事件
}
//if (ConfigureTreeItemMenu(memberNode, member, out ContextMenu? contextMenu))
//{
// memberNode.ContextMenu = contextMenu; // 设置子项节点的事件
//}
}
}
@@ -191,23 +275,25 @@ namespace Serein.WorkBench.Themes
/// <param name="obj"></param>
/// <param name="member"></param>
/// <returns></returns>
private static TreeViewItem ConfigureTreeViewItem(object obj, MemberInfo member)
private TreeViewItem ConfigureTreeViewItem(object obj, MemberInfo member)
{
TreeViewItem memberNode = new TreeViewItem { Header = member.Name };
if (member is PropertyInfo property)
{
string propertyValue = GetPropertyValue(obj, property,out object value);
FlowDataDetails flowDataDetails = new FlowDataDetails
{
ItemType = TreeItemType.Property,
DataType = property.PropertyType,
Name = property.Name,
DataValue = property,
DataValue = value,
DataPath = GetNodeFullPath(memberNode),
};
memberNode.Tag = flowDataDetails;
string propertyValue = GetPropertyValue(obj, property);
memberNode.Header = $"{property.Name} : {property.PropertyType.Name} = {propertyValue}";
if (!property.PropertyType.IsPrimitive && property.PropertyType != typeof(string))
@@ -218,18 +304,19 @@ namespace Serein.WorkBench.Themes
}
else if (member is FieldInfo field)
{
string fieldValue = GetFieldValue(obj, field, out object value);
FlowDataDetails flowDataDetails = new FlowDataDetails
{
ItemType = TreeItemType.Field,
DataType = field.FieldType,
Name = field.Name,
DataValue = field,
DataValue = value,
DataPath = GetNodeFullPath(memberNode),
};
memberNode.Tag = flowDataDetails;
string fieldValue = GetFieldValue(obj, field);
memberNode.Header = $"{field.Name} : {field.FieldType.Name} = {fieldValue}";
if (!field.FieldType.IsPrimitive && field.FieldType != typeof(string))
@@ -248,15 +335,22 @@ namespace Serein.WorkBench.Themes
/// <param name="obj"></param>
/// <param name="property"></param>
/// <returns></returns>
private static string GetPropertyValue(object obj, PropertyInfo property)
{
private string GetPropertyValue(object obj, PropertyInfo property,out object value)
{
try
{
var value = property.GetValue(obj);
return value?.ToString() ?? "null";
var properties = obj.GetType().GetProperties();
// 获取实例属性值
value = property.GetValue(obj);
return value?.ToString() ?? "null"; // 返回值或“null”
}
catch
{
value = null;
return "Error";
}
}
@@ -268,15 +362,16 @@ namespace Serein.WorkBench.Themes
/// <param name="obj"></param>
/// <param name="field"></param>
/// <returns></returns>
private static string GetFieldValue(object obj, FieldInfo field)
private string GetFieldValue(object obj, FieldInfo field, out object value)
{
try
{
var value = field.GetValue(obj);
value = field.GetValue(obj);
return value?.ToString() ?? "null";
}
catch
{
value = null;
return "Error";
}
}
@@ -288,13 +383,21 @@ namespace Serein.WorkBench.Themes
/// <param name="member"></param>
/// <param name="contextMenu"></param>
/// <returns></returns>
private static bool ConfigureTreeItemMenu(TreeViewItem memberNode, MemberInfo member, out ContextMenu? contextMenu)
private bool ConfigureTreeItemMenu(TreeViewItem memberNode, MemberInfo member, out ContextMenu? contextMenu)
{
bool isChange = false;
if (member is PropertyInfo property)
{
//isChange = true;
isChange = true;
contextMenu = new ContextMenu();
contextMenu.Items.Add(MainWindow.CreateMenuItem($"表达式", (s, e) =>
{
string fullPath = GetNodeFullPath(memberNode);
string copyValue = /*"@Get " + */fullPath;
ExpressionTextBox.Text = copyValue;
// Clipboard.SetDataObject(copyValue);
}));
}
else if (member is MethodInfo method)
{
@@ -305,29 +408,13 @@ namespace Serein.WorkBench.Themes
{
isChange = true;
contextMenu = new ContextMenu();
contextMenu.Items.Add(MainWindow.CreateMenuItem($"取值表达式", (s, e) =>
contextMenu.Items.Add(MainWindow.CreateMenuItem($"表达式", (s, e) =>
{
string fullPath = ObjectViewerControl.GetNodeFullPath(memberNode);
string copyValue = "@Get " + fullPath;
Clipboard.SetDataObject(copyValue);
string fullPath = GetNodeFullPath(memberNode);
string copyValue = /*"@Get " +*/ fullPath;
ExpressionTextBox.Text = copyValue;
// Clipboard.SetDataObject(copyValue);
}));
//contextMenu.Items.Add(MainWindow.CreateMenuItem($"监视中断", (s, e) =>
//{
// string fullPath = GetNodeFullPath(memberNode);
// Clipboard.SetDataObject(fullPath);
// OpenInputDialog((exp) =>
// {
// if (node.DebugSetting.InterruptExpression.Contains(exp))
// {
// Console.WriteLine("表达式已存在");
// }
// else
// {
// node.DebugSetting.InterruptExpression.Add(exp);
// }
// });
//}));
}
else
{
@@ -336,12 +423,14 @@ namespace Serein.WorkBench.Themes
return isChange;
}
/// <summary>
/// 获取当前节点的完整路径,例如 "node1.node2.node3.node4"
/// </summary>
/// <param name="node">目标节点</param>
/// <returns>节点路径</returns>
private static string GetNodeFullPath(TreeViewItem node)
private string GetNodeFullPath(TreeViewItem node)
{
if (node == null)
return string.Empty;
@@ -366,7 +455,7 @@ namespace Serein.WorkBench.Themes
/// </summary>
/// <param name="node">目标节点</param>
/// <returns>父节点</returns>
private static TreeViewItem GetParentTreeViewItem(TreeViewItem node)
private TreeViewItem GetParentTreeViewItem(TreeViewItem node)
{
DependencyObject parent = VisualTreeHelper.GetParent(node);
while (parent != null && !(parent is TreeViewItem))
@@ -378,7 +467,7 @@ namespace Serein.WorkBench.Themes
private static InputDialog OpenInputDialog(Action<string> action)
private InputDialog OpenInputDialog(Action<string> action)
{
var inputDialog = new InputDialog();
inputDialog.Closed += (s, e) =>
@@ -398,7 +487,6 @@ namespace Serein.WorkBench.Themes
///// <summary>
///// 刷新按钮的点击事件
///// </summary>