< Summary

Information
Class: Trailblazer.Pathing.TraversalTransitionRuleComparer
Assembly: Trailblazer
File(s): /home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Pathing/Map/TraversalTransitionRule.cs
Line coverage
100%
Covered lines: 2
Uncovered lines: 0
Coverable lines: 2
Total lines: 143
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
Compare(...)100%11100%

File(s)

/home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Pathing/Map/TraversalTransitionRule.cs

#LineLine coverage
 1//=======================================================================
 2// TraversalTransitionRule.cs
 3//=======================================================================
 4// MIT License, Copyright (c) 2024-present David Oravsky (mrdav30)
 5// See LICENSE file in the project root for full license information.
 6//=======================================================================
 7
 8using System;
 9using System.Collections.Generic;
 10using FixedMathSharp;
 11using SwiftCollections.Utility;
 12
 13namespace Trailblazer.Pathing;
 14
 15/// <summary>Stores one immutable bounded procedural transition authoring rule.</summary>
 16public readonly struct TraversalTransitionRule : IEquatable<TraversalTransitionRule>
 17{
 18    internal const TraversalTransitionLocomotionHints KnownLocomotionHints =
 19        TraversalTransitionLocomotionHints.RequestClimb
 20        | TraversalTransitionLocomotionHints.PreserveClimbAfterCompletion;
 21
 22    /// <summary>Creates one complete bounded procedural transition rule.</summary>
 23    public TraversalTransitionRule(
 24        string id,
 25        TraversalTransitionType type,
 26        TraversalMedium sourceMedium,
 27        TraversalMedium destinationMedium,
 28        TraversalTransitionRuleScope scope,
 29        TraversalCapability requiredCapabilities,
 30        Fixed64 actionCost,
 31        TraversalTransitionLocomotionHints locomotionHints)
 32    {
 33        Id = id;
 34        Type = type;
 35        SourceMedium = sourceMedium;
 36        DestinationMedium = destinationMedium;
 37        Scope = scope;
 38        RequiredCapabilities = requiredCapabilities;
 39        ActionCost = actionCost;
 40        LocomotionHints = locomotionHints;
 41        Validate();
 42    }
 43
 44    /// <summary>Gets the stable globally unique rule identifier.</summary>
 45    public string Id { get; }
 46
 47    /// <summary>Gets the semantic action type.</summary>
 48    public TraversalTransitionType Type { get; }
 49
 50    /// <summary>Gets the exact source medium.</summary>
 51    public TraversalMedium SourceMedium { get; }
 52
 53    /// <summary>Gets the exact destination medium.</summary>
 54    public TraversalMedium DestinationMedium { get; }
 55
 56    /// <summary>Gets the bounded procedural scope.</summary>
 57    public TraversalTransitionRuleScope Scope { get; }
 58
 59    /// <summary>Gets the capabilities required to use the action.</summary>
 60    public TraversalCapability RequiredCapabilities { get; }
 61
 62    /// <summary>Gets the non-negative semantic action cost.</summary>
 63    public Fixed64 ActionCost { get; }
 64
 65    /// <summary>Gets the authored built-in locomotion hints.</summary>
 66    public TraversalTransitionLocomotionHints LocomotionHints { get; }
 67
 68    /// <inheritdoc />
 69    public bool Equals(TraversalTransitionRule other) =>
 70        string.Equals(Id, other.Id, StringComparison.Ordinal)
 71        && Type == other.Type
 72        && SourceMedium == other.SourceMedium
 73        && DestinationMedium == other.DestinationMedium
 74        && Scope == other.Scope
 75        && RequiredCapabilities == other.RequiredCapabilities
 76        && ActionCost == other.ActionCost
 77        && LocomotionHints == other.LocomotionHints;
 78
 79    /// <inheritdoc />
 80    public override bool Equals(object? obj) =>
 81        obj is TraversalTransitionRule other && Equals(other);
 82
 83    /// <inheritdoc />
 84    public override int GetHashCode()
 85    {
 86        int idHash = Id == null
 87            ? 0
 88            : SwiftHashTools.GetDeterministicStringEqualityComparer().GetHashCode(Id);
 89        int hash = SwiftHashTools.CombineHashCodes(idHash, (int)Type);
 90        hash = SwiftHashTools.CombineHashCodes(hash, (int)SourceMedium);
 91        hash = SwiftHashTools.CombineHashCodes(hash, (int)DestinationMedium);
 92        hash = SwiftHashTools.CombineHashCodes(hash, (int)Scope);
 93        hash = SwiftHashTools.CombineHashCodes(hash, (int)RequiredCapabilities);
 94        hash = SwiftHashTools.CombineHashCodes(hash, ActionCost.GetHashCode());
 95        return SwiftHashTools.CombineHashCodes(hash, (int)LocomotionHints);
 96    }
 97
 98    internal void Validate()
 99    {
 100        SwiftThrowHelper.ThrowIfArgument(
 101            string.IsNullOrWhiteSpace(Id),
 102            nameof(Id),
 103            "Rule ID cannot be null, empty, or whitespace.");
 104        SwiftThrowHelper.ThrowIfArgument(
 105            !TraversalTransitionDefinition.IsKnownType(Type),
 106            nameof(Type),
 107            "Transition type is unknown.");
 108        SwiftThrowHelper.ThrowIfArgument(
 109            !TraversalTransitionDefinition.IsKnownMedium(SourceMedium),
 110            nameof(SourceMedium),
 111            "Source medium must identify one known traversal medium.");
 112        SwiftThrowHelper.ThrowIfArgument(
 113            !TraversalTransitionDefinition.IsKnownMedium(DestinationMedium),
 114            nameof(DestinationMedium),
 115            "Destination medium must identify one known traversal medium.");
 116        SwiftThrowHelper.ThrowIfArgument(
 117            Scope is < TraversalTransitionRuleScope.SameCell
 118                or > TraversalTransitionRuleScope.PositiveFaceContact,
 119            nameof(Scope),
 120            "Rule scope is unknown.");
 121        SwiftThrowHelper.ThrowIfArgument(
 122            (RequiredCapabilities & ~NavigationCell.KnownCapabilities) != 0,
 123            nameof(RequiredCapabilities),
 124            "Required capabilities contain an unknown bit.");
 125        SwiftThrowHelper.ThrowIfArgument(
 126            ActionCost < Fixed64.Zero,
 127            nameof(ActionCost),
 128            "Action cost must be non-negative.");
 129        SwiftThrowHelper.ThrowIfArgument(
 130            (LocomotionHints & ~KnownLocomotionHints) != 0,
 131            nameof(LocomotionHints),
 132            "Locomotion hints contain an unknown bit.");
 133    }
 134}
 135
 136/// <summary>Provides complete deterministic canonical ordering for transition rules.</summary>
 137internal sealed class TraversalTransitionRuleComparer : IComparer<TraversalTransitionRule>
 138{
 1139    internal static readonly TraversalTransitionRuleComparer Instance = new();
 140
 141    public int Compare(TraversalTransitionRule left, TraversalTransitionRule right) =>
 15142        string.CompareOrdinal(left.Id, right.Id);
 143}