Skip to content

Game.Pathfind.PathfindQueueSystem

Assembly: Assembly-CSharp
Namespace: Game.Pathfind

Type: class

Base: GameSystemBase, IPreDeserialize

Summary:
PathfindQueueSystem orchestrates pathfinding and related operations (coverage, availability, density, time, flow) for the simulation. It collects requests (create/update/delete edges, pathfind queries, coverage/availability queries and several modification jobs), batches and schedules them as Unity Jobs across worker threads and per-worker path graph data (NativePathfindData). The system maintains multiple worker data containers, per-thread allocators for query work, and action queues with support for high-priority actions and modification actions. It also exposes APIs to enqueue actions, obtain data containers, and query memory usage. Nested helper types implement action lists, worker action buffers and the actual PathfindWorkerJob that executes queries in parallel.


Fields

  • private const int WORKER_DATA_COUNT
    Holds the constant value 2 — the number of WorkerData instances allocated by default.

  • private PathfindSetupSystem m_PathfindSetupSystem
    Reference to the PathfindSetupSystem used to ensure graph setup is completed before scheduling work.

  • private TransportLineSystem m_TransportLineSystem
    Reference used to query max transport speeds for pathfinding heuristics.

  • private NetInitializeSystem m_NetInitializeSystem
    Provides heuristic data and initialization information for the pathfinding subsystem.

  • private ActionList<CreateAction> m_CreateActions
    Container for create-edge actions.

  • private ActionList<UpdateAction> m_UpdateActions
    Container for update-edge actions.

  • private ActionList<DeleteAction> m_DeleteActions
    Container for delete-edge actions.

  • private ActionList<PathfindAction> m_PathfindActions
    Container for pathfinding queries.

  • private ActionList<CoverageAction> m_CoverageActions
    Container for coverage queries.

  • private ActionList<AvailabilityAction> m_AvailabilityActions
    Container for availability queries.

  • private ActionList<DensityAction> m_DensityActions
    Container for density modification actions.

  • private ActionList<TimeAction> m_TimeActions
    Container for time modification actions.

  • private ActionList<FlowAction> m_FlowActions
    Container for flow modification actions.

  • private Queue<ActionType> m_ActionTypes
    Queue of action types representing normal (non-modification, non-high-priority) actions to process.

  • private Queue<ActionType> m_HighPriorityTypes
    Queue of high-priority action types — those that should be scheduled before others.

  • private Queue<ActionType> m_ModificationTypes
    Queue of modification-type actions (graph changes, density/time/flow) that must be applied to path graph data.

  • private Queue<WorkerActions> m_WorkerActions
    Queue of WorkerActions currently pending scheduling to worker threads.

  • private Queue<WorkerActions> m_WorkerActionPool
    Pool of WorkerActions objects reused to avoid allocations.

  • private List<WorkerData> m_WorkerData
    List of per-worker WorkerData instances; each holds a NativePathfindData and per-worker read/write job handles.

  • private List<ThreadData> m_ThreadData
    List of per-thread ThreadData (job handle + allocator helper) currently in use for executing PathfindWorkerJob instances.

  • private List<AllocatorHelper<UnsafeLinearAllocator>> m_AllocatorPool
    Pool of allocators usable by worker threads for query allocations.

  • private int m_MaxThreadCount
    Maximum number of worker threads to spawn for a single batch; derived from available job workers.

  • private int m_NextWorkerIndex
    Index of the next WorkerData to be used when obtaining graph data for new work.

  • private int m_LastWorkerIndex
    Index of last worker used; used to advance m_NextWorkerIndex in round-robin fashion.

  • private int m_DependencyIndex
    Index used to track dependency rotation for thread data reuse.

  • private bool m_RequireDebug
    Flag that forces scheduling only actions that marked debug (used in OnUpdate to gate debug actions).

Nested / helper types (brief):

  • public struct ActionListItem<T>
    Represents a queued action item including action data, owner entity, dependencies, flags, result frame and optional event data/system. Implements IDisposable to ensure dependencies complete and the action disposed.

  • public class ActionList<T>
    Holds a List of ActionListItem, a next index, and a priority count. Provides Clear and Dispose.

  • private class WorkerData
    Per-worker container that has a NativePathfindData, and write/read JobHandles. Provides Clear and Dispose semantics.

  • private class WorkerActions
    Holds a NativeList (action descriptors) and a NativeReference action index used by worker jobs; supports Add(ref T) to append typed action data pointers.

  • private struct ThreadData
    Container with JobHandle and AllocatorHelper for thread-local allocation and job tracking.

  • public struct WorkerAction
    Small struct used inside WorkerActions array: ActionType and an unsafe pointer to action data.

  • public enum ActionType
    Types enumerating supported actions (Create, Update, Delete, Pathfind, Coverage, Availability, Density, Time, Flow).

  • public struct PathfindWorkerJob : IJob
    The actual Burst-compiled worker job that executes PathfindJobs, CoverageJobs or AvailabilityJobs on action data pulled from the WorkerActions buffer.


