Skip to content

Game.Pathfind.CoverageJobs

Assembly:
Game (pathfinding module)

Namespace:
Game.Pathfind

Type:
static class

Base:
System.Object

Summary:
CoverageJobs contains nested types and Burst-compiled Unity Jobs used to compute "coverage" (reachability/cost) across the pathfinding graph. It provides a CoverageExecutor (internal algorithm) to run Dijkstra-like expansion from multiple source edges, a CoverageJob (IJob) that wraps the executor for single-run execution, and a ProcessResultsJob (IJobParallelFor) that aggregates and writes coverage results into game entity buffers. This is used by the game's systems to determine what targets (edges/owners) are reachable from given sources within parameterized ranges and cost constraints.


Fields

  • private UnsafePathfindData m_PathfindData
    Used by CoverageExecutor to hold a read-only view of the native pathfinding data (edges, nodes, connections). This references the low-level path graph the executor queries.

  • private CoverageParameters m_Parameters
    CoverageExecutor field that stores parameters (range, methods, etc.) controlling cost calculation and allowed traversal.

  • private float4 m_MinDistance
    Precomputed component-wise minimum distance thresholds used to normalize costs into a target cost metric.

  • private float4 m_MaxDistance
    Precomputed component-wise maximum distance thresholds used to normalize costs into a target cost metric.

  • private UnsafeList<int> m_NodeIndex
    Sparse index mapping used to quickly find node entries in the executor's node list.

  • private UnsafeList<int> m_NodeIndexBits
    Bitset blocks for fast existence checking of indices in m_NodeIndex.

  • private UnsafeMinHeap<HeapData> m_Heap
    Min-heap used to drive the Dijkstra-like expansion by always extracting the lowest-cost frontier node.

  • private UnsafeList<NodeData> m_NodeData
    Storage for discovered nodes (their costs, associated edge IDs, processed flags, link to next collision node, etc.) during coverage expansion.

(Notes: the above fields are members of the nested CoverageExecutor structure. Additional small fields exist in nested helper structs such as NodeData/HeapData/FullNode.)

Properties

  • (No public properties on CoverageJobs itself)
    CoverageJobs is a static container of nested types and jobs; nested job types expose public fields rather than properties.

Constructors

  • (None — CoverageJobs is a static class)
    The nested types have constructors (e.g., NodeData, HeapData, FullNode) and the CoverageExecutor uses Initialize(...) to set up its state rather than a conventional constructor.

