mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-03-03 00:00:49 +08:00
优化了运行环境与启动器的运行逻辑,以及IOC容器的注册/绑定/获取对象的机制
This commit is contained in:
@@ -45,65 +45,45 @@ namespace Serein.WorkBench
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
/// <summary>
|
||||
/// 一种轻量的IOC容器
|
||||
/// </summary>
|
||||
private SereinIoc ServiceContainer { get; } = new SereinIoc();
|
||||
|
||||
/// <summary>
|
||||
/// 全局捕获Console输出事件,打印在这个窗体里面
|
||||
/// </summary>
|
||||
private readonly LogWindow logWindow;
|
||||
|
||||
/// <summary>
|
||||
/// 存储加载的程序集
|
||||
/// </summary>
|
||||
// private readonly List<Assembly> loadedAssemblies = [];
|
||||
/// <summary>
|
||||
/// 存储加载的程序集路径
|
||||
/// </summary>
|
||||
// private readonly List<string> loadedAssemblyPaths = [];
|
||||
|
||||
/// <summary>
|
||||
/// 存储所有方法信息
|
||||
/// </summary>
|
||||
// private static ConcurrentDictionary<string, MethodDetails> DllMethodDetails { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 存储所有与节点有关的控件
|
||||
/// </summary>
|
||||
private readonly Dictionary<string, NodeControlBase> NodeControls = [];
|
||||
/// <summary>
|
||||
/// 存储所有的连接
|
||||
/// </summary>
|
||||
private readonly List<Connection> Connections = [];
|
||||
|
||||
/// <summary>
|
||||
/// 存放触发器节点(运行时全部调用)
|
||||
/// </summary>
|
||||
// private readonly List<SingleFlipflopNode> flipflopNodes = [];
|
||||
|
||||
/// <summary>
|
||||
/// 节点的命名空间
|
||||
/// </summary>
|
||||
public const string NodeSpaceName = $"{nameof(Serein)}.{nameof(Serein.NodeFlow)}.{nameof(Serein.NodeFlow.Model)}";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 流程运行环境
|
||||
/// </summary>
|
||||
private IFlowEnvironment FlowEnvironment;
|
||||
private IFlowEnvironment FlowEnvironment { get; }
|
||||
private MainWindowViewModel ViewModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 流程启动器
|
||||
/// 存储所有与节点有关的控件
|
||||
/// </summary>
|
||||
// private FlowStarter nodeFlowStarter;
|
||||
private Dictionary<string, NodeControlBase> NodeControls { get; } = [];
|
||||
/// <summary>
|
||||
/// 存储所有的连接
|
||||
/// </summary>
|
||||
private List<Connection> Connections { get; } = [];
|
||||
|
||||
|
||||
|
||||
#region 与画布相关的字段
|
||||
|
||||
/// <summary>
|
||||
/// 当前选取的控件
|
||||
/// </summary>
|
||||
private readonly List<NodeControlBase> selectControls = [];
|
||||
|
||||
/// <summary>
|
||||
/// 拖动创建节点控件时的鼠标位置
|
||||
/// </summary>
|
||||
private Point canvasDropPosition;
|
||||
|
||||
/// <summary>
|
||||
/// 记录拖动开始时的鼠标位置
|
||||
/// </summary>
|
||||
@@ -154,20 +134,14 @@ namespace Serein.WorkBench
|
||||
private TranslateTransform translateTransform;
|
||||
#endregion
|
||||
|
||||
private Point canvasDropPosition;
|
||||
|
||||
|
||||
// private MainWindowViewModel mainWindowViewModel { get; }
|
||||
public MainWindow()
|
||||
{
|
||||
// mainWindowViewModel = new MainWindowViewModel(this);
|
||||
InitializeComponent();
|
||||
ViewModel = new MainWindowViewModel(this);
|
||||
FlowEnvironment = ViewModel.FlowEnvironment;
|
||||
|
||||
|
||||
|
||||
InitializeComponent();
|
||||
logWindow = new LogWindow();
|
||||
logWindow.Show();
|
||||
|
||||
// 重定向 Console 输出
|
||||
var logTextWriter = new LogTextWriter(WriteLog);
|
||||
Console.SetOut(logTextWriter);
|
||||
@@ -177,7 +151,6 @@ namespace Serein.WorkBench
|
||||
|
||||
private void InitFlowEvent()
|
||||
{
|
||||
FlowEnvironment = new FlowEnvironment();
|
||||
FlowEnvironment.OnDllLoad += FlowEnvironment_DllLoadEvent;
|
||||
FlowEnvironment.OnLoadNode += FlowEnvironment_NodeLoadEvent;
|
||||
FlowEnvironment.OnStartNodeChange += FlowEnvironment_StartNodeChangeEvent;
|
||||
@@ -188,8 +161,6 @@ namespace Serein.WorkBench
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void InitUI()
|
||||
{
|
||||
canvasTransformGroup = new TransformGroup();
|
||||
@@ -226,7 +197,6 @@ namespace Serein.WorkBench
|
||||
WriteLog("-------运行完成---------\r\n");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 加载了DLL文件,dll内容
|
||||
/// </summary>
|
||||
@@ -287,23 +257,8 @@ namespace Serein.WorkBench
|
||||
|
||||
NodeControls.TryAdd(nodeInfo.Guid, nodeControl); // 存放对应的控件
|
||||
PlaceNodeOnCanvas(nodeControl, nodeInfo.Position.X, nodeInfo.Position.Y); // 配置节点,并放置在画布上
|
||||
|
||||
|
||||
// 添加到画布
|
||||
//FlowChartCanvas.Dispatcher.Invoke(() =>
|
||||
//{
|
||||
// // 添加控件到画布
|
||||
// FlowChartCanvas.Children.Add(nodeControl);
|
||||
// Canvas.SetLeft(nodeControl, nodeInfo.Position.x);
|
||||
// Canvas.SetTop(nodeControl, nodeInfo.Position.y);
|
||||
// nodeControls.TryAdd(nodeInfo.Guid, nodeControl); // 存放对应的控件
|
||||
// ConfigureContextMenu(nodeControl); // 配置节点右键菜单
|
||||
// ConfigureNodeEvents(nodeControl); // 配置节点事件
|
||||
//});
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 节点连接关系变更
|
||||
/// </summary>
|
||||
@@ -319,7 +274,7 @@ namespace Serein.WorkBench
|
||||
return;
|
||||
}
|
||||
ConnectionType connectionType = eventArgs.ConnectionType;
|
||||
if(eventArgs.ChangeType == NodeConnectChangeEventArgs.ChangeTypeEnum.Create)
|
||||
if(eventArgs.ChangeType == NodeConnectChangeEventArgs.ConnectChangeType.Create)
|
||||
{
|
||||
// 添加连接
|
||||
var connection = new Connection
|
||||
@@ -334,7 +289,7 @@ namespace Serein.WorkBench
|
||||
Connections.Add(connection);
|
||||
EndConnection();
|
||||
}
|
||||
else if (eventArgs.ChangeType == NodeConnectChangeEventArgs.ChangeTypeEnum.Remote)
|
||||
else if (eventArgs.ChangeType == NodeConnectChangeEventArgs.ConnectChangeType.Remote)
|
||||
{
|
||||
// 需要移除连接
|
||||
var removeConnections = Connections.Where(c => c.Start.ViewModel.Node.Guid.Equals(fromNodeGuid)
|
||||
@@ -1403,7 +1358,7 @@ namespace Serein.WorkBench
|
||||
/// <param name="e"></param>
|
||||
private void ButtonDebugFlipflopNode_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
FlowEnvironment.Exit();
|
||||
FlowEnvironment.Exit(); // 在运行平台上点击了退出
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Serein.Library.Attributes;
|
||||
using Serein.Library.Api;
|
||||
using Serein.Library.Attributes;
|
||||
using Serein.Library.Entity;
|
||||
using Serein.Library.Utils;
|
||||
using Serein.NodeFlow;
|
||||
@@ -18,64 +19,13 @@ namespace Serein.WorkBench
|
||||
public class MainWindowViewModel
|
||||
{
|
||||
private readonly MainWindow window ;
|
||||
public IFlowEnvironment FlowEnvironment { get; set; }
|
||||
public MainWindowViewModel(MainWindow window)
|
||||
{
|
||||
FlowEnvironment = new FlowEnvironment();
|
||||
this.window = window;
|
||||
}
|
||||
|
||||
public FlowEnvironment FlowEnvironment { get; set; }
|
||||
|
||||
|
||||
#region 加载项目文件
|
||||
public void LoadProjectFile(SereinOutputFileData projectFile)
|
||||
{
|
||||
var dllPaths = projectFile.Librarys.Select(it => it.Path).ToList();
|
||||
foreach (var dll in dllPaths)
|
||||
{
|
||||
var filePath = System.IO.Path.GetFullPath(System.IO.Path.Combine(App.FileDataPath, dll));
|
||||
//LoadAssembly(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private void DisplayControlDll(Assembly assembly,
|
||||
List<MethodDetails> conditionTypes,
|
||||
List<MethodDetails> actionTypes,
|
||||
List<MethodDetails> flipflopMethods)
|
||||
{
|
||||
|
||||
var dllControl = new DllControl
|
||||
{
|
||||
Header = "DLL name : " + assembly.GetName().Name // 设置控件标题为程序集名称
|
||||
};
|
||||
|
||||
|
||||
foreach (var item in actionTypes)
|
||||
{
|
||||
dllControl.AddAction(item.Clone()); // 添加动作类型到控件
|
||||
}
|
||||
foreach (var item in flipflopMethods)
|
||||
{
|
||||
dllControl.AddFlipflop(item.Clone()); // 添加触发器方法到控件
|
||||
}
|
||||
|
||||
/*foreach (var item in stateTypes)
|
||||
{
|
||||
dllControl.AddState(item);
|
||||
}*/
|
||||
|
||||
window.DllStackPanel.Children.Add(dllControl); // 将控件添加到界面上显示
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,270 +0,0 @@
|
||||
namespace DySerin;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*public class ConditionNode : NodeBase, ICondition
|
||||
{
|
||||
private Func<bool> ConditionFunc { get; set; }
|
||||
|
||||
public ConditionNode(Func<bool> conditionFunc)
|
||||
{
|
||||
ConditionFunc = conditionFunc;
|
||||
}
|
||||
|
||||
public override void Execute()
|
||||
{
|
||||
if (ConditionFunc())
|
||||
{
|
||||
EnterTrueBranch();
|
||||
}
|
||||
else
|
||||
{
|
||||
EnterFalseBranch();
|
||||
}
|
||||
}
|
||||
|
||||
// 实现条件接口的方法
|
||||
public bool Evaluate(DynamicContext context)
|
||||
{
|
||||
Context = context; // 更新节点的上下文
|
||||
return ConditionFunc();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class ActionNode : NodeBase, IAction
|
||||
{
|
||||
private Action ActionMethod { get; set; }
|
||||
|
||||
public ActionNode(Action actionMethod)
|
||||
{
|
||||
ActionMethod = actionMethod;
|
||||
}
|
||||
|
||||
public override void Execute()
|
||||
{
|
||||
try
|
||||
{
|
||||
ActionMethod();
|
||||
EnterTrueBranch(); // 动作成功,进入真分支
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 可添加异常处理逻辑
|
||||
Return(); // 动作失败,终止节点
|
||||
}
|
||||
}
|
||||
|
||||
// 实现动作接口的方法
|
||||
public void Execute(DynamicContext context)
|
||||
{
|
||||
Context = context; // 更新节点的上下文
|
||||
Execute();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/// <summary>
|
||||
/// 根节点
|
||||
/// </summary>
|
||||
public abstract class NodeControl : UserControl
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
public abstract void Execute(NodeContext context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 条件节点
|
||||
/// </summary>
|
||||
public class ConditionNodeControl : NodeControl
|
||||
{
|
||||
public Func<NodeContext, bool> Condition { get; set; }
|
||||
public NodeControl TrueNode { get; set; }
|
||||
public NodeControl FalseNode { get; set; }
|
||||
|
||||
public ConditionNodeControl()
|
||||
{
|
||||
this.Content = new TextBlock { Text = "条件节点" };
|
||||
this.Background = Brushes.LightBlue;
|
||||
}
|
||||
|
||||
public override void Execute(NodeContext context)
|
||||
{
|
||||
if (Condition(context))
|
||||
{
|
||||
TrueNode?.Execute(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
FalseNode?.Execute(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动作节点
|
||||
/// </summary>
|
||||
public class ActionNodeControl : NodeControl
|
||||
{
|
||||
public Action<NodeContext> Action { get; set; }
|
||||
|
||||
public ActionNodeControl()
|
||||
{
|
||||
this.Content = new TextBlock { Text = "动作节点" };
|
||||
this.Background = Brushes.LightGreen;
|
||||
}
|
||||
|
||||
public override void Execute(NodeContext context)
|
||||
{
|
||||
Action?.Invoke(context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 状态节点
|
||||
/// </summary>
|
||||
public class StateNodeControl : NodeControl
|
||||
{
|
||||
public Func<NodeContext, object> StateFunction { get; set; }
|
||||
|
||||
public StateNodeControl()
|
||||
{
|
||||
this.Content = new TextBlock { Text = "状态节点" };
|
||||
this.Background = Brushes.LightYellow;
|
||||
}
|
||||
|
||||
public override void Execute(NodeContext context)
|
||||
{
|
||||
var result = StateFunction(context);
|
||||
context.Set("StateResult", result);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 节点上下文
|
||||
/// </summary>
|
||||
public class NodeContext
|
||||
{
|
||||
private readonly Dictionary<string, object> _data = new Dictionary<string, object>();
|
||||
|
||||
public void Set<T>(string key, T value)
|
||||
{
|
||||
_data[key] = value;
|
||||
}
|
||||
|
||||
public T Get<T>(string key)
|
||||
{
|
||||
return _data.ContainsKey(key) ? (T)_data[key] : default;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
public class Context
|
||||
{
|
||||
public Dictionary<string, object> Data { get; set; } = new Dictionary<string, object>();
|
||||
public void Set<T>(string key, T value)
|
||||
{
|
||||
Data[key] = value;
|
||||
}
|
||||
|
||||
public T Get<T>(string key)
|
||||
{
|
||||
return Data.ContainsKey(key) ? (T)Data[key] : default;
|
||||
}
|
||||
}
|
||||
|
||||
public interface INode
|
||||
{
|
||||
Context Enter(Context context);
|
||||
Context Exit(Context context);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public partial class ConditionNode : INode
|
||||
{
|
||||
public Func<Context, bool> Condition { get; set; }
|
||||
public INode TrueBranch { get; set; }
|
||||
public INode FalseBranch { get; set; }
|
||||
|
||||
public Context Enter(Context context)
|
||||
{
|
||||
if (Condition(context))
|
||||
{
|
||||
return TrueBranch?.Enter(context) ?? context;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FalseBranch?.Enter(context) ?? context;
|
||||
}
|
||||
}
|
||||
|
||||
public Context Exit(Context context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public partial class ActionNode : INode
|
||||
{
|
||||
public Action<Context> Action { get; set; }
|
||||
public bool IsTask { get; set; }
|
||||
|
||||
public Context Enter(Context context)
|
||||
{
|
||||
if (IsTask)
|
||||
{
|
||||
Task.Run(() => Action(context));
|
||||
}
|
||||
else
|
||||
{
|
||||
Action(context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
public Context Exit(Context context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
||||
public partial class StateNode : INode
|
||||
{
|
||||
public Context Enter(Context context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
|
||||
public Context Exit(Context context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
*/
|
||||
@@ -40,6 +40,11 @@ namespace Serein.WorkBench.Themes
|
||||
TypeTreeView.Items.Add(rootNode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加属性节点
|
||||
/// </summary>
|
||||
/// <param name="node"></param>
|
||||
/// <param name="type"></param>
|
||||
private void AddMembersToTreeNode(TreeViewItem node, Type type)
|
||||
{
|
||||
var members = type.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly);
|
||||
@@ -61,6 +66,7 @@ namespace Serein.WorkBench.Themes
|
||||
memberNode.Header = $"{member.Name} : {propertyType.Name}";
|
||||
if (!propertyType.IsPrimitive && propertyType != typeof(string))
|
||||
{
|
||||
// 递归显示类型属性的节点
|
||||
AddMembersToTreeNode(memberNode, propertyType);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user