Pipe testing

This commit is contained in:
Michael Schimmel
2025-12-26 17:20:00 +01:00
parent 185f8273dd
commit d5d71afdaa
13 changed files with 569 additions and 193 deletions
+1
View File
@@ -480,6 +480,7 @@ begin
vkRecordSeries: Result := TDataValue.FromSeries(baseValue.AsRecordSeries.Fields[Node.Member.Value]);
vkScalarRecord: Result := TDataValue(baseValue.AsScalarRecord.Fields[Node.Member.Value]);
vkGenericRecord: Result := TDataValue(baseValue.AsGenericRecord.Fields[Node.Member.Value]);
vkStream: Result := TDataValue.FromSeries(baseValue.AsStream.Series.Fields[Node.Member.Value]);
else
raise EEvaluatorException.Create('Member access operator `.` is not supported for this value type.');
end;
@@ -0,0 +1,177 @@
unit Myc.Fmx.AstEditor.Handlers.Pipes;
interface
uses
System.SysUtils,
System.UITypes,
System.Types,
Myc.Ast,
Myc.Ast.Nodes,
Myc.Fmx.AstEditor.Render,
Myc.Fmx.AstEditor.Node,
Myc.Fmx.AstEditor.Handlers;
type
// --- Pipe Container ---
TPipeNodeHandler = class(TBaseNodeHandler<IPipeNode>)
private
FInputsNode: TAstViewNode;
FTransformNode: TAstViewNode;
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
// --- Pipe Inputs ---
TPipeInputListHandler = class(TNodeListHandler<IPipeInputNode>)
protected
function GetOrientation: TLayoutOrientation; override;
function GetAlignment: TLayoutAlignment; override;
public
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
TPipeInputNodeHandler = class(TBaseNodeHandler<IPipeInputNode>)
private
FStreamNode: TAstViewNode;
FSelectorsNode: TAstViewNode;
public
procedure BuildUI(OwnerNode: TAstViewNode); override;
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
// --- Selectors ---
TPipeSelectorListHandler = class(TNodeListHandler<IKeywordNode>)
protected
function GetOrientation: TLayoutOrientation; override;
public
function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
end;
implementation
{ TPipeNodeHandler }
procedure TPipeNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
header: TTextNode;
arrow: TTextNode;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth + 1);
OwnerNode.Frameless := False;
OwnerNode.Orientation := loVertical;
OwnerNode.Alignment := laCenter;
// Distinct background color for Pipes to make them stand out as data flows
OwnerNode.BackgroundColor := $FF202530;
OwnerNode.BorderColor := TAlphaColors.Slateblue;
// Header
header := OwnerNode.AddLabel(OwnerNode, 'Pipe Pipeline');
header.FontSettings.Font.Style := [TFontStyle.fsBold];
header.Color := TAlphaColors.Lightskyblue;
// Section 1: Inputs
FInputsNode := visu.CallAccept(FNode.Inputs);
// Visual Separator / Direction indicator
arrow := OwnerNode.AddLabel(OwnerNode, '▼ Transform ▼');
arrow.FontSettings.Font.Size := 10;
arrow.Color := TAlphaColors.Gray;
arrow.Margins := TMarginRect.Create(0, 5, 0, 5);
// Section 2: Transformation (Lambda)
FTransformNode := visu.CallAccept(FNode.Transformation);
end;
function TPipeNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result :=
TAst.Pipe(FNode.Identity, FInputsNode.CreateAst.AsPipeInputList, FTransformNode.CreateAst.AsLambdaExpression, FNode.StaticType);
end;
{ TPipeInputListHandler }
function TPipeInputListHandler.GetOrientation: TLayoutOrientation;
begin
// Stack inputs vertically
Result := loVertical;
end;
function TPipeInputListHandler.GetAlignment: TLayoutAlignment;
begin
Result := laFlush;
end;
function TPipeInputListHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
var
arr: TArray<IPipeInputNode>;
i: Integer;
begin
SetLength(arr, FChildNodes.Count);
for i := 0 to FChildNodes.Count - 1 do
arr[i] := FChildNodes[i].CreateAst.AsPipeInput;
Result := TPipeInputList.Create(arr, FNode.Identity);
end;
{ TPipeInputNodeHandler }
procedure TPipeInputNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
visu: IAstVisualizer;
begin
visu := OwnerNode.Visualizer.Clone(OwnerNode, OwnerNode.Visualizer.ExprDepth);
OwnerNode.Frameless := True;
OwnerNode.Orientation := loHorizontal;
OwnerNode.Alignment := laCenter;
// "StreamName [ :Col :Col ]"
FStreamNode := visu.CallAccept(FNode.StreamSource);
// Add small spacing
var spacer := TAutoFitLayout.Create(OwnerNode.Host);
spacer.Size := TSizeF.Create(5, 5);
OwnerNode.AddChild(spacer);
FSelectorsNode := visu.CallAccept(FNode.Selectors);
end;
function TPipeInputNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
Result :=
TAst.PipeInput(
FNode.StreamSource, // Identifiers are immutable usually, or re-create if needed
FSelectorsNode.CreateAst.AsPipeSelectorList,
FNode.Identity.Location
);
end;
{ TPipeSelectorListHandler }
function TPipeSelectorListHandler.GetOrientation: TLayoutOrientation;
begin
// Selectors are horizontal: [:A :B :C]
Result := loHorizontal;
end;
function TPipeSelectorListHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
var
arr: TArray<IKeywordNode>;
i: Integer;
begin
SetLength(arr, FChildNodes.Count);
for i := 0 to FChildNodes.Count - 1 do
arr[i] := FChildNodes[i].CreateAst.AsKeyword;
Result := TPipeSelectorList.Create(arr, FNode.Identity);
end;
end.