Methods

  • CoverageExecutor.Initialize(NativePathfindData pathfindData, Allocator allocator, CoverageParameters parameters)
    Initializes internal data structures (lists, heap, bitsets) and precomputes distance thresholds. Must be called before using the executor.

  • CoverageExecutor.Release()
    Disposes all created Native/Unsafe allocations used by the executor. Always call to avoid native memory leaks.

  • CoverageExecutor.AddSources(ref UnsafeQueue<PathTarget> pathTargets)
    Dequeues source PathTargets and seeds the search frontier by converting path edge entities into initial heap entries based on their edge specifications and source deltas.

  • CoverageExecutor.FindCoveredNodes() : bool
    Runs the main expansion loop: repeatedly extracts the next node from the heap, marks it processed, and if under max distance explores outgoing connections / next edges. Returns true if any node was processed (i.e., coverage exists).

  • CoverageExecutor.CheckNextEdge(EdgeID nextID, FullNode pathNode, float2 baseCosts, in Edge edge)
    Given an edge and an entry point on that edge (start / end / middle), determines valid traversal directions and delegates to AddConnections.

  • CoverageExecutor.AddConnections(EdgeID id, in Edge edge, float2 baseCosts, float startDelta, bool3 directions)
    Adds frontier entries for the allowed directions of traversal across an edge (forward, middle, backward) honoring access requirements and middle-node connection rules.

  • CoverageExecutor.GetOrAddNodeIndex(FullNode pathNode, out int nodeIndex) : bool
    Finds or inserts a node entry for the provided FullNode. Returns true if node already existed (and nodeIndex is set to it), otherwise sets nodeIndex to the newly reserved index for the caller to fill.

  • CoverageExecutor.TryGetNodeIndex(FullNode pathNode, out int nodeIndex) : bool
    Like GetOrAddNodeIndex but does not add; returns whether a node index exists.

  • CoverageExecutor.AddHeapData(EdgeID id, in Edge edge, float2 baseCosts, FullNode pathNode, float2 edgeDelta)
    Compute cost+distance for traversing a portion of an edge and insert/update the node entry and heap as needed. (Overload also exists that takes an additional EdgeID id2 to track "next" edge.)

  • CoverageExecutor.DisallowConnection(PathSpecification newSpec) : bool
    Checks whether a connection should be disallowed based on the new edge's PathSpecification and the executor's CoverageParameters (methods mismatch).

  • CoverageExecutor.FillResults(ref UnsafeList<CoverageResult> results)
    After expansion, inspects processed node pairs across edges to produce CoverageResult entries (target entity + normalized target cost) which are appended to the provided results list.

  • CoverageJob.Execute()
    IJob entry point which invokes the static Execute(...) passing the stored NativePathfindData and the job's action data. This wraps the single-run use-case of the executor.

  • CoverageJob.Execute(NativePathfindData pathfindData, Allocator allocator, ref CoverageActionData actionData) (static)
    Static helper that runs a full coverage query: initializes a CoverageExecutor, seeds sources from actionData, runs expansion, fills actionData results, and releases resources. Uses Allocator.Temp by default when called from the job.

  • ProcessResultsJob.Execute(int index)
    IJobParallelFor implementation that takes a ResultItem (owner + results list) and aggregates per-owner coverage: it maps covered edge targets to their Owner entities, selects minimum costs per owner, and writes a DynamicBuffer on the owner entity with final per-edge costs.

  • ProcessResultsJob.GetCost(float2 cost, float2 edgeDelta) : float2 (private static)
    Utility that applies special handling for edge-delta flags to choose between cost components or mark unreachable using float.MaxValue; used when mapping coverage results to final cost values for storage.

  • FullNode.Equals(FullNode other) : bool and FullNode.GetHashCode() : int
    Simple value equality/hash implementation for FullNode which pairs a NodeID and curve position. Used by the executor indexing.

  • NodeData / HeapData constructors and comparison methods
    NodeData holds discovered node fields (path node, costs, processed flag, access requirement, linked indices). HeapData implements ILessThan and IComparable for heap ordering.

(Notes: many helper methods are marked AggressiveInlining and the main heavy lifting is implemented inside CoverageExecutor and the two jobs.)

Usage Example

// Example: run a coverage query synchronously (conceptual)
// Prepare a CoverageActionData (m_Sources, m_Parameters, results list) elsewhere...

CoverageJobs.CoverageJob job = new CoverageJobs.CoverageJob
{
    m_PathfindData = nativePathfindData, // provided by path system
    m_Action = coverageAction // CoverageAction wrapping CoverageActionData
};
job.Execute(); // runs the coverage algorithm and fills action data results

// After the coverage job produced results, collect them into ResultItem(s)
// and schedule ProcessResultsJob (IJobParallelFor) to aggregate them into entity buffers.

(Notes / Tips) - CoverageExecutor uses Unsafe* containers and must be explicitly Release()d to avoid native leaks; using the provided CoverageJob wrapper manages that for a single-run execution. - The algorithm is essentially a multi-source Dijkstra expansion with edge-specific partial traversal (curve positions) and access requirements. CoverageParameters control what methods are allowed and the normalization range for the final "target cost". - ProcessResultsJob expects certain components/buffers to exist (Owner, EdgeLane, CoverageElement) and will skip entities missing them. Ensure those components are present on entities you expect to receive coverage data.