mirror of
https://gitee.com/akwkevin/aistudio.-wpf.-diagram
synced 2026-04-11 03:36:38 +08:00
sfc逻辑基本完成
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
using AIStudio.Wpf.SFC.ViewModels;
|
||||
using org.mariuszgromada.math.mxparser;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Media;
|
||||
using Util.DiagramDesigner;
|
||||
|
||||
namespace AIStudio.Wpf.SFC
|
||||
@@ -27,15 +30,179 @@ namespace AIStudio.Wpf.SFC
|
||||
LinkPoint.Add(new LinkPoint { Id = Guid.NewGuid(), Name = "T3", Despcription = "容器3液位", Value = 20 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 流程数据
|
||||
/// </summary>
|
||||
public static Dictionary<IDiagramViewModel, List<SFCNode>> SFCNodes { get; set; } = new Dictionary<IDiagramViewModel, List<SFCNode>>();
|
||||
|
||||
/// <summary>
|
||||
/// 初始化数据
|
||||
/// </summary>
|
||||
/// <param name="json"></param>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public static void InitData(List<SFCNode> oASteps, List<ConnectorViewModel> connectors)
|
||||
public static void InitData(List<SFCNode> nodes, List<ConnectorViewModel> connectors, IDiagramViewModel viewModel)
|
||||
{
|
||||
|
||||
var start = nodes.FirstOrDefault(p => p.Kind == SFCNodeKinds.Start);
|
||||
if (start == null)
|
||||
throw new Exception("没有开始节点");
|
||||
|
||||
foreach (var edge in connectors)
|
||||
{
|
||||
var source = nodes.FirstOrDefault(p => p.BottomConnector == edge.SourceConnectorInfo || p.LeftConnector == edge.SourceConnectorInfo || p.RightConnector == edge.SourceConnectorInfo || p.TopConnector == edge.SourceConnectorInfo);
|
||||
if (source != null)
|
||||
{
|
||||
source.NextNode.Add((edge.SinkConnectorInfo as FullyCreatedConnectorInfo).DataItem as SFCNode);
|
||||
((edge.SinkConnectorInfo as FullyCreatedConnectorInfo).DataItem as SFCNode).PreNode.Add(source);
|
||||
}
|
||||
}
|
||||
|
||||
SFCNodes.Add(viewModel, nodes);
|
||||
ResetStatus(viewModel);
|
||||
}
|
||||
|
||||
private static void ResetStatus(IDiagramViewModel viewModel)
|
||||
{
|
||||
var nodes = SFCNodes[viewModel];
|
||||
var start = nodes.FirstOrDefault(p => p.Kind == SFCNodeKinds.Start);
|
||||
|
||||
SetStatus(start, 1);
|
||||
nodes.ForEach(p =>
|
||||
{
|
||||
if (p != start)
|
||||
{
|
||||
SetStatus(p, 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void Execute(IDiagramViewModel viewModel)
|
||||
{
|
||||
//仅T2进行计算
|
||||
var tank = SFCNodes[viewModel].OfType<Simulate_TankViewModel>().FirstOrDefault(p => p.Text == "T2");
|
||||
tank.Execute();
|
||||
|
||||
var startbtn = SFCNodes[viewModel].OfType<Simulate_StartViewModel>().FirstOrDefault();
|
||||
if (startbtn != null && startbtn.LinkPoint.Value == 0)//停止
|
||||
{
|
||||
ResetStatus(viewModel);
|
||||
|
||||
//关闭所有阀门
|
||||
foreach (var node in SFCNodes[viewModel].OfType<Simulate_SolenoidViewModel>())
|
||||
{
|
||||
if (node.DILinkPoint != null)
|
||||
{
|
||||
node.DILinkPoint.Value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//真实情况不会改变容器液位,只是为了模拟重新启动时候为了低液位处理的
|
||||
//tank.LinkPoint.Value = 0;
|
||||
}
|
||||
else//启动
|
||||
{
|
||||
var currentNodes = SFCNodes[viewModel].Where(p => p.Status == 1);
|
||||
foreach (var node in currentNodes)
|
||||
{
|
||||
if (node.NextNode.OfType<SFCConditionNode>().Count() > 1)//选择分支
|
||||
{
|
||||
foreach (var next in node.NextNode)
|
||||
{
|
||||
if (next is SFCConditionNode nextconditionNode)
|
||||
{
|
||||
List<Argument> args = new List<Argument>();
|
||||
for (int i = 0; i < nextconditionNode.LinkPoint.Count; i++)
|
||||
{
|
||||
Argument x = new Argument($"p{i}", nextconditionNode.LinkPoint[i].Value);
|
||||
args.Add(x);
|
||||
}
|
||||
Expression e = new Expression(nextconditionNode.Expression, args.ToArray());
|
||||
var result = e.calculate();
|
||||
if (result == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
SetStatus(node, 100);
|
||||
SetStatus(next, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (node is SFCConditionNode conditionNode)
|
||||
{
|
||||
List<Argument> args = new List<Argument>();
|
||||
for (int i = 0; i < conditionNode.LinkPoint.Count; i++)
|
||||
{
|
||||
Argument x = new Argument($"p{i}", conditionNode.LinkPoint[i].Value);
|
||||
args.Add(x);
|
||||
}
|
||||
Expression e = new Expression(conditionNode.Expression, args.ToArray());
|
||||
var result = e.calculate();
|
||||
if (result == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (node is SFCActionNode actionNode)
|
||||
{
|
||||
if (actionNode.LinkPoint != null)
|
||||
{
|
||||
Expression e = new Expression(actionNode.Expression);
|
||||
actionNode.LinkPoint.Value = e.calculate();
|
||||
SetStatus(actionNode, 100);
|
||||
}
|
||||
}
|
||||
else if (node is SFCCOEndNode cOEndNode)
|
||||
{
|
||||
//并行结束节点需要前面节点都完成
|
||||
if (cOEndNode.PreNode.Any(p => p.Status != 100))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SetStatus(node, 100);
|
||||
foreach (var next in node.NextNode)
|
||||
{
|
||||
if (next is SFCStartNode startNode)
|
||||
{
|
||||
ResetStatus(viewModel);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetStatus(next, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置颜色
|
||||
/// </summary>
|
||||
/// <param name="flowNode"></param>
|
||||
/// <param name="status"></param>
|
||||
/// <param name="remark"></param>
|
||||
public static void SetStatus(SFCNode node, int status)
|
||||
{
|
||||
node.Status = status;
|
||||
switch (status)
|
||||
{
|
||||
case 100:
|
||||
node.ColorViewModel.FillColor.Color = Colors.Gray;
|
||||
break;
|
||||
case 0:
|
||||
node.ColorViewModel.FillColor.Color = Colors.Blue;
|
||||
break;
|
||||
case 1:
|
||||
node.ColorViewModel.FillColor.Color = Colors.Green;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,5 +135,19 @@ namespace AIStudio.Wpf.SFC.ViewModels
|
||||
SetProperty(ref _value, value);
|
||||
}
|
||||
}
|
||||
|
||||
private int _status;
|
||||
|
||||
public int Status
|
||||
{
|
||||
get { return _status; }
|
||||
set
|
||||
{
|
||||
SetProperty(ref _status, value);
|
||||
}
|
||||
}
|
||||
|
||||
public List<SFCNode> NextNode { get; set; } = new List<SFCNode>();
|
||||
public List<SFCNode> PreNode { get; set; } = new List<SFCNode>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,9 +33,9 @@
|
||||
|
||||
<ControlTemplate x:Key="ConditionStyle" TargetType="{x:Type ContentControl}">
|
||||
<Grid IsHitTestVisible="False">
|
||||
<Border BorderThickness="1" HorizontalAlignment="Center" BorderBrush="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}">
|
||||
<Border BorderThickness="3" HorizontalAlignment="Center" BorderBrush="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}">
|
||||
</Border>
|
||||
<Border BorderThickness="1" VerticalAlignment="Center" BorderBrush="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}">
|
||||
<Border BorderThickness="3" VerticalAlignment="Center" BorderBrush="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}">
|
||||
</Border>
|
||||
<TextBlock Text="{Binding Text}" RenderTransformOrigin="1,0.5" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="2">
|
||||
<TextBlock.RenderTransform>
|
||||
@@ -75,6 +75,7 @@
|
||||
<Grid IsHitTestVisible="False">
|
||||
<Rectangle RadiusX="5" RadiusY="5" StrokeThickness="1" Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}" Fill="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}" />
|
||||
<ProgressBar Orientation="Vertical" Foreground="Green" Background="Red" Value="{Binding LinkPoint.Value,FallbackValue=50}" Width="5" HorizontalAlignment="Right" Margin="5" Maximum="100" Minimum="0"/>
|
||||
<TextBlock Text="{Binding LinkPoint.Value,StringFormat={}{0}%}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,30,0,0"/>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
|
||||
@@ -242,11 +243,12 @@
|
||||
ItemsSource="{Binding LinkPoint}" AlternationCount="{Binding LinkPoint.Count}" Background="{DynamicResource Fluent.Ribbon.Brushes.AccentBaseColorBrush}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<DockPanel Margin="2">
|
||||
<DockPanel >
|
||||
<Button DockPanel.Dock="Right" Command="{Binding DataContext.DeleteCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}}" CommandParameter="{Binding .}" Width="16" Height="16">
|
||||
<Path Stretch="Fill" Fill="Black" Data="M512 620.544l253.3376 253.3376a76.6976 76.6976 0 1 0 108.544-108.544L620.6464 512l253.2352-253.3376a76.6976 76.6976 0 1 0-108.544-108.544L512 403.3536 258.6624 150.1184a76.6976 76.6976 0 1 0-108.544 108.544L403.3536 512 150.1184 765.3376a76.6976 76.6976 0 1 0 108.544 108.544L512 620.6464z"/>
|
||||
</Button>
|
||||
<ComboBox SelectedValue="{Binding Name}" ItemsSource="{x:Static local:SFCService.LinkPoint}" VerticalAlignment="Center" SelectedValuePath="Name" DisplayMemberPath="Name" FontSize="12"/>
|
||||
<TextBlock VerticalAlignment="Center" Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentPresenter}, AncestorLevel=1}, Path=(ItemsControl.AlternationIndex),StringFormat={}p{0}}"/>
|
||||
<ComboBox SelectedValue="{Binding Name}" ItemsSource="{x:Static local:SFCService.LinkPoint}" VerticalAlignment="Center" SelectedValuePath="Name" DisplayMemberPath="Name" FontSize="12" Margin="2"/>
|
||||
</DockPanel>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
|
||||
@@ -46,7 +46,26 @@ namespace AIStudio.Wpf.SFC.ViewModels
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_dILinkPoint != null)
|
||||
{
|
||||
_dILinkPoint.PropertyChanged -= _dILinkPoint_PropertyChanged;
|
||||
}
|
||||
SetProperty(ref _dILinkPoint, value);
|
||||
if (_dILinkPoint != null)
|
||||
{
|
||||
_dILinkPoint.PropertyChanged += _dILinkPoint_PropertyChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void _dILinkPoint_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == "Value")
|
||||
{
|
||||
if (DOLinkPoint != null)
|
||||
{
|
||||
DOLinkPoint.Value = DILinkPoint.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Util.DiagramDesigner;
|
||||
|
||||
@@ -68,5 +69,15 @@ namespace AIStudio.Wpf.SFC.ViewModels
|
||||
this.LinkPoint = data.LinkPoint;
|
||||
}
|
||||
}
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
double input = PreNode.OfType<Simulate_SolenoidViewModel>().Sum(p => p.DOLinkPoint?.Value ?? 0);
|
||||
double output = NextNode.OfType<Simulate_SolenoidViewModel>().Sum(p => p.DOLinkPoint?.Value ?? 0);
|
||||
if (LinkPoint != null)
|
||||
{
|
||||
LinkPoint.Value += input - output;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user