< Summary

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

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
Equals(...)100%1414100%
Equals(...)100%22100%
GetHashCode()100%22100%
Validate()100%44100%

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    {
 9233        Id = id;
 9234        Type = type;
 9235        SourceMedium = sourceMedium;
 9236        DestinationMedium = destinationMedium;
 9237        Scope = scope;
 9238        RequiredCapabilities = requiredCapabilities;
 9239        ActionCost = actionCost;
 9240        LocomotionHints = locomotionHints;
 9241        Validate();
 8342    }
 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) =>
 1370        string.Equals(Id, other.Id, StringComparison.Ordinal)
 1371        && Type == other.Type
 1372        && SourceMedium == other.SourceMedium
 1373        && DestinationMedium == other.DestinationMedium
 1374        && Scope == other.Scope
 1375        && RequiredCapabilities == other.RequiredCapabilities
 1376        && ActionCost == other.ActionCost
 1377        && LocomotionHints == other.LocomotionHints;
 78
 79    /// <inheritdoc />
 80    public override bool Equals(object? obj) =>
 381        obj is TraversalTransitionRule other && Equals(other);
 82
 83    /// <inheritdoc />
 84    public override int GetHashCode()
 85    {
 886        int idHash = Id == null
 887            ? 0
 888            : SwiftHashTools.GetDeterministicStringEqualityComparer().GetHashCode(Id);
 889        int hash = SwiftHashTools.CombineHashCodes(idHash, (int)Type);
 890        hash = SwiftHashTools.CombineHashCodes(hash, (int)SourceMedium);
 891        hash = SwiftHashTools.CombineHashCodes(hash, (int)DestinationMedium);
 892        hash = SwiftHashTools.CombineHashCodes(hash, (int)Scope);
 893        hash = SwiftHashTools.CombineHashCodes(hash, (int)RequiredCapabilities);
 894        hash = SwiftHashTools.CombineHashCodes(hash, ActionCost.GetHashCode());
 895        return SwiftHashTools.CombineHashCodes(hash, (int)LocomotionHints);
 96    }
 97
 98    internal void Validate()
 99    {
 172100        SwiftThrowHelper.ThrowIfArgument(
 172101            string.IsNullOrWhiteSpace(Id),
 172102            nameof(Id),
 172103            "Rule ID cannot be null, empty, or whitespace.");
 170104        SwiftThrowHelper.ThrowIfArgument(
 170105            !TraversalTransitionDefinition.IsKnownType(Type),
 170106            nameof(Type),
 170107            "Transition type is unknown.");
 169108        SwiftThrowHelper.ThrowIfArgument(
 169109            !TraversalTransitionDefinition.IsKnownMedium(SourceMedium),
 169110            nameof(SourceMedium),
 169111            "Source medium must identify one known traversal medium.");
 168112        SwiftThrowHelper.ThrowIfArgument(
 168113            !TraversalTransitionDefinition.IsKnownMedium(DestinationMedium),
 168114            nameof(DestinationMedium),
 168115            "Destination medium must identify one known traversal medium.");
 167116        SwiftThrowHelper.ThrowIfArgument(
 167117            Scope is < TraversalTransitionRuleScope.SameCell
 167118                or > TraversalTransitionRuleScope.PositiveFaceContact,
 167119            nameof(Scope),
 167120            "Rule scope is unknown.");
 165121        SwiftThrowHelper.ThrowIfArgument(
 165122            (RequiredCapabilities & ~NavigationCell.KnownCapabilities) != 0,
 165123            nameof(RequiredCapabilities),
 165124            "Required capabilities contain an unknown bit.");
 164125        SwiftThrowHelper.ThrowIfArgument(
 164126            ActionCost < Fixed64.Zero,
 164127            nameof(ActionCost),
 164128            "Action cost must be non-negative.");
 163129        SwiftThrowHelper.ThrowIfArgument(
 163130            (LocomotionHints & ~KnownLocomotionHints) != 0,
 163131            nameof(LocomotionHints),
 163132            "Locomotion hints contain an unknown bit.");
 162133    }
 134}
 135
 136/// <summary>Provides complete deterministic canonical ordering for transition rules.</summary>
 137internal sealed class TraversalTransitionRuleComparer : IComparer<TraversalTransitionRule>
 138{
 139    internal static readonly TraversalTransitionRuleComparer Instance = new();
 140
 141    public int Compare(TraversalTransitionRule left, TraversalTransitionRule right) =>
 142        string.CompareOrdinal(left.Id, right.Id);
 143}