feat: port p-rec-annot line-number command planning
This commit is contained in:
@@ -55,6 +55,10 @@ public interface ILineNumberAnnotationFormatter
|
|||||||
public sealed record DataLinksPropertyReadResult(bool Success, IReadOnlyDictionary<string, string?> Properties, string? FailureCode = null);
|
public sealed record DataLinksPropertyReadResult(bool Success, IReadOnlyDictionary<string, string?> Properties, string? FailureCode = null);
|
||||||
public interface IDataLinksPropertyReader { DataLinksPropertyReadResult ReadProperties(long rowId); }
|
public interface IDataLinksPropertyReader { DataLinksPropertyReadResult ReadProperties(long rowId); }
|
||||||
public sealed record LineNumberFieldResolution(bool Success, IReadOnlyDictionary<string, string?> Values, string? FailureCode = null);
|
public sealed record LineNumberFieldResolution(bool Success, IReadOnlyDictionary<string, string?> Values, string? FailureCode = null);
|
||||||
|
public sealed record LineNumberCandidate(string StableId, long RowId, AnnotationPoint Position, double Rotation, string Layer, string TextStyle, IReadOnlyDictionary<string, string?> Properties);
|
||||||
|
public sealed record ExistingLineNumberAnnotation(string StableId, string SourceStableId, string Text);
|
||||||
|
public sealed record LineNumberCommandOperation(string StableId, AnnotationOperationKind Kind, string? Text, AnnotationPoint Position, double Rotation, string Layer, string TextStyle, IReadOnlyList<string> Reasons);
|
||||||
|
public sealed record LineNumberCommandPlan(IReadOnlyList<LineNumberCommandOperation> Operations);
|
||||||
|
|
||||||
public sealed record GeometrySnapshot
|
public sealed record GeometrySnapshot
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using PRecAnnot.Abstractions;
|
||||||
|
namespace PRecAnnot.Core;
|
||||||
|
|
||||||
|
public sealed class LineNumberCommandPlanner(ILineNumberAnnotationFormatter formatter)
|
||||||
|
{
|
||||||
|
public LineNumberCommandPlan Build(LineNumberAnnotationDefinition definition, IEnumerable<LineNumberCandidate> candidates, IEnumerable<ExistingLineNumberAnnotation> existing)
|
||||||
|
{
|
||||||
|
var seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
var indexed = existing.GroupBy(x => x.SourceStableId, StringComparer.OrdinalIgnoreCase).ToDictionary(x => x.Key, x => x.First(), StringComparer.OrdinalIgnoreCase);
|
||||||
|
var result = new List<LineNumberCommandOperation>();
|
||||||
|
foreach (var candidate in candidates.OrderBy(x => x.StableId, StringComparer.Ordinal))
|
||||||
|
{
|
||||||
|
if (!seen.Add(candidate.StableId)) { result.Add(new(candidate.StableId, AnnotationOperationKind.Conflict, null, candidate.Position, candidate.Rotation, candidate.Layer, candidate.TextStyle, ["DUPLICATE_CANDIDATE"])); continue; }
|
||||||
|
var text = formatter.Format(definition, candidate.Properties);
|
||||||
|
if (!text.Success) { result.Add(new(candidate.StableId, AnnotationOperationKind.Skip, null, candidate.Position, candidate.Rotation, candidate.Layer, candidate.TextStyle, [text.ErrorCode ?? "FORMAT_FAILED"])); continue; }
|
||||||
|
result.Add(new(candidate.StableId, indexed.ContainsKey(candidate.StableId) ? AnnotationOperationKind.Update : AnnotationOperationKind.Create, text.Text, candidate.Position, candidate.Rotation, candidate.Layer, candidate.TextStyle, Array.Empty<string>()));
|
||||||
|
}
|
||||||
|
return new(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -35,6 +35,12 @@ public sealed class EntryPoint : IExtensionApplication
|
|||||||
[CommandMethod("PXP-OA")]
|
[CommandMethod("PXP-OA")]
|
||||||
public void OrthoAnnotateCommand() => RunDiagnostic("PXP-OA");
|
public void OrthoAnnotateCommand() => RunDiagnostic("PXP-OA");
|
||||||
|
|
||||||
|
[CommandMethod("PXP-LN")] public void AnnotateLineNumbersCommand() => RunDiagnostic("PXP-LN");
|
||||||
|
[CommandMethod("PXP-ULN")] public void UpdateLineNumbersCommand() => RunDiagnostic("PXP-ULN");
|
||||||
|
[CommandMethod("PXP-ESN")] public void EditLineNumberStartCommand() => RunDiagnostic("PXP-ESN");
|
||||||
|
[CommandMethod("PXP-ELN")] public void EditLineNumbersCommand() => RunDiagnostic("PXP-ELN");
|
||||||
|
[CommandMethod("PXP-RMP")] public void ResetMarkerPositionCommand() => RunDiagnostic("PXP-RMP");
|
||||||
|
|
||||||
[CommandMethod("PHP_REC_AUTOMATION_START", CommandFlags.Session)]
|
[CommandMethod("PHP_REC_AUTOMATION_START", CommandFlags.Session)]
|
||||||
public void AutomationStartCommand() => FirstLimitedApplyAutomationBootstrap.Arm();
|
public void AutomationStartCommand() => FirstLimitedApplyAutomationBootstrap.Arm();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using PRecAnnot.Abstractions;
|
||||||
|
using PRecAnnot.Core;
|
||||||
|
namespace PRecAnnot.Core.Tests;
|
||||||
|
public sealed class LineNumberCommandPlannerTests
|
||||||
|
{
|
||||||
|
[Fact] public void ProducesDeterministicCreateUpdateAndDuplicateDecisions()
|
||||||
|
{
|
||||||
|
var def = new LineNumberAnnotationDefinition { Nickname="LN", Tags=[new() { Field="EngineeringItems.LineNumber" }] };
|
||||||
|
var c = new LineNumberCandidate("b", 1, new(0,0), 0, "PXP", "Standard", new Dictionary<string,string?> { ["EngineeringItems.LineNumber"]="L-2" });
|
||||||
|
var plan = new LineNumberCommandPlanner(new LineNumberAnnotationFormatter()).Build(def, [c, c, c with { StableId="a" }], [new("x", "b", "old")]);
|
||||||
|
Assert.Collection(plan.Operations, x => Assert.Equal(AnnotationOperationKind.Create,x.Kind), x => Assert.Equal(AnnotationOperationKind.Update,x.Kind), x => Assert.Equal(AnnotationOperationKind.Conflict,x.Kind));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user