Properties

  • None (this type exposes methods rather than instance properties).
    You can access per-action lists via GetCreateActions/GetPathfindActions/etc methods.

Constructors

  • public PathfindQueueSystem()
    Default constructor. The system uses the OnCreate override to perform full initialization; constructor contains no custom logic aside from standard CLR instantiation.

Methods

  • protected override void OnCreate()
    Initializes references to other systems, creates action lists, queues and pools, allocates the initial WorkerData instances (2 by default) and sets m_MaxThreadCount based on JobsUtility.JobWorkerCount. Called by the ECS world when the system is created.

  • protected override void OnDestroy()
    Cleans up thread data (completing jobs and disposing allocators), disposes allocator pool and all action lists, drains and disposes worker action queues/pool and WorkerData instances, then calls base.OnDestroy.

  • public void PreDeserialize(Context context)
    Called before deserialization: completes thread jobs, moves allocators back to the pool, clears pending action lists and queues, resets dependency index and clears worker data read/write handles.

  • public NativePathfindData GetDataContainer(out JobHandle dependencies)
    Returns the NativePathfindData for the current m_NextWorkerIndex and outputs the write JobHandle that represents outstanding write dependencies so callers can chain reads/writes. This is used by clients to access the path graph for reading/writing safely.

  • public void AddDataReader(JobHandle handle)
    Adds a read JobHandle dependency to the current worker's read handle, used to ensure the worker's ReadHandle accounts for additional readers.

  • public void RequireDebug()
    Marks the system to require debug flags when scheduling; used in OnUpdate to decide whether to schedule debug-marked pathfind actions.

  • public int GetGraphSize()
    Returns the size (node/edge capacity) of the current worker's NativePathfindData graph.

  • public void GetGraphMemory(out uint usedMemory, out uint allocatedMemory)
    Populates used/allocated memory usage summing all WorkerData NativePathfindData memory stats.

  • public void GetQueryMemory(out uint usedMemory, out uint allocatedMemory)
    Reports allocator memory usage for all thread-local allocators currently in use and stored in the allocator pool.

Enqueue API (several overloads):

  • public void Enqueue(CreateAction action, JobHandle dependencies)
  • public void Enqueue(UpdateAction action, JobHandle dependencies)
  • public void Enqueue(DeleteAction action, JobHandle dependencies)
  • public void Enqueue(PathfindAction action, Entity owner, JobHandle dependencies, uint resultFrame, object system, bool highPriority = false)
  • public void Enqueue(PathfindAction action, Entity owner, JobHandle dependencies, uint resultFrame, object system, PathEventData eventData, bool highPriority = false)
  • public void Enqueue(CoverageAction action, Entity owner, JobHandle dependencies, uint resultFrame, object system, bool highPriority = false)
  • public void Enqueue(CoverageAction action, Entity owner, JobHandle dependencies, uint resultFrame, object system, PathEventData eventData, bool highPriority = false)
  • public void Enqueue(AvailabilityAction action, Entity owner, JobHandle dependencies, uint resultFrame, object system)
  • public void Enqueue(DensityAction action, JobHandle dependencies)
  • public void Enqueue(TimeAction action, JobHandle dependencies)
  • public void Enqueue(FlowAction action, JobHandle dependencies)

These overloads place typed actions into their corresponding ActionList. Each enqueued ActionListItem includes the action struct (by value), owner Entity (if applicable), dependency JobHandle, flags (initially Pending or Pending|WantsEvent), target result frame and optional PathEventData/system. High-priority or modification flags determine which internal queue the ActionType is pushed onto so scheduling order respects priority and modification constraints.

  • public ActionList<CreateAction> GetCreateActions() (and similar getters for other action lists)
    Return references to the internal ActionList instances for inspection by other systems.

