mirror of
https://gitee.com/akwkevin/aistudio.-wpf.-diagram
synced 2026-03-02 15:50:51 +08:00
sfc逻辑基本完成
This commit is contained in:
@@ -1067,5 +1067,9 @@ namespace AIStudio.Wpf.ADiagram.ViewModels
|
||||
|
||||
return new Size(formattedText.Width, formattedText.Height);
|
||||
}
|
||||
|
||||
public virtual void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ namespace AIStudio.Wpf.Flowchart
|
||||
|
||||
DiagramViewModel.ClearSelectedItems();
|
||||
|
||||
FlowchartService.InitData(DiagramViewModel.Items.OfType<FlowNode>().ToList(), DiagramViewModel.Items.OfType<ConnectorViewModel>().ToList());
|
||||
FlowchartService.InitData(DiagramViewModel.Items.OfType<FlowNode>().ToList(), DiagramViewModel.Items.OfType<ConnectorViewModel>().ToList(), DiagramViewModel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -133,6 +133,14 @@ namespace AIStudio.Wpf.Logical
|
||||
}
|
||||
}
|
||||
|
||||
if (arg is TimerDesignerItemViewModel)
|
||||
{
|
||||
if (DiagramViewModel.Items.OfType<LogicalGateItemViewModelBase>().Any(p => p.LogicalType == LogicalType.Time))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -661,6 +661,11 @@ namespace AIStudio.Wpf.ADiagram.ViewModels
|
||||
{
|
||||
//here's how you can cancel stuff:
|
||||
//args.Cancel();
|
||||
|
||||
if (args.DragablzItem.DataContext is DiagramsViewModel viewModel)
|
||||
{
|
||||
viewModel.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void MainWindowViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
|
||||
@@ -8,6 +8,7 @@ using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Util.DiagramDesigner;
|
||||
@@ -35,6 +36,7 @@ namespace AIStudio.Wpf.Flowchart
|
||||
DiagramViewModel.CellVerticalAlignment = CellVerticalAlignment.Center;
|
||||
}
|
||||
|
||||
private System.Timers.Timer readDataTimer = new System.Timers.Timer();
|
||||
protected override void Init()
|
||||
{
|
||||
base.Init();
|
||||
@@ -42,43 +44,46 @@ namespace AIStudio.Wpf.Flowchart
|
||||
SFCStartNode start = new SFCStartNode() { Left = 0, Top = 60, Text = "S0" };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(start);
|
||||
|
||||
SFCConditionNode condition1 = new SFCConditionNode() { Left = 0, Top = 120, Text = "X0" };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(condition1);
|
||||
SFCConditionNode condition1_1 = new SFCConditionNode() { Left = 0, Top = 120, Text = "X01", Expression = "p0==1&p1<20", LinkPoint = new ObservableCollection<LinkPoint> { SFCService.LinkPoint.FirstOrDefault(p => p.Name == "S0"), SFCService.LinkPoint.FirstOrDefault(p => p.Name == "T2") } };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(condition1_1);
|
||||
|
||||
SFCConditionNode condition1_2 = new SFCConditionNode() { Left = 100, Top = 120, Text = "X02", Expression = "p0==1&p1<30", LinkPoint = new ObservableCollection<LinkPoint> { SFCService.LinkPoint.FirstOrDefault(p => p.Name == "S0"), SFCService.LinkPoint.FirstOrDefault(p => p.Name == "T2") } };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(condition1_2);
|
||||
|
||||
SFCNodeNode step1 = new SFCNodeNode() { Left = 0, Top = 180, Text = "S1" };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(step1);
|
||||
|
||||
SFCActionNode action11 = new SFCActionNode() { Left = 100, Top = 180, Text = "SET_V1" };
|
||||
SFCActionNode action11 = new SFCActionNode() { Left = 100, Top = 180, Text = "SET_V1", Expression = "1", LinkPoint = SFCService.LinkPoint.FirstOrDefault(p => p.Name == "K1_DI") };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(action11);
|
||||
|
||||
SFCActionNode action12 = new SFCActionNode() { Left = 200, Top = 180, Text = "SET_V2" };
|
||||
SFCActionNode action12 = new SFCActionNode() { Left = 200, Top = 180, Text = "SET_V2", Expression = "1", LinkPoint = SFCService.LinkPoint.FirstOrDefault(p => p.Name == "K2_DI") };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(action12);
|
||||
|
||||
SFCActionNode action13 = new SFCActionNode() { Left = 300, Top = 180, Text = "SET_V3" };
|
||||
SFCActionNode action13 = new SFCActionNode() { Left = 300, Top = 180, Text = "SET_V3", Expression = "1", LinkPoint = SFCService.LinkPoint.FirstOrDefault(p => p.Name == "K3_DI") };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(action13);
|
||||
|
||||
SFCActionNode action14 = new SFCActionNode() { Left = 400, Top = 180, Text = "RES_V4" };
|
||||
SFCActionNode action14 = new SFCActionNode() { Left = 400, Top = 180, Text = "RES_V4", Expression = "0", LinkPoint = SFCService.LinkPoint.FirstOrDefault(p => p.Name == "K4_DI") };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(action14);
|
||||
|
||||
SFCConditionNode condition2 = new SFCConditionNode() { Left = 0, Top = 240, Text = "X1" };
|
||||
SFCConditionNode condition2 = new SFCConditionNode() { Left = 0, Top = 240, Text = "X1", Expression = "p0>50", LinkPoint = new ObservableCollection<LinkPoint> { SFCService.LinkPoint.FirstOrDefault(p => p.Name == "T2") } };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(condition2);
|
||||
|
||||
SFCNodeNode step2 = new SFCNodeNode() { Left = 0, Top = 300, Text = "S2" };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(step2);
|
||||
|
||||
SFCActionNode action2 = new SFCActionNode() { Left = 100, Top = 300, Text = "SET_V4" };
|
||||
SFCActionNode action2 = new SFCActionNode() { Left = 100, Top = 300, Text = "SET_V4", Expression = "1", LinkPoint = SFCService.LinkPoint.FirstOrDefault(p => p.Name == "K4_DI") };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(action2);
|
||||
|
||||
SFCConditionNode condition3 = new SFCConditionNode() { Left = 0, Top = 360, Text = "X2" };
|
||||
SFCConditionNode condition3 = new SFCConditionNode() { Left = 0, Top = 360, Text = "X2", Expression = "p0>70", LinkPoint = new ObservableCollection<LinkPoint> { SFCService.LinkPoint.FirstOrDefault(p => p.Name == "T2") } };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(condition3);
|
||||
|
||||
SFCNodeNode step3 = new SFCNodeNode() { Left = 0, Top = 420, Text = "S3" };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(step3);
|
||||
|
||||
SFCActionNode action3 = new SFCActionNode() { Left = 100, Top = 420, Text = "RES_V1" };
|
||||
SFCActionNode action3 = new SFCActionNode() { Left = 100, Top = 420, Text = "RES_V1", Expression = "0", LinkPoint = SFCService.LinkPoint.FirstOrDefault(p => p.Name == "K1_DI") };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(action3);
|
||||
|
||||
SFCConditionNode condition4 = new SFCConditionNode() { Left = 0, Top = 480, Text = "X4" };
|
||||
SFCConditionNode condition4 = new SFCConditionNode() { Left = 0, Top = 480, Text = "X3", Expression = "p0>80", LinkPoint = new ObservableCollection<LinkPoint> { SFCService.LinkPoint.FirstOrDefault(p => p.Name == "T2") } };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(condition4);
|
||||
|
||||
SFCCOBeginNode cobegin = new SFCCOBeginNode() { Left = 38, Top = 540, Text = "" };
|
||||
@@ -87,23 +92,35 @@ namespace AIStudio.Wpf.Flowchart
|
||||
SFCNodeNode step4 = new SFCNodeNode() { Left = 0, Top = 600, Text = "S4" };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(step4);
|
||||
|
||||
SFCActionNode action4 = new SFCActionNode() { Left = 100, Top = 600, Text = "RES_V2" };
|
||||
SFCActionNode action4 = new SFCActionNode() { Left = 100, Top = 600, Text = "RES_V2", Expression = "0", LinkPoint = SFCService.LinkPoint.FirstOrDefault(p => p.Name == "K2_DI") };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(action4);
|
||||
|
||||
SFCConditionNode condition5 = new SFCConditionNode() { Left = 0, Top = 660, Text = "X4", Expression = "p0==0", LinkPoint = new ObservableCollection<LinkPoint> { SFCService.LinkPoint.FirstOrDefault(p => p.Name == "K2_DO") } };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(condition5);
|
||||
|
||||
SFCNodeNode step5 = new SFCNodeNode() { Left = 200, Top = 600, Text = "S5" };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(step5);
|
||||
|
||||
SFCActionNode action5 = new SFCActionNode() { Left = 300, Top = 600, Text = "RES_V3" };
|
||||
SFCActionNode action5 = new SFCActionNode() { Left = 300, Top = 600, Text = "RES_V3", Expression = "0", LinkPoint = SFCService.LinkPoint.FirstOrDefault(p => p.Name == "K3_DI") };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(action5);
|
||||
|
||||
SFCCOEndNode coend = new SFCCOEndNode() { Left = 38, Top = 660, Text = "" };
|
||||
SFCConditionNode condition6 = new SFCConditionNode() { Left = 200, Top = 660, Text = "X5", Expression = "p0==0", LinkPoint = new ObservableCollection<LinkPoint> { SFCService.LinkPoint.FirstOrDefault(p => p.Name == "K3_DO") } };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(condition6);
|
||||
|
||||
SFCCOEndNode coend = new SFCCOEndNode() { Left = 38, Top = 720, Text = "" };
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(coend);
|
||||
|
||||
ConnectorViewModel connector1 = new ConnectorViewModel(start.Output[0], condition1.Input[0]);
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(connector1);
|
||||
ConnectorViewModel connector1_1 = new ConnectorViewModel(start.Output[0], condition1_1.Input[0]);
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(connector1_1);
|
||||
|
||||
ConnectorViewModel connector2 = new ConnectorViewModel(condition1.Output[0], step1.Input[0]);
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(connector2);
|
||||
ConnectorViewModel connector2_1 = new ConnectorViewModel(condition1_1.Output[0], step1.Input[0]);
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(connector2_1);
|
||||
|
||||
ConnectorViewModel connector1_2 = new ConnectorViewModel(start.Output[0], condition1_2.Input[0]);
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(connector1_2);
|
||||
|
||||
ConnectorViewModel connector2_2 = new ConnectorViewModel(condition1_2.Output[0], step1.Input[0]);
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(connector2_2);
|
||||
|
||||
ConnectorViewModel connector31 = new ConnectorViewModel(step1.Action[0], action11.Input[0]);
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(connector31);
|
||||
@@ -147,21 +164,27 @@ namespace AIStudio.Wpf.Flowchart
|
||||
ConnectorViewModel connector13 = new ConnectorViewModel(step4.Action[0], action4.Input[0]);
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(connector13);
|
||||
|
||||
ConnectorViewModel connector14 = new ConnectorViewModel(cobegin.Output[1], step5.Input[0]);
|
||||
ConnectorViewModel connector14 = new ConnectorViewModel(step4.Output[0], condition5.Input[0]);
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(connector14);
|
||||
|
||||
ConnectorViewModel connector15 = new ConnectorViewModel(step5.Action[0], action5.Input[0]);
|
||||
ConnectorViewModel connector15 = new ConnectorViewModel(cobegin.Output[1], step5.Input[0]);
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(connector15);
|
||||
|
||||
ConnectorViewModel connector16 = new ConnectorViewModel(step4.Output[0], coend.Input[0]);
|
||||
ConnectorViewModel connector16 = new ConnectorViewModel(step5.Action[0], action5.Input[0]);
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(connector16);
|
||||
|
||||
ConnectorViewModel connector17 = new ConnectorViewModel(step5.Output[0], coend.Input[1]);
|
||||
ConnectorViewModel connector17 = new ConnectorViewModel(step5.Output[0], condition6.Input[0]);
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(connector17);
|
||||
|
||||
ConnectorViewModel connector18 = new ConnectorViewModel(coend.Output[0], start.Input[0]);
|
||||
ConnectorViewModel connector18 = new ConnectorViewModel(condition5.Output[0], coend.Input[0]);
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(connector18);
|
||||
|
||||
ConnectorViewModel connector19 = new ConnectorViewModel(condition6.Output[0], coend.Input[1]);
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(connector19);
|
||||
|
||||
ConnectorViewModel connector20 = new ConnectorViewModel(coend.Output[0], start.Input[0]);
|
||||
DiagramViewModel.DirectAddItemCommand.Execute(connector20);
|
||||
|
||||
#region 模拟部分
|
||||
TextDesignerItemViewModel despcription = new TextDesignerItemViewModel()
|
||||
{
|
||||
@@ -239,9 +262,29 @@ namespace AIStudio.Wpf.Flowchart
|
||||
|
||||
DiagramViewModel.ClearSelectedItems();
|
||||
|
||||
SFCService.InitData(DiagramViewModel.Items.OfType<SFCNode>().ToList(), DiagramViewModel.Items.OfType<ConnectorViewModel>().ToList(), DiagramViewModel);
|
||||
|
||||
readDataTimer.Elapsed += timeCycle;
|
||||
readDataTimer.Interval = 1000;
|
||||
readDataTimer.AutoReset = false;
|
||||
readDataTimer.Start();
|
||||
}
|
||||
|
||||
private void timeCycle(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
if (DiagramViewModel != null)
|
||||
{
|
||||
SFCService.Execute(DiagramViewModel);
|
||||
}
|
||||
readDataTimer.Start();
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
|
||||
readDataTimer.Stop();
|
||||
readDataTimer.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
<Fluent:Ribbon.Menu>
|
||||
<Grid>
|
||||
<!--Backstage items can be keytipped-->
|
||||
<Fluent:Backstage x:Name="Backstage" IsOpen="{Binding IsOpenBackstage,Mode=TwoWay}">
|
||||
<Fluent:Backstage x:Name="Backstage" IsOpen="{Binding IsOpenBackstage,Mode=TwoWay}">
|
||||
<Fluent:BackstageTabControl>
|
||||
<Fluent:Button Header="打开"
|
||||
Icon="{iconPacks:Material Kind=OpenInNew}"
|
||||
@@ -93,7 +93,7 @@
|
||||
</Button>
|
||||
<Button Margin="5" ToolTip="顺序控制图" Command="{Binding NewCommand}" CommandParameter="SFC" Width="80" Height="80" Foreground="{DynamicResource BlackBrush}" Background="{DynamicResource WhiteBrush}" BorderBrush="{DynamicResource BlackBrush}">
|
||||
<Path Stretch="Fill" Margin="20" Fill="{DynamicResource GrayBrush2}" Data="M10.984 13.836a.5.5 0 0 1-.353-.146l-.745-.743a.5.5 0 1 1 .706-.708l.392.391 1.181-1.18a.5.5 0 0 1 .708.707l-1.535 1.533a.504.504 0 0 1-.354.146zm9.353-.147l1.534-1.532a.5.5 0 0 0-.707-.707l-1.181 1.18-.392-.391a.5.5 0 1 0-.706.708l.746.743a.497.497 0 0 0 .706-.001zM4.527 7.452l2.557-1.585A1 1 0 0 0 7.09 4.17L4.533 2.56A1 1 0 0 0 3 3.406v3.196a1.001 1.001 0 0 0 1.527.85zm2.03-2.436L4 6.602V3.406l2.557 1.61zM24 12.5c0 1.93-1.57 3.5-3.5 3.5a3.503 3.503 0 0 1-3.46-3h-2.08a3.503 3.503 0 0 1-3.46 3 3.502 3.502 0 0 1-3.46-3h-.558c-.972 0-1.85-.399-2.482-1.042V17c0 1.654 1.346 3 3 3h.04c.244-1.693 1.7-3 3.46-3 1.93 0 3.5 1.57 3.5 3.5S13.43 24 11.5 24a3.502 3.502 0 0 1-3.46-3H8c-2.206 0-4-1.794-4-4V9.899A5.008 5.008 0 0 1 0 5c0-2.757 2.243-5 5-5s5 2.243 5 5a5.005 5.005 0 0 1-4.952 4.998A2.482 2.482 0 0 0 7.482 12h.558c.244-1.693 1.7-3 3.46-3a3.502 3.502 0 0 1 3.46 3h2.08a3.503 3.503 0 0 1 3.46-3c1.93 0 3.5 1.57 3.5 3.5zm-15 8c0 1.378 1.122 2.5 2.5 2.5s2.5-1.122 2.5-2.5-1.122-2.5-2.5-2.5S9 19.122 9 20.5zM5 9c2.206 0 4-1.794 4-4S7.206 1 5 1 1 2.794 1 5s1.794 4 4 4zm9 3.5c0-1.378-1.122-2.5-2.5-2.5S9 11.122 9 12.5s1.122 2.5 2.5 2.5 2.5-1.122 2.5-2.5zm9 0c0-1.378-1.122-2.5-2.5-2.5S18 11.122 18 12.5s1.122 2.5 2.5 2.5 2.5-1.122 2.5-2.5zm-13 8a.5.5 0 1 0 1 0 .5.5 0 0 0-1 0zm2 0a.5.5 0 1 0 1 0 .5.5 0 0 0-1 0zm12 0c0 1.93-1.57 3.5-3.5 3.5a3.503 3.503 0 0 1-3.46-3.002c-.007.001-.013.005-.021.005l-.506.017h-.017a.5.5 0 0 1-.016-.999l.506-.017c.018-.002.035.006.052.007A3.503 3.503 0 0 1 20.5 17c1.93 0 3.5 1.57 3.5 3.5zm-1 0c0-1.378-1.122-2.5-2.5-2.5S18 19.122 18 20.5s1.122 2.5 2.5 2.5 2.5-1.122 2.5-2.5z" ></Path>
|
||||
</Button>
|
||||
</Button>
|
||||
</WrapPanel>
|
||||
</TabItem>
|
||||
<TabItem Header="待续" />
|
||||
@@ -322,7 +322,7 @@
|
||||
SizeDefinition="Middle,Small"
|
||||
Command="{Binding DiagramsViewModel.DiagramViewModel.RedoCommand}">
|
||||
<Fluent:Button.ToolTip>
|
||||
<Fluent:ScreenTip Title="Redo"
|
||||
<Fluent:ScreenTip Title="Redo"
|
||||
Text="重做操作"
|
||||
Width="190" />
|
||||
</Fluent:Button.ToolTip>
|
||||
@@ -1620,7 +1620,7 @@
|
||||
<Binding Path="PageUnit"/>
|
||||
<Binding ElementName="designerScrollViewer" Path="ActualWidth"/>
|
||||
<Binding ElementName="panel" Path="ActualWidth"/>
|
||||
<Binding ElementName="diagram" Path="ActualWidth"/>
|
||||
<Binding ElementName="diagram" Path="ActualWidth"/>
|
||||
</MultiBinding>
|
||||
</controls:Ruler.CountShift>
|
||||
</controls:Ruler>
|
||||
@@ -1646,7 +1646,7 @@
|
||||
<Binding Path="PageUnit"/>
|
||||
<Binding ElementName="designerScrollViewer" Path="ActualHeight"/>
|
||||
<Binding ElementName="panel" Path="ActualHeight"/>
|
||||
<Binding ElementName="diagram" Path="ActualHeight"/>
|
||||
<Binding ElementName="diagram" Path="ActualHeight"/>
|
||||
</MultiBinding>
|
||||
</controls:Ruler.CountShift>
|
||||
</controls:Ruler>
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace AIStudio.Wpf.Flowchart
|
||||
/// <summary>
|
||||
/// 流程数据
|
||||
/// </summary>
|
||||
public static List<FlowNode> FlowNodes { get; set; }
|
||||
public static Dictionary<IDiagramViewModel, List<FlowNode>> FlowNodes { get; set; } = new Dictionary<IDiagramViewModel, List<FlowNode>>();
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -60,7 +60,7 @@ namespace AIStudio.Wpf.Flowchart
|
||||
/// <param name="json"></param>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public static void InitData(List<FlowNode> oASteps, List<ConnectorViewModel> connectors)
|
||||
public static void InitData(List<FlowNode> oASteps, List<ConnectorViewModel> connectors, IDiagramViewModel viewModel)
|
||||
{
|
||||
foreach (var edge in connectors)
|
||||
{
|
||||
@@ -120,8 +120,10 @@ namespace AIStudio.Wpf.Flowchart
|
||||
}
|
||||
|
||||
string nextstepid = oAStartStep.NextStepId;
|
||||
FlowNodes = InitStep(oASteps, nextstepid);
|
||||
FlowNodes.Insert(0, oAStartStep);
|
||||
var nodes = InitStep(oASteps, nextstepid);
|
||||
nodes.Insert(0, oAStartStep);
|
||||
|
||||
FlowNodes.Add(viewModel, nodes);
|
||||
|
||||
Approve(oAStartStep, 100);
|
||||
}
|
||||
@@ -214,13 +216,13 @@ namespace AIStudio.Wpf.Flowchart
|
||||
SetStatus(flowNode, status, remark);
|
||||
if (!string.IsNullOrEmpty(flowNode.NextStepId))
|
||||
{
|
||||
Next(flowNode.NextStepId);
|
||||
Next(flowNode.NextStepId, flowNode);
|
||||
}
|
||||
else if (flowNode.SelectNextStep != null && flowNode.SelectNextStep.Count > 0)
|
||||
{
|
||||
foreach (var step in flowNode.SelectNextStep)
|
||||
{
|
||||
Next(step.Key);
|
||||
Next(step.Key, flowNode);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -236,8 +238,8 @@ namespace AIStudio.Wpf.Flowchart
|
||||
break;
|
||||
case 3:
|
||||
SetStatus(flowNode, status, remark);
|
||||
FlowNodes.ForEach(p => { if (p.Status == 100) p.Status = 0; });
|
||||
Approve(FlowNodes[0], 100);
|
||||
FlowNodes[flowNode.Parent].ForEach(p => { if (p.Status == 100) p.Status = 0; });
|
||||
Approve(FlowNodes[flowNode.Parent][0], 100);
|
||||
MessageBox.Show("流程重新开始");
|
||||
break;
|
||||
case 4:
|
||||
@@ -251,16 +253,16 @@ namespace AIStudio.Wpf.Flowchart
|
||||
/// 流向下一个节点
|
||||
/// </summary>
|
||||
/// <param name="stepid"></param>
|
||||
public static void Next(string stepid)
|
||||
public static void Next(string stepid, FlowNode flowNode)
|
||||
{
|
||||
FlowNode nextNode = FlowNodes.FirstOrDefault(p => p.Id.ToString() == stepid);
|
||||
FlowNode nextNode = FlowNodes[flowNode.Parent].FirstOrDefault(p => p.Id.ToString() == stepid);
|
||||
SetStatus(nextNode, 1);
|
||||
|
||||
switch (nextNode.Kind)
|
||||
{
|
||||
case NodeKinds.Start:
|
||||
SetStatus(nextNode, 100);
|
||||
Next(nextNode.NextStepId);
|
||||
Next(nextNode.NextStepId, nextNode);
|
||||
break;
|
||||
case NodeKinds.End:
|
||||
SetStatus(nextNode, 100);
|
||||
@@ -278,33 +280,33 @@ namespace AIStudio.Wpf.Flowchart
|
||||
if (result == 1)
|
||||
{
|
||||
SetStatus(nextNode, 100);
|
||||
Next(step.Key);
|
||||
Next(step.Key, nextNode);
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
//如果表达式错了,就按第一个处理
|
||||
Next(nextNode.SelectNextStep.FirstOrDefault().Key);
|
||||
Next(nextNode.SelectNextStep.FirstOrDefault().Key, nextNode);
|
||||
break;
|
||||
case NodeKinds.COBegin:
|
||||
foreach (var step in nextNode.SelectNextStep)//启动各个分支
|
||||
{
|
||||
SetStatus(nextNode, 100);
|
||||
Next(step.Key);
|
||||
Next(step.Key, nextNode);
|
||||
}
|
||||
break;
|
||||
case NodeKinds.COEnd:
|
||||
foreach (var prestep in nextNode.PreStepId)
|
||||
{
|
||||
var step = FlowNodes.FirstOrDefault(p => p.Id.ToString() == prestep);
|
||||
var step = FlowNodes[flowNode.Parent].FirstOrDefault(p => p.Id.ToString() == prestep);
|
||||
if (step.Status != 100)//如果并行分支没有都完成,那么并行结束节点也未完成
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
SetStatus(nextNode, 100);
|
||||
Next(nextNode.NextStepId);
|
||||
Next(nextNode.NextStepId, nextNode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -318,7 +320,7 @@ namespace AIStudio.Wpf.Flowchart
|
||||
{
|
||||
if (flowNode.PreStepId != null && flowNode.PreStepId.Count == 1)
|
||||
{
|
||||
FlowNode preNode = FlowNodes.FirstOrDefault(p => p.Id.ToString() == flowNode.PreStepId[0]);
|
||||
FlowNode preNode = FlowNodes[flowNode.Parent].FirstOrDefault(p => p.Id.ToString() == flowNode.PreStepId[0]);
|
||||
if (preNode.Kind == NodeKinds.Middle)
|
||||
{
|
||||
SetStatus(preNode, 1);
|
||||
|
||||
@@ -734,7 +734,7 @@ namespace AIStudio.Wpf.Logical.ViewModels
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
|
||||
readDataTimer.Stop();
|
||||
readDataTimer.Dispose();
|
||||
}
|
||||
|
||||
|
||||
@@ -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