Game.EndFrameBarrier
Assembly:
Assembly-CSharp
Namespace:
Game.Pathfind
Type:
static class (AvailabilityJobs)
Base:
Summary:
This file implements AvailabilityJobs — a set of jobs and helper types used to calculate "availability" of service providers along path edges for pathfinding in Cities: Skylines 2. The algorithm performs a multi-source search from provider targets, combines provider capacities and costs, propagates availability along edges (using path cost calculations), and emits AvailabilityResult items that are then reduced into AvailabilityElement buffers on owner entities. Main entry points are AvailabilityJob (IJob) which runs the availability graph search and ProcessResultsJob (IJobParallelFor) which aggregates results into ECS buffers. The implementation is optimized for Burst, uses Unsafe collections and a custom min-heap to prioritize nodes by availability, and merges providers when their search frontiers meet.
Fields
private System.Diagnostics.Stopwatch m_Stopwatch
This field is not present in AvailabilityJobs.cs. Instead, the file contains several internal/private structures and fields inside the AvailabilityExecutor that manage state for the search. Important state items include:- m_PathfindData: read-only UnsafePathfindData used to access nodes/edges/connections.
- m_Allocator: Allocator used for allocating temporary unsafe containers.
- m_Parameters: AvailabilityParameters used for cost/normalization factors.
- m_ProviderTargets: UnsafeParallelMultiHashMap
mapping providers to PathTarget entries. - m_Providers: UnsafeList
storing per-provider capacity and adjusted cost. - m_ProviderIndex: UnsafeList
disjoint-set-like index mapping to merge provider indices. - m_NodeIndex / m_NodeIndexBits: UnsafeList
bit-indexed table for deduplicating FullNode entries. - m_Heap: UnsafeMinHeap
priority heap for processing candidate nodes by availability. -
m_NodeData: UnsafeList
list storing discovered nodes, their best availability, link to next chain item, processed flag, and chosen next edge. -
private Unity.Jobs.JobHandle <producerHandle>k__BackingField
This property/backing-field is not present in this file. The file exposes two Jobs instead: - AvailabilityJob : IJob — schedules the graph search operation (Burst-compiled).
- ProcessResultsJob : IJobParallelFor — aggregates the produced AvailabilityResult lists into ECS buffers.
Properties
public Unity.Jobs.JobHandle producerHandle { get; private set }
This specific property is not part of AvailabilityJobs. Relevant public/internal data are the job structs and their public fields:- AvailabilityJob.m_PathfindData (ReadOnly NativePathfindData) and m_Action (AvailabilityAction) — the job reads path data and an action payload containing sources, providers and parameters.
- ProcessResultsJob members: m_ResultItems (NativeList
), m_OwnerData and m_EdgeLaneData (ComponentLookup<>), and m_AvailabilityElements (BufferLookup ) used to write aggregated results.
Constructors
public EndFrameBarrier()
There is no EndFrameBarrier constructor in this file. AvailabilityJobs is a static container type; key structs (AvailabilityExecutor, ProviderItem, NodeData, etc.) are value types with default constructors, and jobs are plain value types as well. The AvailabilityExecutor has an Initialize method used to set up internal containers rather than a public constructor.
Methods
-
protected virtual OnCreate() : System.Void
There is no OnCreate in this file. Instead, main methods and important internal routines include: -
AvailabilityJob.Execute() : void
- Burst compiled. Entry point invoked by the job system. Calls static Execute(pathfindData, Allocator.Temp, ref actionData).
- Behavior: if actionData contains providers, it constructs an AvailabilityExecutor, initializes it, adds sources and providers, runs the availability search, fills results, and releases temporary resources.
-
AvailabilityJob.Execute(NativePathfindData pathfindData, Allocator allocator, ref AvailabilityActionData actionData) : static void
- Core orchestration static routine used by the job. Performs the full flow for one AvailabilityActionData.
-
AvailabilityExecutor.Initialize(NativePathfindData pathfindData, Allocator allocator, AvailabilityParameters parameters) : void
- Allocates and initializes all internal unsafe lists, bitmaps and heap. Computes sizing based on node/edge counts and prepares containers for the search.
-
AvailabilityExecutor.Release() : void
- Disposes all created Unsafe containers (lists, heap, maps). Ensures no leak of native allocations.
-
AvailabilityExecutor.AddSources(ref UnsafeQueue
pathTargets) : void - Moves PathTarget items out of the provided queue into an internal UnsafeParallelMultiHashMap keyed by provider Entity for quick lookup when adding provider influence.
-
AvailabilityExecutor.AddProviders(ref UnsafeQueue
availabilityProviders) : void - Pulls providers from the queue, creates ProviderItem entries (capacity, scaled cost), and iterates PathTargets for each provider to add initial connections into the node heap while accumulating a per-provider initial cost adjustment.
-
AvailabilityExecutor.FindAvailabilityNodes() : bool
- Main processing loop: repeatedly extracts the highest-availability candidate from the heap, marks node as processed, inspects adjacent edges/connections (or the next edge if present), enqueues new candidate nodes, merges providers when different provider frontiers meet, and increments provider costs by traversed segments. Returns true if any nodes were added (i.e., results exist).
-
AvailabilityExecutor.FillResults(ref UnsafeList
results) : void - After processing, iterates processed NodeData entries and creates AvailabilityResult entries for edges where both directions have been reached (i.e., forms a usable connection), normalizing availability using AvailabilityParameters.m_ResultFactor.
-
AvailabilityExecutor.AddHeapData(...) overloads : void
- Helpers to get-or-create a NodeData entry for a FullNode, possibly merge providers, update best availability for that node, and insert HeapData to the heap.
-
AvailabilityExecutor.MergeProviders(int providerIndex1, int providerIndex2) : void
- Merges two provider entries when their search fronts meet by combining capacities and costs and updating provider index mapping.
-
AvailabilityExecutor.GetAvailability(ProviderItem providerItem, float cost) : float
- Computes availability value = capacity / (1 + cost + providerCost), used as heap priority (higher availability is better).
-
AvailabilityExecutor.GetOrAddNodeIndex / TryGetNodeIndex : bool
- Internal deduplication / hash-bucketing to map FullNode values to NodeData indices using m_NodeIndex and m_NodeIndexBits arrays.
-
ProcessResultsJob.Execute(int index) : void
- For each ResultItem:
- Ensures owner has an AvailabilityElement buffer.
- Merges multiple AvailabilityResult entries by owner (Entity) taking component-specific availability adjusted by edge lane deltas.
- Writes aggregated AvailabilityElement entries into the owner entity's dynamic buffer.
- Uses a temporary NativeParallelHashMap
to reduce results per owner.
-
ProcessResultsJob.GetAvailability(float2 availability, float2 edgeDelta) : float2 (private static)
- Helper logic to select availability based on edge lane delta flags and availability component ordering; used when reducing results to owners.
Notes on algorithmic behavior: - The search is not a straightforward Dijkstra on distances; it uses a custom "availability" metric combining provider capacity, provider cost (scaled by parameters), and path cost segments computed by PathUtils.CalculateCost. Availability is higher for more capacity and lower cumulative cost. - When multiple providers meet at a node, their capacities and costs are merged to represent a combined provider supply. - The code avoids allocations in the job-run path by using unsafe collections and a supplied Allocator for temporary work memory.
Usage Example
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
m_Stopwatch = new Stopwatch();
}
{{ YOUR_INFO }}
- How to schedule the availability search in a typical system:
- Prepare an AvailabilityActionData instance containing:
- m_Sources: queue of PathTarget entries (entity + delta info).
- m_Providers: queue of AvailabilityProvider items (provider Entity, capacity, cost).
- m_Parameters: AvailabilityParameters controlling cost factor and result normalization.
- m_Results: an UnsafeList