114 lines
4.0 KiB
C#
114 lines
4.0 KiB
C#
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);
|
|
}
|
|
}
|
|
} |