Files
ParkingRobot/ClumsyPilot/TrajectoryPlanningVisualization/Contracts/VisualizationPrimitives.cs
T

148 lines
4.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace TrajectoryPlanningVisualization;
public sealed class VisualizationPoint
{
public VisualizationPoint(double x, double y)
{
VisualizationContract.RequireFinite(x, nameof(x));
VisualizationContract.RequireFinite(y, nameof(y));
X = x;
Y = y;
}
public double X { get; }
public double Y { get; }
}
public sealed class VisualizationPose
{
public VisualizationPose(double x, double y, double headingRadians)
{
VisualizationContract.RequireFinite(x, nameof(x));
VisualizationContract.RequireFinite(y, nameof(y));
VisualizationContract.RequireFinite(headingRadians, nameof(headingRadians));
X = x;
Y = y;
HeadingRadians = headingRadians;
}
public double X { get; }
public double Y { get; }
public double HeadingRadians { get; }
}
public sealed class VisualizationBounds
{
public VisualizationBounds(double xMin, double xMax, double yMin, double yMax)
{
VisualizationContract.RequireFinite(xMin, nameof(xMin));
VisualizationContract.RequireFinite(xMax, nameof(xMax));
VisualizationContract.RequireFinite(yMin, nameof(yMin));
VisualizationContract.RequireFinite(yMax, nameof(yMax));
if (xMax < xMin || yMax < yMin)
{
throw new ArgumentOutOfRangeException(nameof(xMax), "Bounds maxima must not precede minima.");
}
XMin = xMin;
XMax = xMax;
YMin = yMin;
YMax = yMax;
}
public double XMin { get; }
public double XMax { get; }
public double YMin { get; }
public double YMax { get; }
}
public sealed class VisualizationValue
{
public VisualizationValue(string chineseName, string rawName, string value, string unit, string severity)
{
ChineseName = VisualizationContract.RequireText(chineseName, nameof(chineseName));
RawName = VisualizationContract.RequireText(rawName, nameof(rawName));
Value = VisualizationContract.RequireText(value, nameof(value));
Unit = VisualizationContract.RequireText(unit, nameof(unit));
if (severity != "normal" && severity != "notice" && severity != "failure")
{
throw new ArgumentOutOfRangeException(nameof(severity), "Severity must be normal, notice, or failure.");
}
Severity = severity;
}
public string ChineseName { get; }
public string RawName { get; }
public string Value { get; }
public string Unit { get; }
public string Severity { get; }
}
public sealed class VisualizationConfigurationGroup
{
public VisualizationConfigurationGroup(string chineseTitle, IReadOnlyList<VisualizationValue> entries)
{
ChineseTitle = VisualizationContract.RequireText(chineseTitle, nameof(chineseTitle));
Entries = VisualizationContract.Copy(entries, nameof(entries));
}
public string ChineseTitle { get; }
public IReadOnlyList<VisualizationValue> Entries { get; }
}
internal static class VisualizationContract
{
public static string RequireText(string value, string parameterName)
{
if (value == null)
{
throw new ArgumentNullException(parameterName);
}
return value;
}
public static void RequireFinite(double value, string parameterName)
{
if (double.IsNaN(value) || double.IsInfinity(value))
{
throw new ArgumentOutOfRangeException(parameterName, "Value must be finite.");
}
}
public static void RequireFinite(double? value, string parameterName)
{
if (value.HasValue)
{
RequireFinite(value.Value, parameterName);
}
}
public static IReadOnlyList<T> Copy<T>(IReadOnlyList<T> values, string parameterName)
{
if (values == null)
{
throw new ArgumentNullException(parameterName);
}
var copy = new List<T>(values.Count);
for (var index = 0; index < values.Count; index++)
{
T value = values[index];
if (value is null)
{
throw new ArgumentException("Collections cannot contain null elements.", parameterName);
}
copy.Add(value);
}
return new ReadOnlyCollection<T>(copy);
}
}