< Summary

Information
Class: Trailblazer.Pathing.PathRequest
Assembly: Trailblazer
File(s): /home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Pathing/Search/Request/PathRequest.cs
Line coverage
97%
Covered lines: 78
Uncovered lines: 2
Coverable lines: 80
Total lines: 205
Line coverage: 97.5%
Branch coverage
66%
Covered branches: 41
Total branches: 62
Branch coverage: 66.1%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Context()50%22100%
set_Context(...)100%11100%
get_HasOrigin()100%11100%
get_HasDestination()100%11100%
get_HasValidEndpoints()100%22100%
get_IsValid()100%22100%
get_HasZeroDisplacement()100%22100%
get_RequestCacheKey()100%11100%
UpdateRequest(...)60%1010100%
TrySetOrigin(...)60%202095.65%
TrySetDestination(...)65%202095.65%
TrySetUnitSize(...)75%44100%

File(s)

/home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Pathing/Search/Request/PathRequest.cs

#LineLine coverage
 1using FixedMathSharp;
 2using GridForge.Grids;
 3using System;
 4
 5namespace Trailblazer.Pathing;
 6
 7/// <summary>
 8/// Represents an abstract base class for a pathfinding request, encapsulating the parameters and
 9/// state required to compute a path between two points in a voxel-based environment.
 10/// </summary>
 11/// <remarks>
 12/// PathRequest provides a common interface and shared logic for specifying origins, destinations, and
 13/// traversal options for pathfinding operations.
 14/// Derived classes should implement additional behavior as needed for specific pathfinding scenarios.
 15/// Thread safety is not guaranteed; synchronize access if used concurrently.
 16/// </remarks>
 17public abstract class PathRequest : IPathRequest
 18{
 19    private TrailblazerWorldContext? _context;
 20
 21    /// <inheritdoc/>
 22    public TrailblazerWorldContext Context
 23    {
 408124        get => _context ?? throw new InvalidOperationException("Path request is not bound to a TrailblazerWorldContext."
 108425        protected set => _context = value;
 26    }
 27
 28    /// <inheritdoc/>
 29    public Vector3d Origin { get; protected set; }
 30
 31    /// <inheritdoc/>
 32    public Voxel? StartNode { get; protected set; }
 33
 34    /// <inheritdoc/>
 35    public Vector3d TargetPosition { get; protected set; }
 36
 37    /// <inheritdoc/>
 38    public Voxel? EndNode { get; protected set; }
 39
 40    /// <inheritdoc/>
 41    public Fixed64 UnitSize { get; protected set; }
 42
 43    /// <inheritdoc/>
 44    public bool AllowUnwalkableEndpoints { get; set; }
 45
 46    /// <summary>
 47    /// Whether chart-backed requests may fall back through authored traversal transitions when direct chart routing fai
 48    /// </summary>
 49    public bool AllowTraversalTransitions { get; set; }
 50
 51    /// <inheritdoc/>
 52    public int MaxPathSearchRange { get; set; }
 53
 54    /// <inheritdoc/>
 298955    public bool HasOrigin => StartNode != null;
 56
 57    /// <inheritdoc/>
 298558    public bool HasDestination => EndNode != null;
 59
 60    /// <inheritdoc/>
 298961    public bool HasValidEndpoints => HasOrigin && HasDestination;
 62
 63    /// <inheritdoc/>
 277664    public bool IsValid => HasValidEndpoints && MaxPathSearchRange > 0;
 65
 66    /// <inheritdoc/>
 67    public bool HasZeroDisplacement =>
 159468        !IsValid
 159469        || StartNode == EndNode;
 70
 71    /// <inheritdoc/>
 566272    public int RequestCacheKey => GetHashCode();
 73
 74    /// <inheritdoc/>
 75    public bool UpdateRequest(
 76        Vector3d origin,
 77        Vector3d destination,
 78        Fixed64? unitSize = null)
 79    {
 880        TrailblazerWorldContext context = Context;
 881        Fixed64 resolvedUnitSize = unitSize ?? context.VoxelSize;
 882        bool success = SolidVoxelFinder.TryGetPathEdgeVoxels(
 883            context,
 884            origin,
 885            destination,
 886            out Voxel? startVoxel,
 887            out Voxel? endVoxel,
 888            resolvedUnitSize,
 889            AllowUnwalkableEndpoints);
 90
 91        // need to set these even if null incase the new size invalidates the request
 892        Origin = origin;
 893        TargetPosition = destination;
 894        StartNode = startVoxel;
 895        EndNode = endVoxel;
 896        UnitSize = resolvedUnitSize;
 897        MaxPathSearchRange = 0;
 98
 899        if (!success)
 3100            return false;
 101
 5102        if (StartNode != null
 5103            && EndNode != null
 5104            && context.Pathing.TryGetMaxSearchSize(StartNode, EndNode, out int searchSize))
 5105            MaxPathSearchRange = searchSize;
 106
 5107        return true;
 108    }
 109
 110    /// <inheritdoc/>
 111    public bool TrySetOrigin(Vector3d origin, bool resetSearchRange = false)
 112    {
 80113        if (EndNode == null) return false;
 114
 76115        bool success = SolidVoxelFinder.GetStartVoxel(
 76116            Context,
 76117            origin,
 76118            TargetPosition,
 76119            out Voxel? newVoxel,
 76120            AllowUnwalkableEndpoints,
 76121            UnitSize);
 122
 76123        if (!success || newVoxel == null) return false;
 124
 76125        Origin = origin;
 126
 76127        if (StartNode != null)
 128        {
 129            // nothing to do here then
 76130            if (newVoxel == StartNode)
 75131                return true;
 132
 133            // force reset if grid changed
 1134            if (newVoxel.GridIndex != StartNode.GridIndex)
 0135                resetSearchRange = true;
 136        }
 137
 1138        StartNode = newVoxel;
 139
 1140        if (resetSearchRange)
 141        {
 1142            MaxPathSearchRange = 0;
 1143            if (StartNode != null
 1144                && EndNode != null
 1145                && Context.Pathing.TryGetMaxSearchSize(StartNode, EndNode, out int searchSize))
 1146                MaxPathSearchRange = searchSize;
 147        }
 148
 1149        return true;
 150    }
 151
 152    /// <inheritdoc/>
 153    public bool TrySetDestination(Vector3d destination, bool resetSearchRange = false)
 154    {
 8155        if (StartNode == null) return false;
 156
 6157        bool success = SolidVoxelFinder.GetEndVoxel(
 6158            Context,
 6159            Origin,
 6160            destination,
 6161            out Voxel? newVoxel,
 6162            AllowUnwalkableEndpoints,
 6163            UnitSize);
 164
 6165        if (!success || newVoxel == null) return false;
 166
 6167        TargetPosition = destination;
 168
 6169        if (EndNode != null)
 170        {
 171            // nothing to do here then
 6172            if (newVoxel == EndNode)
 3173                return true;
 174
 175            // force reset if grid changed
 3176            if (newVoxel.GridIndex != EndNode.GridIndex)
 0177                resetSearchRange = true;
 178        }
 179
 3180        EndNode = newVoxel;
 181
 3182        if (resetSearchRange)
 183        {
 2184            MaxPathSearchRange = 0;
 2185            if (StartNode != null
 2186                && EndNode != null
 2187                && Context.Pathing.TryGetMaxSearchSize(StartNode, EndNode, out int searchSize))
 2188                MaxPathSearchRange = searchSize;
 189        }
 190
 3191        return true;
 192    }
 193
 194    /// <inheritdoc/>
 195    public bool TrySetUnitSize(Fixed64 unitSize)
 196    {
 197        // no change
 3198        if (UnitSize == unitSize || !HasValidEndpoints) return false;
 199
 1200        return UpdateRequest(Origin, TargetPosition, unitSize);
 201    }
 202
 203    /// <inheritdoc/>
 204    public override abstract int GetHashCode();
 205}