diff --git a/src/XTMF2.GUI/Controls/ModelSystemCanvas/ModelSystemCanvas.Rendering.cs b/src/XTMF2.GUI/Controls/ModelSystemCanvas/ModelSystemCanvas.Rendering.cs
index b94f7f9..c1ec14e 100644
--- a/src/XTMF2.GUI/Controls/ModelSystemCanvas/ModelSystemCanvas.Rendering.cs
+++ b/src/XTMF2.GUI/Controls/ModelSystemCanvas/ModelSystemCanvas.Rendering.cs
@@ -712,8 +712,11 @@ private void RenderLinks(DrawingContext ctx)
else if (_isLight) { glowOuter = LinkGlowOuterPenL; glowInner = LinkGlowInnerPenL; }
else { glowOuter = LinkGlowOuterPen; glowInner = LinkGlowInnerPen; }
+ bool passesExecution = link.UnderlyingLink.OriginHook.PassesExecution;
+
Point bp2, arrowFrom;
Point shaftEnd;
+ Point labelFrom;
if (link.UnderlyingLink.IsOrthogonal)
{
@@ -724,55 +727,72 @@ private void RenderLinks(DrawingContext ctx)
var pts = ComputeOrthogonalPath(link, hasSharedSpine ? spineX : (double?)null);
// pts = [p1, corner1, corner2, p2] (always 4 points)
bp2 = pts[^1];
- arrowFrom = BorderArrivalFrom(link.Destination, bp2);
- shaftEnd = DrawArrow(ctx, brush, arrowFrom, bp2);
-
- if (hasSharedSpine)
+ if (passesExecution)
{
- // For multi-link groups the trunk is identical for every sibling.
- // Draw trunk glow + stroke only once to avoid stacking alpha.
- if (_orthogonalTrunkDrawn.Add(link.UnderlyingLink))
+ arrowFrom = BorderArrivalFrom(link.Destination, bp2);
+ shaftEnd = DrawArrow(ctx, brush, arrowFrom, bp2);
+ labelFrom = pts[^2];
+
+ if (hasSharedSpine)
{
- // Build the full-extent trunk from the precomputed range.
- // The trunk is two segments that share the junction at (spineX, p1.Y):
- // 1. Horizontal exit: p1 → (spineX, p1.Y)
- // 2. Full vertical: (spineX, topY) → (spineX, bottomY)
- // Drawing them as one polyline works when p1.Y is at one extreme;
- // for the mixed case (branches above AND below) we draw two
- // segments so the spine covers the complete range.
- var p1Trunk = pts[0]; // hook anchor
- var corner1 = pts[1]; // (spineX, p1.Y)
- _orthogonalTrunkRange.TryGetValue(link.UnderlyingLink, out var range);
- var spineTop = new Point(spineX, range.TopY);
- var spineBot = new Point(spineX, range.BottomY);
-
- // Horizontal exit + vertical spine as a joined polyline.
- // The vertical goes from spineTop down to spineBot; corner1 is
- // somewhere along it, so we route: p1 → corner1 → spineTop
- // then a separate segment corner1 → spineBot (the other direction).
- // This draws the T/L shape correctly with a single extra segment.
- var mainTrunkGeo = MakePolyGeo([p1Trunk, corner1, spineTop]);
- var extGeo = MakeSegGeo(corner1, spineBot);
-
- foreach (var trunkPen in new[] { glowOuter, glowInner, pen })
+ // For multi-link groups the trunk is identical for every sibling.
+ // Draw trunk glow + stroke only once to avoid stacking alpha.
+ if (_orthogonalTrunkDrawn.Add(link.UnderlyingLink))
{
- ctx.DrawGeometry(null, trunkPen, mainTrunkGeo);
- ctx.DrawGeometry(null, trunkPen, extGeo);
+ // Build the full-extent trunk from the precomputed range.
+ // The trunk is two segments that share the junction at (spineX, p1.Y):
+ // 1. Horizontal exit: p1 → (spineX, p1.Y)
+ // 2. Full vertical: (spineX, topY) → (spineX, bottomY)
+ // Drawing them as one polyline works when p1.Y is at one extreme;
+ // for the mixed case (branches above AND below) we draw two
+ // segments so the spine covers the complete range.
+ var p1Trunk = pts[0]; // hook anchor
+ var corner1 = pts[1]; // (spineX, p1.Y)
+ _orthogonalTrunkRange.TryGetValue(link.UnderlyingLink, out var range);
+ var spineTop = new Point(spineX, range.TopY);
+ var spineBot = new Point(spineX, range.BottomY);
+
+ // Horizontal exit + vertical spine as a joined polyline.
+ // The vertical goes from spineTop down to spineBot; corner1 is
+ // somewhere along it, so we route: p1 → corner1 → spineTop
+ // then a separate segment corner1 → spineBot (the other direction).
+ // This draws the T/L shape correctly with a single extra segment.
+ var mainTrunkGeo = MakePolyGeo([p1Trunk, corner1, spineTop]);
+ var extGeo = MakeSegGeo(corner1, spineBot);
+
+ foreach (var trunkPen in new[] { glowOuter, glowInner, pen })
+ {
+ ctx.DrawGeometry(null, trunkPen, mainTrunkGeo);
+ ctx.DrawGeometry(null, trunkPen, extGeo);
+ }
}
- }
- // Branch segment: corner2 → p2 (glow) and corner2 → shaftEnd (stroke).
- var branchGlowGeo = MakeSegGeo(pts[^2], pts[^1]); // corner2 → bp2
- var branchShaftGeo = MakeSegGeo(pts[^2], shaftEnd); // corner2 → shaftEnd
- ctx.DrawGeometry(null, glowOuter, branchGlowGeo);
- ctx.DrawGeometry(null, glowInner, branchGlowGeo);
- ctx.DrawGeometry(null, pen, branchShaftGeo);
+ // Branch segment: corner2 → p2 (glow) and corner2 → shaftEnd (stroke).
+ var branchGlowGeo = MakeSegGeo(pts[^2], pts[^1]);
+ var branchShaftGeo = MakeSegGeo(pts[^2], shaftEnd);
+ ctx.DrawGeometry(null, glowOuter, branchGlowGeo);
+ ctx.DrawGeometry(null, glowInner, branchGlowGeo);
+ ctx.DrawGeometry(null, pen, branchShaftGeo);
+ }
+ else
+ {
+ // Single-destination orthogonal link: draw the full path normally.
+ var glowGeo = MakePolyGeo(pts);
+ var shaftGeo = ReplacePolyGeoLastPoint(pts, shaftEnd);
+ ctx.DrawGeometry(null, glowOuter, glowGeo);
+ ctx.DrawGeometry(null, glowInner, glowGeo);
+ ctx.DrawGeometry(null, pen, shaftGeo);
+ }
}
else
{
- // Single-destination orthogonal link: draw the full path normally.
- var glowGeo = MakePolyGeo(pts);
- var shaftGeo = ReplacePolyGeoLastPoint(pts, shaftEnd);
+ var revPts = new[] { pts[^1], pts[^2], pts[1], pts[0] };
+ arrowFrom = BorderArrivalFrom(link.Origin, revPts[^1]);
+ shaftEnd = DrawArrow(ctx, brush, arrowFrom, revPts[^1]);
+ labelFrom = revPts[1];
+
+ var glowGeo = MakePolyGeo(revPts);
+ var shaftGeo = ReplacePolyGeoLastPoint(revPts, shaftEnd);
ctx.DrawGeometry(null, glowOuter, glowGeo);
ctx.DrawGeometry(null, glowInner, glowGeo);
ctx.DrawGeometry(null, pen, shaftGeo);
@@ -784,9 +804,6 @@ private void RenderLinks(DrawingContext ctx)
// links curve gently and long ones sweep broadly, with no elbow kinks.
var (bp1, bc1, bc2, bp2c) = ComputeSCurve(link);
bp2 = bp2c;
- arrowFrom = BorderArrivalFrom(link.Destination, bp2);
- shaftEnd = DrawArrow(ctx, brush, arrowFrom, bp2);
-
// Build the geometry once; reuse for glow and main stroke.
static StreamGeometry MakeCurveGeo(Point p1, Point c1, Point c2, Point end)
{
@@ -798,12 +815,32 @@ static StreamGeometry MakeCurveGeo(Point p1, Point c1, Point c2, Point end)
return g;
}
- var glowGeo = MakeCurveGeo(bp1, bc1, bc2, bp2);
- var shaftGeo = MakeCurveGeo(bp1, bc1, bc2, shaftEnd);
+ if (passesExecution)
+ {
+ arrowFrom = BorderArrivalFrom(link.Destination, bp2);
+ shaftEnd = DrawArrow(ctx, brush, arrowFrom, bp2);
+ labelFrom = SampleCubicBezier(bp1, bc1, bc2, bp2, 0.97);
+
+ var glowGeo = MakeCurveGeo(bp1, bc1, bc2, bp2);
+ var shaftGeo = MakeCurveGeo(bp1, bc1, bc2, shaftEnd);
- ctx.DrawGeometry(null, glowOuter, glowGeo);
- ctx.DrawGeometry(null, glowInner, glowGeo);
- ctx.DrawGeometry(null, pen, shaftGeo);
+ ctx.DrawGeometry(null, glowOuter, glowGeo);
+ ctx.DrawGeometry(null, glowInner, glowGeo);
+ ctx.DrawGeometry(null, pen, shaftGeo);
+ }
+ else
+ {
+ arrowFrom = BorderArrivalFrom(link.Origin, bp1);
+ shaftEnd = DrawArrow(ctx, brush, arrowFrom, bp1);
+ labelFrom = SampleCubicBezier(bp2, bc2, bc1, bp1, 0.03);
+
+ var glowGeo = MakeCurveGeo(bp2, bc2, bc1, bp1);
+ var shaftGeo = MakeCurveGeo(bp2, bc2, bc1, shaftEnd);
+
+ ctx.DrawGeometry(null, glowOuter, glowGeo);
+ ctx.DrawGeometry(null, glowInner, glowGeo);
+ ctx.DrawGeometry(null, pen, shaftGeo);
+ }
}
// For multi-link destinations draw a small 1-based index number
@@ -819,18 +856,44 @@ static StreamGeometry MakeCurveGeo(Point p1, Point c1, Point c2, Point end)
if (idx >= 0)
{
var ft = MakeText((idx + 1).ToString(), LinkIndexFontSize, brush);
- double adx = bp2.X - arrowFrom.X;
- double ady = bp2.Y - arrowFrom.Y;
+ // Keep ordering badges outside the destination element regardless
+ // of curve direction by offsetting along the destination's outward normal.
+ // Also shift laterally (alternating above/below) so the badge does not
+ // sit on top of the arrow shaft near the destination.
+ var inward = BorderInwardNormal(link.Destination, bp2);
+ double ox = -inward.X;
+ double oy = -inward.Y;
+
+ double adx = bp2.X - labelFrom.X;
+ double ady = bp2.Y - labelFrom.Y;
double dlen = Math.Sqrt(adx * adx + ady * ady);
+ double ux, uy;
if (dlen >= 1)
{
- double ux = adx / dlen, uy = ady / dlen;
- double nx = -uy, ny = ux; // 90° CCW perpendicular unit vector
- double offset = ft.Height * 0.5 + 3;
- double lx = shaftEnd.X - ft.Width * 0.5 + nx * offset;
- double ly = shaftEnd.Y - ft.Height * 0.5 + ny * offset;
- ctx.DrawText(ft, new Point(lx, ly));
+ ux = adx / dlen;
+ uy = ady / dlen;
+ }
+ else
+ {
+ // Fallback direction when the local segment is near-degenerate.
+ ux = ox;
+ uy = oy;
}
+
+ // Lateral offset direction (90° CCW from arrow direction).
+ double nx = -uy;
+ double ny = ux;
+ double sideSign = (idx & 1) == 0 ? 1.0 : -1.0;
+
+ double outwardOffset = Math.Max(ft.Height * 0.6 + 6.0, ArrowSize + 4.0);
+ double lateralOffset = ft.Height * 0.5 + 3.0;
+
+ double anchorX = bp2.X + ox * outwardOffset + nx * lateralOffset * sideSign;
+ double anchorY = bp2.Y + oy * outwardOffset + ny * lateralOffset * sideSign;
+
+ double lx = anchorX - ft.Width * 0.5;
+ double ly = anchorY - ft.Height * 0.5;
+ ctx.DrawText(ft, new Point(lx, ly));
}
}
}
diff --git a/src/XTMF2.GUI/Views/TypePickerDialog.axaml.cs b/src/XTMF2.GUI/Views/TypePickerDialog.axaml.cs
index 358d2d7..b6191dc 100644
--- a/src/XTMF2.GUI/Views/TypePickerDialog.axaml.cs
+++ b/src/XTMF2.GUI/Views/TypePickerDialog.axaml.cs
@@ -25,6 +25,7 @@ You should have received a copy of the GNU General Public License
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
+using Avalonia.Threading;
using XTMF2.GUI.Controls;
namespace XTMF2.GUI.Views;
@@ -265,23 +266,29 @@ public TypePickerDialog(
}, RoutingStrategies.Tunnel);
UpdateFilter();
- // Focus the filter box and honour an initial selection once the window is shown.
+ // Focus the filter box and honour an initial selection once the list is loaded.
Opened += (_, _) =>
{
FilterBox.FocusSearchBox();
- if (_initialType is not null)
+ };
+
+ TypeListBox.Loaded += (_, _) =>
+ {
+ Dispatcher.UIThread.Post(() =>
{
- var idx = FilteredTypes.IndexOf(_initialType);
- if (idx >= 0)
+ if (_initialType is not null)
{
- TypeListBox.SelectedIndex = idx;
- TypeListBox.ScrollIntoView(TypeListBox.SelectedItem!);
- // Explicitly call OnListSelectionChanged to ensure CanOK is updated.
- // This is needed because if the item is already at the selected index,
- // SelectionChanged won't fire.
- OnListSelectionChanged();
+ var idx = FilteredTypes.IndexOf(_initialType);
+ if (idx >= 0)
+ {
+ TypeListBox.SelectedIndex = idx;
+ TypeListBox.ScrollIntoView(TypeListBox.SelectedItem!);
+ }
}
- }
+
+ // Ensure the OK binding reflects the realized ListBox selection.
+ OnListSelectionChanged();
+ });
};
TypeListBox.DoubleTapped += (_, _) =>
diff --git a/src/XTMF2.Interfaces/SubModuleAttribute.cs b/src/XTMF2.Interfaces/SubModuleAttribute.cs
index e543942..49117fb 100644
--- a/src/XTMF2.Interfaces/SubModuleAttribute.cs
+++ b/src/XTMF2.Interfaces/SubModuleAttribute.cs
@@ -31,12 +31,29 @@ public SubModuleAttribute()
Index = -1;
}
+ ///
+ /// The name of the submodule / Parameter.
+ ///
public string? Name { get; set; }
+ ///
+ /// The description of the submodule / Parameter.
+ ///
public string? Description { get; set; }
+ ///
+ /// Whether the submodule / Parameter is required.
+ ///
public bool Required { get; set; }
+ ///
+ /// Whether the submodule / Parameter passes execution if false then the submodule is considered input, if true then we either pass execution to the submodule or it is output.
+ ///
+ public bool PassesExecution { get; set; }
+
+ ///
+ /// The index of the submodule / Parameter within the module. This must be unique within the module.
+ ///
public int Index { get; set; }
}
}
diff --git a/src/XTMF2/ModelSystemConstruct/NodeHook.cs b/src/XTMF2/ModelSystemConstruct/NodeHook.cs
index 37c3464..022d6a4 100644
--- a/src/XTMF2/ModelSystemConstruct/NodeHook.cs
+++ b/src/XTMF2/ModelSystemConstruct/NodeHook.cs
@@ -50,13 +50,19 @@ public abstract class NodeHook
///
public string? DefaultValue;
- public NodeHook(string name, HookCardinality cardinality, int index, bool isParameter, string? defaultValue)
+ ///
+ /// True when this hook passes execution context to its destination.
+ ///
+ public bool PassesExecution { get; private set; }
+
+ public NodeHook(string name, HookCardinality cardinality, int index, bool isParameter, string? defaultValue, bool passesExecution = false)
{
Name = name;
Cardinality = cardinality;
Index = index;
IsParameter = isParameter;
DefaultValue = defaultValue;
+ PassesExecution = passesExecution;
}
protected static HookCardinality GetCardinality(Type type, bool required)
@@ -115,8 +121,8 @@ public enum HookCardinality
sealed class PropertyHook : NodeHook
{
readonly PropertyInfo Property;
- public PropertyHook(string name, PropertyInfo property, bool required, int index, bool isParameter, string? defaultValue)
- : base(name, GetCardinality(property, required), index, isParameter, defaultValue)
+ public PropertyHook(string name, PropertyInfo property, bool required, int index, bool isParameter, string? defaultValue, bool passesExecution = false)
+ : base(name, GetCardinality(property, required), index, isParameter, defaultValue, passesExecution)
{
Property = property;
}
@@ -200,8 +206,8 @@ internal override bool AnyInstalled(IModule module)
sealed class FieldHook : NodeHook
{
readonly FieldInfo Field;
- public FieldHook(string name, FieldInfo field, bool required, int index, bool isParameter, string? defaultValue)
- : base(name, GetCardinality(field, required), index, isParameter, defaultValue)
+ public FieldHook(string name, FieldInfo field, bool required, int index, bool isParameter, string? defaultValue, bool passesExecution = false)
+ : base(name, GetCardinality(field, required), index, isParameter, defaultValue, passesExecution)
{
Field = field;
}
@@ -296,7 +302,7 @@ public sealed class FunctionParameterHook : NodeHook
/// The function-parameter slot this hook exposes.
/// Ordinal position among the template's FunctionParameters.
public FunctionParameterHook(ModelSystemConstruct.FunctionParameter parameter, int index)
- : base(parameter.Name, HookCardinality.SingleOptional, index, isParameter: false, defaultValue: null)
+ : base(parameter.Name, HookCardinality.SingleOptional, index, isParameter: false, defaultValue: null, passesExecution: false)
{
Parameter = parameter;
}
diff --git a/src/XTMF2/Repository/ModuleRepository.cs b/src/XTMF2/Repository/ModuleRepository.cs
index c9ff79e..f06fbdc 100644
--- a/src/XTMF2/Repository/ModuleRepository.cs
+++ b/src/XTMF2/Repository/ModuleRepository.cs
@@ -379,7 +379,7 @@ private static void LoadFields(Type type, TypeInfo typeInfo, List hook
throw new XTMFCodeStyleError(type, $"There is no index defined for sub module property {field.Name}!");
}
// all parameters are required
- hooks.Add(new FieldHook(parameter.Name!, field, true, parameter.Index, true, parameter.DefaultValue));
+ hooks.Add(new FieldHook(parameter.Name!, field, true, parameter.Index, true, parameter.DefaultValue, parameter.PassesExecution));
}
else if (attributes.First() is SubModuleAttribute subModule)
{
@@ -387,7 +387,7 @@ private static void LoadFields(Type type, TypeInfo typeInfo, List hook
{
throw new XTMFCodeStyleError(type, $"There is no index defined for sub module property {field.Name}!");
}
- hooks.Add(new FieldHook(subModule.Name!, field, subModule.Required, subModule.Index, false, null));
+ hooks.Add(new FieldHook(subModule.Name!, field, subModule.Required, subModule.Index, false, null, subModule.PassesExecution));
}
else
{
@@ -448,7 +448,7 @@ private static void LoadProperties(Type type, TypeInfo typeInfo, List
throw new XTMFCodeStyleError(type, $"There is no index defined for sub module property {property.Name}!");
}
// all parameters are required
- hooks.Add(new PropertyHook(parameter.Name!, property, true, parameter.Index, true, parameter.DefaultValue));
+ hooks.Add(new PropertyHook(parameter.Name!, property, true, parameter.Index, true, parameter.DefaultValue, parameter.PassesExecution));
}
else if (attributes.First() is SubModuleAttribute subModule)
{
@@ -456,7 +456,7 @@ private static void LoadProperties(Type type, TypeInfo typeInfo, List
{
throw new XTMFCodeStyleError(type, $"There is no index defined for sub module property {property.Name}!");
}
- hooks.Add(new PropertyHook(subModule.Name!, property, subModule.Required, subModule.Index, false, null));
+ hooks.Add(new PropertyHook(subModule.Name!, property, subModule.Required, subModule.Index, false, null, subModule.PassesExecution));
}
else
{
diff --git a/src/XTMF2/RuntimeModules/Execute.cs b/src/XTMF2/RuntimeModules/Execute.cs
index fedf84e..f5c4f65 100644
--- a/src/XTMF2/RuntimeModules/Execute.cs
+++ b/src/XTMF2/RuntimeModules/Execute.cs
@@ -33,10 +33,10 @@ public class Execute : BaseAction
[Parameter(DefaultValue = "1", Name = "Iterations", Required = false, Index = 1)]
public IFunction? Iterations;
- [SubModule(Name = "Current Iteration", Required = false, Description = "Place to store the current iteration", Index = 2)]
+ [SubModule(Name = "Current Iteration", Required = false, Description = "Place to store the current iteration", Index = 2, PassesExecution = true)]
public ISetableValue? CurrentIteration;
- [SubModule(Name = "To Execute", Description = "The modules in order to execute", Index = 3)]
+ [SubModule(Name = "To Execute", Description = "The modules in order to execute", Index = 3, PassesExecution = true)]
public IAction[]? ToInvoke;
public override void Invoke()
@@ -78,10 +78,10 @@ public class Execute : BaseAction
[Parameter(DefaultValue = "1", Name = "Iterations", Required = false, Index = 1)]
public IFunction? Iterations;
- [SubModule(Name = "Current Iteration", Required = false, Description = "Place to store the current iteration", Index = 2)]
+ [SubModule(Name = "Current Iteration", Required = false, Description = "Place to store the current iteration", Index = 2, PassesExecution = true)]
public ISetableValue? CurrentIteration;
- [SubModule(Name = "To Execute", Description = "The modules in order to execute", Index = 3)]
+ [SubModule(Name = "To Execute", Description = "The modules in order to execute", Index = 3, PassesExecution = true)]
public IAction[]? ToInvoke;
public override void Invoke(Context context)
diff --git a/src/XTMF2/RuntimeModules/ExecuteActionsThenFunction.cs b/src/XTMF2/RuntimeModules/ExecuteActionsThenFunction.cs
index f32893f..25f9e85 100644
--- a/src/XTMF2/RuntimeModules/ExecuteActionsThenFunction.cs
+++ b/src/XTMF2/RuntimeModules/ExecuteActionsThenFunction.cs
@@ -27,13 +27,13 @@ namespace XTMF2.RuntimeModules
Description = "Allows you to execute actions before calling a function. This allows you to ")]
public class ExecuteActionsThenFunction : BaseFunction
{
- [SubModule(Index = 0, Name = "Invoke First", Description = "Actions to invoke before invoking the function.")]
+ [SubModule(Index = 0, Name = "Invoke First", Description = "Actions to invoke before invoking the function.", PassesExecution = true)]
public IAction[]? InvokeFirst;
[Parameter(Index = 1, Name = "Invoke Actions in Parallel", Description = "Should the actions be invoked in parallel?", DefaultValue = "false")]
public IFunction? InvokeActionsInParallel;
- [SubModule(Index = 2, Required = true, Name = "End With", Description = "The function to invoke and return the value of.")]
+ [SubModule(Index = 2, Required = true, Name = "End With", Description = "The function to invoke and return the value of.", PassesExecution = true)]
public IFunction? EndWith;
public override Return Invoke()
diff --git a/src/XTMF2/RuntimeModules/ExecuteWithContext.cs b/src/XTMF2/RuntimeModules/ExecuteWithContext.cs
index ae06523..d7a616a 100644
--- a/src/XTMF2/RuntimeModules/ExecuteWithContext.cs
+++ b/src/XTMF2/RuntimeModules/ExecuteWithContext.cs
@@ -26,7 +26,7 @@ public sealed class ExecuteWithContext : BaseAction
[SubModule(Required = true, Name = "Get Context", Description = "The function to get the context to execute with.", Index = 0)]
public IFunction GetContext = null!;
- [SubModule(Required = true, Name = "To Execute", Description = "The actions to execute with the context.", Index = 1)]
+ [SubModule(Required = true, Name = "To Execute", Description = "The actions to execute with the context.", Index = 1, PassesExecution = true)]
public IAction[] ToInvoke = null!;
override public void Invoke()
@@ -43,7 +43,7 @@ override public void Invoke()
Description = "Provides a way to execute a series of actions using a context provided to it.")]
public sealed class ExecuteWithForwardedContext : BaseAction
{
- [SubModule(Required = true, Name = "To Execute", Description = "The actions to execute with the context.", Index = 0)]
+ [SubModule(Required = true, Name = "To Execute", Description = "The actions to execute with the context.", Index = 0, PassesExecution = true)]
public IAction[] ToInvoke = null!;
override public void Invoke(Context context)
diff --git a/src/XTMF2/RuntimeModules/If.cs b/src/XTMF2/RuntimeModules/If.cs
index 839e4a0..9f81a06 100644
--- a/src/XTMF2/RuntimeModules/If.cs
+++ b/src/XTMF2/RuntimeModules/If.cs
@@ -30,10 +30,10 @@ public sealed class IfF : BaseFunction
Description = "The condition to invoke to see if the true or false path is taken.", DefaultValue = "true", Index = 0)]
public IFunction? Condition;
- [SubModule(Required = true, Name = "If True", Description = "The logic to invoke if true", Index = 1)]
+ [SubModule(Required = true, Name = "If True", Description = "The logic to invoke if true", Index = 1, PassesExecution = true)]
public IFunction? ToInvokeIfTrue;
- [SubModule(Required = true, Name = "If False", Description = "The logic to invoke if false", Index = 2)]
+ [SubModule(Required = true, Name = "If False", Description = "The logic to invoke if false", Index = 2, PassesExecution = true)]
public IFunction? ToInvokeIfFalse;
public override Return Invoke()
@@ -57,10 +57,10 @@ public sealed class IfF : BaseFunction
Description = "The condition to invoke to see if the true or false path is taken.", DefaultValue = "true", Index = 0)]
public IFunction? Condition;
- [SubModule(Required = true, Name = "If True", Description = "The logic to invoke if true", Index = 1)]
+ [SubModule(Required = true, Name = "If True", Description = "The logic to invoke if true", Index = 1, PassesExecution = true)]
public IFunction? ToInvokeIfTrue;
- [SubModule(Required = true, Name = "If False", Description = "The logic to invoke if false", Index = 2)]
+ [SubModule(Required = true, Name = "If False", Description = "The logic to invoke if false", Index = 2, PassesExecution = true)]
public IFunction? ToInvokeIfFalse;
public override Return Invoke(Context context)
@@ -84,10 +84,10 @@ public sealed class IfWithContextF : BaseFunction? Condition;
- [SubModule(Required = true, Name = "If True", Description = "The logic to invoke if true", Index = 1)]
+ [SubModule(Required = true, Name = "If True", Description = "The logic to invoke if true", Index = 1, PassesExecution = true)]
public IFunction? ToInvokeIfTrue;
- [SubModule(Required = true, Name = "If False", Description = "The logic to invoke if false", Index = 2)]
+ [SubModule(Required = true, Name = "If False", Description = "The logic to invoke if false", Index = 2, PassesExecution = true)]
public IFunction? ToInvokeIfFalse;
public override Return Invoke(Context context)
@@ -111,10 +111,10 @@ public sealed class IfA : BaseAction
Description = "The condition to invoke to see if the true or false path is taken.", DefaultValue = "true", Index = 0)]
public IFunction? Condition;
- [SubModule(Required = false, Name = "If True", Description = "The logic to invoke if true", Index = 1)]
+ [SubModule(Required = false, Name = "If True", Description = "The logic to invoke if true", Index = 1, PassesExecution = true)]
public IAction? ToInvokeIfTrue;
- [SubModule(Required = false, Name = "If False", Description = "The logic to invoke if false", Index = 2)]
+ [SubModule(Required = false, Name = "If False", Description = "The logic to invoke if false", Index = 2, PassesExecution = true)]
public IAction? ToInvokeIfFalse;
public override void Invoke()
@@ -138,10 +138,10 @@ public sealed class IfA : BaseAction
Description = "The condition to invoke to see if the true or false path is taken.", DefaultValue = "true", Index = 0)]
public IFunction? Condition;
- [SubModule(Required = false, Name = "If True", Description = "The logic to invoke if true", Index = 1)]
+ [SubModule(Required = false, Name = "If True", Description = "The logic to invoke if true", Index = 1, PassesExecution = true)]
public IAction? ToInvokeIfTrue;
- [SubModule(Required = false, Name = "If False", Description = "The logic to invoke if false", Index = 2)]
+ [SubModule(Required = false, Name = "If False", Description = "The logic to invoke if false", Index = 2, PassesExecution = true)]
public IAction? ToInvokeIfFalse;
public override void Invoke(Context context)
@@ -165,10 +165,10 @@ public sealed class IfWithContextA : BaseAction
Description = "The condition to invoke to see if the true or false path is taken.", DefaultValue = "true", Index = 0)]
public IFunction? Condition;
- [SubModule(Required = false, Name = "If True", Description = "The logic to invoke if true", Index = 1)]
+ [SubModule(Required = false, Name = "If True", Description = "The logic to invoke if true", Index = 1, PassesExecution = true)]
public IAction? ToInvokeIfTrue;
- [SubModule(Required = false, Name = "If False", Description = "The logic to invoke if false", Index = 2)]
+ [SubModule(Required = false, Name = "If False", Description = "The logic to invoke if false", Index = 2, PassesExecution = true)]
public IAction? ToInvokeIfFalse;
public override void Invoke(Context context)
diff --git a/src/XTMF2/RuntimeModules/Ignore.cs b/src/XTMF2/RuntimeModules/Ignore.cs
index c68b0fc..b487a67 100644
--- a/src/XTMF2/RuntimeModules/Ignore.cs
+++ b/src/XTMF2/RuntimeModules/Ignore.cs
@@ -27,7 +27,7 @@ namespace XTMF2.RuntimeModules
Description = "Ignore the result of a function call. This allows you to call functions from an action.")]
public class IgnoreResult : BaseAction
{
- [SubModule(Description = "The module to ignore the results of.", Name = "To Ignore", Required = true, Index = 0)]
+ [SubModule(Description = "The module to ignore the results of.", Name = "To Ignore", Required = true, Index = 0, PassesExecution = true)]
public IFunction? ToExecute;
public override void Invoke()
@@ -40,7 +40,7 @@ public override void Invoke()
Description = "Ignore the result of a function call. This allows you to call functions from an action.")]
public class IgnoreResult : BaseAction
{
- [SubModule(Description = "The module to ignore the results of.", Name = "To Ignore", Required = true, Index = 0)]
+ [SubModule(Description = "The module to ignore the results of.", Name = "To Ignore", Required = true, Index = 0, PassesExecution = true)]
public IFunction? ToExecute;
public override void Invoke(Context context)
@@ -53,7 +53,7 @@ public override void Invoke(Context context)
Description = "Ignore the context of a function call. This allows you to call functions that don't require a context.")]
public class IgnoreContext : BaseAction
{
- [SubModule(Description = "The module to invoke ignoring context.", Name = "To Ignore", Required = true, Index = 0)]
+ [SubModule(Description = "The module to invoke ignoring context.", Name = "To Ignore", Required = true, Index = 0, PassesExecution = true)]
public IAction? ToInvoke;
public override void Invoke(Context context)
@@ -66,7 +66,7 @@ public override void Invoke(Context context)
Description = "Ignore the context of a function call. This allows you to call functions that don't require a context.")]
public class IgnoreContext : BaseFunction
{
- [SubModule(Description = "The module to invoke ignoring context.", Name = "To Ignore", Required = true, Index = 0)]
+ [SubModule(Description = "The module to invoke ignoring context.", Name = "To Ignore", Required = true, Index = 0, PassesExecution = true)]
public IFunction? ToInvoke;
public override Return Invoke(Context context)
diff --git a/src/XTMF2/RuntimeModules/ReportInvocation.cs b/src/XTMF2/RuntimeModules/ReportInvocation.cs
index 8a163fd..6fcba20 100644
--- a/src/XTMF2/RuntimeModules/ReportInvocation.cs
+++ b/src/XTMF2/RuntimeModules/ReportInvocation.cs
@@ -37,7 +37,7 @@ public ReportFunctionInvocation(XTMFRuntime runtime)
_runtime = runtime;
}
- [SubModule(Required = true, Name = "To Invoke", Description = "Invoke after signalling context", Index = 1)]
+ [SubModule(Required = true, Name = "To Invoke", Description = "Invoke after signalling context", Index = 1, PassesExecution = true)]
public IFunction? ToInvoke;
@@ -62,7 +62,7 @@ public ReportFunctionInvocation(XTMFRuntime runtime)
_runtime = runtime;
}
- [SubModule(Required = true, Name = "To Invoke", Description = "Invoke after signalling context", Index = 1)]
+ [SubModule(Required = true, Name = "To Invoke", Description = "Invoke after signalling context", Index = 1, PassesExecution = true)]
public IFunction? ToInvoke;
public override Return Invoke(Context context)
@@ -86,7 +86,7 @@ public ReportActionInvocation(XTMFRuntime runtime)
_runtime = runtime;
}
- [SubModule(Required = true, Name = "To Invoke", Description = "Invoke after signalling context", Index = 1)]
+ [SubModule(Required = true, Name = "To Invoke", Description = "Invoke after signalling context", Index = 1, PassesExecution = true)]
public IAction? ToInvoke;
public override void Invoke()
@@ -110,7 +110,7 @@ public ReportActionInvocation(XTMFRuntime runtime)
_runtime = runtime;
}
- [SubModule(Required = true, Name = "To Invoke", Description = "Invoke after signalling context", Index = 1)]
+ [SubModule(Required = true, Name = "To Invoke", Description = "Invoke after signalling context", Index = 1, PassesExecution = true)]
public IAction? ToInvoke;
public override void Invoke(Context context)
@@ -134,7 +134,7 @@ public ReportActionInvocationWithContext(XTMFRuntime runtime)
_runtime = runtime;
}
- [SubModule(Required = true, Name = "To Invoke", Description = "Invoke after signalling context", Index = 1)]
+ [SubModule(Required = true, Name = "To Invoke", Description = "Invoke after signalling context", Index = 1, PassesExecution = true)]
public IAction? ToInvoke;
public override void Invoke(Context context)
diff --git a/src/XTMF2/RuntimeModules/SetParameter.cs b/src/XTMF2/RuntimeModules/SetParameter.cs
index f4f3042..0ac4aed 100644
--- a/src/XTMF2/RuntimeModules/SetParameter.cs
+++ b/src/XTMF2/RuntimeModules/SetParameter.cs
@@ -20,7 +20,7 @@ namespace XTMF2.RuntimeModules;
DocumentationLink = "https://tmg.utoronto.ca/doc/2.0/xtmf2/modules/XTMF2/RuntimeModules/SetParameter.html")]
public sealed class SetParameter : BaseAction
{
- [Parameter(Required = true, Name = "Value", Description = "The value to set the parameter to.", Index = 0)]
+ [Parameter(Required = true, Name = "Value", Description = "The value to set the parameter to.", Index = 0, PassesExecution = true)]
public ISetableValue Value = null!;
[Parameter(Required = true, Name = "New Value", Description = "The value to set the parameter to.", Index = 1)]
diff --git a/src/XTMF2/RuntimeModules/StartModule.cs b/src/XTMF2/RuntimeModules/StartModule.cs
index cf55f58..30be9d9 100644
--- a/src/XTMF2/RuntimeModules/StartModule.cs
+++ b/src/XTMF2/RuntimeModules/StartModule.cs
@@ -29,7 +29,7 @@ namespace XTMF2.RuntimeModules
Description = "A starting point for a model system.")]
public sealed class StartModule : BaseAction
{
- [SubModule(Name = "ToExecute", Description = "The node to invoke when executing this start.", Index = 0)]
+ [SubModule(Name = "ToExecute", Description = "The node to invoke when executing this start.", Index = 0, PassesExecution = true)]
public IAction? ToExecute;
public override void Invoke()
diff --git a/src/XTMF2/RuntimeModules/WriteToLog.cs b/src/XTMF2/RuntimeModules/WriteToLog.cs
index d46738d..8c16ef1 100644
--- a/src/XTMF2/RuntimeModules/WriteToLog.cs
+++ b/src/XTMF2/RuntimeModules/WriteToLog.cs
@@ -29,7 +29,7 @@ public sealed class WriteToLogF : BaseFunction
[SubModule(Required = true, Name = "Log", Description = "The log that will be written to.", Index = 0)]
public IFunction Log = null!;
- [SubModule(Required = true, Name = "To Invoke", Description = "The function to execute after writing to the log.", Index = 1)]
+ [SubModule(Required = true, Name = "To Invoke", Description = "The function to execute after writing to the log.", Index = 1, PassesExecution = true)]
public IFunction ToInvoke = null!;
[Parameter(Required = true, Name = "Message", Description = "The message to write to the log.", DefaultValue = "", Index = 2)]
@@ -50,7 +50,7 @@ public sealed class WriteToLogF : BaseFunction
[SubModule(Required = true, Name = "Log", Description = "The log that will be written to.", Index = 0)]
public IFunction Log = null!;
- [SubModule(Required = true, Name = "To Invoke", Description = "The function to execute after writing to the log.", Index = 1)]
+ [SubModule(Required = true, Name = "To Invoke", Description = "The function to execute after writing to the log.", Index = 1, PassesExecution = true)]
public IFunction ToInvoke = null!;
[Parameter(Required = true, Name = "Message", Description = "The message to write to the log.", DefaultValue = "", Index = 2)]
@@ -71,7 +71,7 @@ public sealed class WriteToLogBasedOnContextF : BaseFunction Log = null!;
- [SubModule(Required = true, Name = "To Invoke", Description = "The function to execute after writing to the log.", Index = 1)]
+ [SubModule(Required = true, Name = "To Invoke", Description = "The function to execute after writing to the log.", Index = 1, PassesExecution = true)]
public IFunction ToInvoke = null!;
[Parameter(Required = true, Name = "Message", Description = "The message to write to the log.", DefaultValue = "", Index = 2)]
@@ -92,7 +92,7 @@ public sealed class WriteToLogA : BaseAction
[SubModule(Required = true, Name = "Log", Description = "The log that will be written to.", Index = 0)]
public IFunction Log = null!;
- [SubModule(Required = false, Name = "To Invoke", Description = "The function to execute after writing to the log.", Index = 1)]
+ [SubModule(Required = false, Name = "To Invoke", Description = "The function to execute after writing to the log.", Index = 1, PassesExecution = true)]
public IAction? ToInvoke;
[Parameter(Required = true, Name = "Message", Description = "The message to write to the log.", DefaultValue = "", Index = 2)]
@@ -113,7 +113,7 @@ public sealed class WriteToLogA : BaseAction
[SubModule(Required = true, Name = "Log", Description = "The log that will be written to.", Index = 0)]
public IFunction Log = null!;
- [SubModule(Required = false, Name = "To Invoke", Description = "The function to execute after writing to the log.", Index = 1)]
+ [SubModule(Required = false, Name = "To Invoke", Description = "The function to execute after writing to the log.", Index = 1, PassesExecution = true)]
public IAction? ToInvoke;
[Parameter(Required = true, Name = "Message", Description = "The message to write to the log.", DefaultValue = "", Index = 2)]
@@ -134,7 +134,7 @@ public sealed class WriteToLogBasedOnContextA : BaseAction
[SubModule(Required = true, Name = "Log", Description = "The log that will be written to.", Index = 0)]
public IFunction Log = null!;
- [SubModule(Required = true, Name = "To Invoke", Description = "The function to execute after writing to the log.", Index = 1)]
+ [SubModule(Required = true, Name = "To Invoke", Description = "The function to execute after writing to the log.", Index = 1, PassesExecution = true)]
public IAction ToInvoke = null!;
[Parameter(Required = true, Name = "Message", Description = "The message to write to the log.", DefaultValue = "", Index = 2)]