Private scheduling helpers:

  • private void Enqueue<T>(T action, Entity owner, JobHandle dependencies, uint resultFrame, ActionList<T> list, ActionType type, object system, bool highPriority, bool modification) where T : struct, IDisposable
    Internal shared implementation handling normal and modification enqueues (no event data).

  • private void Enqueue<T>(T action, Entity owner, JobHandle dependencies, uint resultFrame, ActionList<T> list, ActionType type, object system, bool highPriority, PathEventData eventData) where T : struct, IDisposable
    Internal shared implementation handling enqueues with PathEventData (WantsEvent flag set).

  • private JobHandle ScheduleModificationJob<T>(T job) where T : struct, IJob, ModificationJobs.IPathfindModificationJob
    Schedules a modification job (graph changes, density/time/flow) on all WorkerData instances. For each worker it sets the job's pathfind data, schedules the job combining existing write/read handles and updates the worker's write and read handles accordingly. Advances m_NextWorkerIndex in round-robin if needed. Returns a combined JobHandle representing the scheduled jobs across all workers.

  • private void ScheduleWorkerJobs(ref WorkerActions currentActions)
    Given a WorkerActions buffer (which contains a list of WorkerAction descriptors and a NativeReference index), schedules PathfindWorkerJob instances across available thread slots. It computes the number of worker jobs (min(actions.Length, maxThreadCount or high priority count)), obtains/allocates thread allocators (either from pool or creates new), sets job data (random seed, pathfind data, heuristic data, transport speeds, allocator), and schedules jobs while combining dependencies appropriately. It also updates per-thread m_JobHandle and currentActions.m_ReadHandle and assigns thread data into m_ThreadData list.

  • private void RequireWorkerActions(ref WorkerActions currentActions)
    Ensures a WorkerActions instance is available (either dequeue from pool or create new) and enqueues it in m_WorkerActions. Called when starting to collect query actions to execute as a batch.

  • protected override void OnUpdate()
    Main scheduling loop invoked each frame. Steps:

  • Completes and reclaims finished thread allocators, compacts m_ThreadData and manages m_DependencyIndex.
  • Completes pending worker data read/write handles if finished.
  • Reclaims WorkerActions whose read handles are completed (clears and returns to pool).
  • Ensures PathfindSetupSystem.CompleteSetup() is called before scheduling actions.
  • Iteratively picks next action type to schedule (prefers high-priority, then modification, then normal) and handles each action type:
    • For modification actions (Create/Update/Delete/Density/Time/Flow) it completes dependencies, schedules worker jobs to flush any in-progress queries, schedules the corresponding modification job across worker data, and updates flags.
    • For query actions (Pathfind/Coverage/Availability) it completes dependencies, ensures a WorkerActions buffer is available, appends action data pointer to current WorkerActions and marks the action scheduled. High-priority query entries decrement the corresponding priority counters.
  • The loop returns early if an action's dependency isn't yet complete, ensuring consistent ordering and correctness.
  • Finally ensures any remaining collected currentActions are scheduled via ScheduleWorkerJobs in the finally block.

  • (Nested) public struct PathfindWorkerJob : IJob
    Burst-compiled job executing a loop where multiple WorkerAction entries are consumed via atomic increment of the NativeReference index. For each entry it dispatches to the appropriate static Execute method (PathfindJobs.PathfindJob.Execute, CoverageJobs.CoverageJob.Execute, AvailabilityJobs.AvailabilityJob.Execute) using the worker's NativePathfindData and a per-job allocator. After executing each action, it sets actionData.m_State to Completed using an interlocked memory barrier. It rewinds the linear allocator between actions and at the end. This is the core work performed on worker threads.


Usage Example

// Example: enqueueing a pathfind request from another system.
// Assume `pathfindQueue` is a reference to the PathfindQueueSystem,
// and `myAction` is a PathfindAction properly populated.
// `dependencies` is a JobHandle representing any job that must complete
// before the pathfind action can be scheduled (commonly default).

PathfindAction myAction = new PathfindAction {
    // populate fields (start, end, options, output buffers, etc.)
};

JobHandle dependencies = default; // or combine with other job handles if needed
uint resultFrame = (uint)SimulationManager.instance.m_currentFrame; // or desired frame index
Entity owner = Entity.Null; // or an entity representing requester
object ownerSystem = this; // optionally pass the system requesting the pathfind

// Enqueue the pathfind (not high priority)
pathfindQueue.Enqueue(myAction, owner, dependencies, resultFrame, ownerSystem, highPriority: false);

// If you need immediate access to the worker graph for custom reads:
JobHandle graphDeps;
NativePathfindData data = pathfindQueue.GetDataContainer(out graphDeps);
// Use graphDeps to chain your read job against the path graph

Notes and tips: - PathfindQueueSystem uses a pool of per-thread UnsafeLinearAllocator instances for query allocations; GetQueryMemory and GetGraphMemory help track memory usage. - Modification actions (create/update/delete edges, set density/time/flow) are scheduled across all worker graphs and must flush outstanding query jobs first — the system schedules them as ModificationJobs using ScheduleModificationJob internally. - Pathfind and coverage/availability queries are batched into WorkerActions and executed by PathfindWorkerJob on available worker threads. High-priority queries are scheduled earlier and may cause more worker threads to be used. - Always ensure dependent JobHandles are passed when enqueuing actions that rely on other jobs to complete.