port from perforce
This commit is contained in:
114
intromat/Intromat/Nodes/Code/ForLoopNode.cs
Normal file
114
intromat/Intromat/Nodes/Code/ForLoopNode.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Linq;
|
||||
using DynamicData;
|
||||
using Intromat.Model.Compiler;
|
||||
using Intromat.PersistentModel;
|
||||
using Intromat.ViewModels;
|
||||
using Intromat.ViewModels.Editors;
|
||||
using Intromat.ViewModels.Previews;
|
||||
using Intromat.Views;
|
||||
using NodeNetwork.Toolkit.ValueNode;
|
||||
using NodeNetwork.ViewModels;
|
||||
using ReactiveUI;
|
||||
using Splat;
|
||||
|
||||
namespace Intromat.Nodes.Code
|
||||
{
|
||||
public class ForLoopNode : ExecutionNodeBase
|
||||
{
|
||||
static ForLoopNode()
|
||||
{
|
||||
Locator.CurrentMutable.Register(() => new CodeGenNodeView(), typeof(IViewFor<ForLoopNode>));
|
||||
}
|
||||
|
||||
public ForLoopNode() : base(NodeType.Code)
|
||||
{
|
||||
var boundsGroup = new EndpointGroup("Bounds");
|
||||
|
||||
Name = "For Loop";
|
||||
|
||||
LoopBodyFlow = new CodeGenInputViewModel<IStatement>(EPortType.Execution)
|
||||
{
|
||||
Name = "Loop Body",
|
||||
Group = _executionFlowGroup
|
||||
};
|
||||
Inputs.Add(LoopBodyFlow);
|
||||
|
||||
FirstIndex = new CodeGenInputViewModel<ITypedExpression<int>>(EPortType.Integer)
|
||||
{
|
||||
Name = "First Index",
|
||||
Group = boundsGroup,
|
||||
Editor = FirstIndexEditor
|
||||
};
|
||||
Inputs.Add(FirstIndex);
|
||||
|
||||
LastIndex = new CodeGenInputViewModel<ITypedExpression<int>>(EPortType.Integer)
|
||||
{
|
||||
Name = "Last Index",
|
||||
Group = boundsGroup,
|
||||
Editor = LastIndexEditor
|
||||
};
|
||||
|
||||
Inputs.Add(LastIndex);
|
||||
|
||||
var loopBodyChanged = LoopBodyFlow.ValueChanged.Select(_ => Unit.Default).StartWith(Unit.Default);
|
||||
FlowIn.Value = loopBodyChanged
|
||||
.CombineLatest(FlowOutChanged, FirstIndex.ValueChanged, LastIndex.ValueChanged, (bodyChange, endChange, firstI, lastI) => (BodyChange: bodyChange, EndChange: endChange, FirstI: firstI, LastI: lastI))
|
||||
.Select(v => new ForLoopValue
|
||||
{
|
||||
LoopBody = LoopBodyFlow.Value,
|
||||
FlowOut = FlowOut.Value,
|
||||
LowerBound = v.FirstI,
|
||||
UpperBound = v.LastI
|
||||
});
|
||||
|
||||
CurrentIndex = new CodeGenOutputViewModel<ITypedExpression<int>>(EPortType.Integer)
|
||||
{
|
||||
Name = "Current Index",
|
||||
Value = FlowIn.Value.Select(v => new VariableReference<int> { LocalVariable = ((ForLoopValue)v).CurrentIndex })
|
||||
};
|
||||
Outputs.Add(CurrentIndex);
|
||||
|
||||
var stringPreview = new StringPreviewViewModel();
|
||||
Preview = stringPreview;
|
||||
|
||||
FlowIn.Value.Subscribe(v =>
|
||||
{
|
||||
var forLoop = (ForLoopValue)v;
|
||||
stringPreview.Value = $"[{forLoop.LowerBound?.PreviewValue ?? "0"}..{forLoop.UpperBound?.PreviewValue ?? "0"}]";
|
||||
});
|
||||
}
|
||||
|
||||
public ValueNodeInputViewModel<IStatement> LoopBodyFlow { get; }
|
||||
|
||||
public IntegerExpressionEditorViewModel FirstIndexEditor { get; } = new();
|
||||
public ValueNodeInputViewModel<ITypedExpression<int>> FirstIndex { get; }
|
||||
|
||||
public IntegerExpressionEditorViewModel LastIndexEditor { get; } = new();
|
||||
public ValueNodeInputViewModel<ITypedExpression<int>> LastIndex { get; }
|
||||
|
||||
public ValueNodeOutputViewModel<ITypedExpression<int>> CurrentIndex { get; }
|
||||
|
||||
public override NodeModelBase CreateModel()
|
||||
{
|
||||
return new ForLoopModel();
|
||||
}
|
||||
|
||||
public override void SaveModel(NodeModelBase model)
|
||||
{
|
||||
base.SaveModel(model);
|
||||
var forLoop = (ForLoopModel)model;
|
||||
forLoop.FirstIndex = FirstIndexEditor.CreateModel();
|
||||
forLoop.LastIndex = LastIndexEditor.CreateModel();
|
||||
}
|
||||
|
||||
public override void LoadModel(NodeModelBase model)
|
||||
{
|
||||
base.LoadModel(model);
|
||||
var forLoop = (ForLoopModel)model;
|
||||
FirstIndexEditor.LoadModel(forLoop.FirstIndex);
|
||||
LastIndexEditor.LoadModel(forLoop.LastIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user