Game.Simulation.PoliceEmergencyDispatchSystem
Assembly: Assembly-CSharp (Game runtime)
Namespace: Game.Simulation
Type: class
Base: GameSystemBase
Summary:
System responsible for handling police emergency service requests (PoliceEmergencyRequest) in the simulation. It validates requests and sites, schedules pathfinding for either finding a vehicle to send to a site or finding the target for a reversed request, and finally dispatches vehicles by writing ServiceDispatch entries or scheduling ServiceRequest updates. The system uses Unity.Entities jobs (PoliceDispatchJob and DispatchVehiclesJob), the PathfindSetupSystem queue, and the area search quadtree to determine districts and dispatch sources. It runs on a 16-frame update interval and batches work using chunk jobs and an end-frame command buffer.
Fields
-
private EndFrameBarrier m_EndFrameBarrier
Used to obtain an EntityCommandBuffer (parallel writer) to perform structural changes (add/remove components, destroy entities) at end of frame from jobs. -
private SimulationSystem m_SimulationSystem
Reference to the main simulation system; used to read frameIndex to determine which requests to process this tick. -
private PathfindSetupSystem m_PathfindSetupSystem
Used to enqueue pathfinding setup requests (SetupQueueItem) produced by PoliceDispatchJob. -
private Game.Areas.SearchSystem m_AreaSearchSystem
Provides the area search quadtree (NativeQuadTree) used by PoliceDispatchJob to resolve districts when CurrentDistrict is not available. -
private EntityQuery m_RequestQuery
EntityQuery matching PoliceEmergencyRequest + UpdateFrame; used to schedule the dispatch job over relevant entities. -
private TypeHandle __TypeHandle
Internal container of Entity/Component type handles and component lookups used to set up job data. Populated in OnCreateForCompiler.
Properties
- None (this system exposes no public properties).
Constructors
public PoliceEmergencyDispatchSystem()
Default constructor. System initialization and runtime setup are handled in OnCreate/OnCreateForCompiler.
Methods
-
public override int GetUpdateInterval(SystemUpdatePhase phase)
Returns 16. The system is scheduled to run every 16 frames (uses frameIndex bits to split work across frames). -
[Preserve] protected override void OnCreate()
Initializes references to supporting systems (EndFrameBarrier, SimulationSystem, PathfindSetupSystem, Game.Areas.SearchSystem) and creates the EntityQuery for PoliceEmergencyRequest + UpdateFrame. Calls RequireForUpdate to ensure the system only updates when there are matching requests. -
[Preserve] protected override void OnUpdate()
Main scheduling method: - Computes which update-frame index to process for requests.
- Allocates a temporary NativeQueue
to collect vehicle dispatches from chunk jobs. - Prepares and schedules PoliceDispatchJob (IJobChunk) over m_RequestQuery, passing in type handles, component lookups, the area quadtree (from m_AreaSearchSystem), the EndFrameBarrier command buffer, pathfind queue writer, and the vehicle dispatch queue writer.
- Schedules DispatchVehiclesJob (IJob) to run after PoliceDispatchJob; this job dequeues VehicleDispatchs and either appends ServiceDispatch buffers to the source entity or sets SkipCooldown on ServiceRequest to immediately trigger handling.
- Registers writers/readers with PathfindSetupSystem and AreaSearchSystem and adds the producer job handle to m_EndFrameBarrier.
-
Sets base.Dependency to the dispatch job handle.
-
private void __AssignQueries(ref SystemState state)
Compiler-generated helper used during build for query assignment (no runtime logic besides creation/disposal of a temporary builder in this generated code). -
protected override void OnCreateForCompiler()
Compiler-time created method to assign queries and type handles (__TypeHandle.__AssignHandles).
Additional internal behavior (implemented inside nested job structs):
- PoliceDispatchJob (IJobChunk)
- Iterates over chunks of PoliceEmergencyRequest+UpdateFrame entities.
- Uses the shared UpdateFrame index to decide which subset of requests to process.
- For each request:
- Validates reversed requests (requests dispatched from vehicle to request) via ValidateReversed (checks PoliceStation/PoliceCar components, flags, ownership, request uniqueness).
- Validates normal requests via ValidateSite (checks AccidentSite component, flags and registers the request on the AccidentSite).
- If valid and ServiceRequest ticks indicate it's time, schedules pathfinding:
- FindVehicleSource: finds district for target (via CurrentDistrict or area quadtree), constructs PathfindParameters and SetupQueueTargets, and enqueues SetupQueueItem to PathfindSetupSystem with origin = police patrol (district) and destination = accident/request target. Adds PathInformation and PathElement buffer to the request entity.
- FindVehicleTarget: constructs SetupQueueItem to find target path from vehicle source to the request location, and adds PathInformation.
- When PathInformation is ready (on a subsequent frame), either:
- DispatchVehicle: resolve parked car ownership (use Owner if parked), enqueue VehicleDispatch (request -> source) and add Dispatched(source) on the request entity via command buffer.
- ResetReverseRequest or ResetFailedRequest: on failures, reset ServiceRequest status, remove PathInformation/PathElement and possibly Dispatched components; if reversed and path found, enqueue VehicleDispatch.
-
Uses ComponentLookup and BufferLookup for accident sites, police stations, police cars, parked cars, owner, transforms, district data, nodes/triangles (for quadtree triangle tests), and service dispatch buffers.
-
DispatchVehiclesJob (IJob)
- Dequeues VehicleDispatch entries produced by PoliceDispatchJob.
- For each VehicleDispatch:
- If the source entity has a ServiceDispatch buffer, appends a new ServiceDispatch(request).
- Else, if source is a ServiceRequest, sets ServiceRequestFlags.SkipCooldown so that source will be considered immediately for dispatch.
Notes on internal helper methods within jobs: - ValidateReversed(Entity request, Entity source): ensures source is a valid police station or police car that can respond and marks component m_TargetRequest. - ValidateHandler(Entity request, Entity handler): checks if a handler actually has a ServiceDispatch entry for the given request. - ValidateSite(Entity request, Entity site): checks that an AccidentSite requires police and registers the m_PoliceRequest on it. - ResetReverseRequest / ResetFailedRequest: undo pathing state and reset ServiceRequest state using SimulationUtils helpers. - DispatchVehicle enqueues a VehicleDispatch and adds Dispatched component to the request entity.
Concurrency/Job notes: - The system uses NativeQuadTree read-only iteration, NativeQueue parallel writers, and an EndFrameBarrier EntityCommandBuffer parallel writer to safely perform structural changes from jobs. - The PathfindSetupSystem queue writer is added as a writer and the AreaSearchSystem quadtree reader is registered to ensure correct job dependencies.
Usage Example
// Example: create a police emergency request entity to be handled by PoliceEmergencyDispatchSystem.
// This would typically be done where an accident/site is detected.
Entity request = entityManager.CreateEntity(
typeof(PoliceEmergencyRequest),
typeof(ServiceRequest),
typeof(UpdateFrame)
);
// Fill PoliceEmergencyRequest: set m_Site (accident site entity), m_Target (entity location), m_Purpose (PolicePurpose)
entityManager.SetComponentData(request, new PoliceEmergencyRequest {
m_Site = accidentSiteEntity, // Entity of the AccidentSite (or Entity.Null if none)
m_Target = victimOrLocationEntity, // Entity representing the location/target
m_Purpose = PolicePurpose.Emergency
});
// Initialize ServiceRequest state (flags/cooldown)
entityManager.SetComponentData(request, new ServiceRequest {
m_Flags = 0,
m_Cooldown = 0
});
// Add UpdateFrame indicating this request participates in the system's update rotation.
// The system will pick up and process this entity within its scheduled frames.
entityManager.SetSharedComponentData(request, new UpdateFrame { m_Index = /* 0..3 */ 0 });
Additional notes: - The system is primarily internal to the simulation; modders usually interact with it by creating PoliceEmergencyRequest / ServiceRequest entities tied to AccidentSite or other in-world entities, or by manipulating PoliceStation / PoliceCar / AccidentSite components to influence dispatch decisions. - Be cautious when creating or destroying entities/components referenced here — use the same ECS patterns (command buffers, appropriate framings) to avoid race conditions with scheduled jobs.