Game.NetEdgeDensitySystem
Assembly: Game
Namespace: Game.Simulation
Type: class NetEdgeDensitySystem
Base: GameSystemBase
Summary:
NetEdgeDensitySystem computes and updates the pedestrian/people density associated with network edges (roads) by aggregating occupants and workers from buildings connected to each edge. It runs a Burst-compiled IJobChunk (CalculateDensityJob) in parallel to:
- read ConnectedBuilding buffers to find buildings linked to an edge,
- sum household citizens and workplace capacities (Renter / HouseholdCitizen / WorkProvider),
- normalize the sum by the edge curve length to produce a density value,
- update the Density component on the edge,
- compute a derived density value (sqrt(max(0.01, density))) and enqueue DensityActionData for sub-lanes that have CarLane components so downstream systems (PathfindQueueSystem) can react (e.g., adapt pathfinding or costs).
The system runs infrequently (GetUpdateInterval returns 1024) and enqueues results into the PathfindQueueSystem via a DensityAction instance scheduled from the job output.
Fields
-
private EntityQuery m_EdgeQuery
Holds the query used to select edge entities to process. The query includes: Game.Net.Edge (read-only), ConnectedBuilding (read-only buffer), Density (read/write), Curve (read-only) and excludes Temp and Deleted. The query is created in OnCreate and required for system updates. -
private PathfindQueueSystem m_PathfindQueueSystem
Reference to the PathfindQueueSystem obtained from the World in OnCreate. Used to enqueue the DensityAction produced by this system's job so downstream pathfinding/queue logic can consume density updates. -
private TypeHandle __TypeHandle
Compiler-generated struct that stores EntityTypeHandle, BufferTypeHandle, ComponentTypeHandle and Buffer/Component lookups used by the CalculateDensityJob. Assigned via __AssignHandles in OnCreateForCompiler / __TypeHandle.__AssignHandles.
Properties
- None
This system does not expose public properties.
Constructors
public NetEdgeDensitySystem()
Default parameterless constructor (marked [Preserve] on the class members where needed). Standard Unity ECS system construction; initialization of query and system references occurs in OnCreate.
Methods
-
public override int GetUpdateInterval(SystemUpdatePhase phase)
Returns 1024. This controls how often (in ticks / frames) the system is considered for updates. The large interval indicates this system runs relatively rarely to amortize cost. -
[Preserve] protected override void OnCreate()
Initializes the system: - Gets or creates PathfindQueueSystem from the World and stores in m_PathfindQueueSystem.
- Creates m_EdgeQuery selecting Edge entities with ConnectedBuilding, Density, Curve and excluding Temp/Deleted.
-
Calls RequireForUpdate(m_EdgeQuery) so the system runs only when there are matching entities.
-
[Preserve] protected override void OnUpdate()
Creates a DensityAction (allocating its internal queue with Allocator.Persistent), constructs a CalculateDensityJob, populates job data using InternalCompilerInterface to obtain type handles / lookups from __TypeHandle and the system state, schedules the job in parallel with JobChunkExtensions.ScheduleParallel, and then enqueues the resulting DensityAction into the PathfindQueueSystem with the returned job dependency. -
private void __AssignQueries(ref SystemState state)
Compiler helper used to assign queries; present for compiler/codegen compatibility. In this file it creates an EntityQueryBuilder and disposes it (placeholder) — real query assignment is done in OnCreate. -
protected override void OnCreateForCompiler()
Compiler-time initialization: calls __AssignQueries and __TypeHandle.__AssignHandles to set up handles/queries for the job and system. -
[BurstCompile] private struct CalculateDensityJob : IJobChunk
Burst-compiled job that executes per-chunk and performs the main density calculation: - Inputs/ReadOnly:
- EntityTypeHandle (entity identities)
- BufferTypeHandle
(list of buildings connected to each edge) - BufferTypeHandle
(sub-lanes for the edge) - ComponentTypeHandle
(edge length) - ComponentLookup
(workplaces / workplace capacity) - ComponentLookup
(to check whether a sub-lane is a car lane) - BufferLookup
(to map buildings -> renters) - BufferLookup
(to get household sizes)
- Read/Write:
- ComponentTypeHandle
(to update the edge Density component)
- ComponentTypeHandle
- Output:
- NativeQueue
.ParallelWriter m_DensityActions – enqueues per-sublane DensityActionData items when the derived density changes.
- NativeQueue
- Work performed per chunk:
- For each edge entity in the chunk:
- Reset value.m_Density to 0 and sum occupants:
- For each connected building:
- If building has Renter buffer, iterate renters; for each renter:
- If renter has HouseholdCitizen buffer, add its length (people count).
- Else if renter has WorkProvider, add m_MaxWorkers.
- If building itself is a WorkProvider, add m_MaxWorkers.
- Divide accumulated occupant count by the curve length (nativeArray3[i].m_Length) to produce density.
- Update the Density component on the entity.
- If density changed vs previous, compute density2 = sqrt(max(0.01f, density)) and for each SubLane buffer entry:
- If the sub-lane entity has CarLane component, enqueue a DensityActionData { m_Owner = subLane, m_Density = density2 } into m_DensityActions.
-
The job implements IJobChunk.Execute and has an explicit interface dispatch wrapper.
-
private struct TypeHandle
Container for the various type/buffer/component handles used by the CalculateDensityJob: - EntityTypeHandle
- BufferTypeHandle
(RO) - BufferTypeHandle
(RO) - ComponentTypeHandle
(RO) - ComponentTypeHandle
(RW) - BufferLookup
(RO) - ComponentLookup
(RO) - ComponentLookup
(RO) - BufferLookup
(RO) - Method __AssignHandles(ref SystemState state) populates these handles via state.Get... calls and is called from OnCreateForCompiler.
Usage Example
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
// Typical OnCreate: set up query and get dependent systems.
m_PathfindQueueSystem = base.World.GetOrCreateSystemManaged<PathfindQueueSystem>();
m_EdgeQuery = GetEntityQuery(
ComponentType.ReadOnly<Game.Net.Edge>(),
ComponentType.ReadOnly<ConnectedBuilding>(),
ComponentType.ReadWrite<Density>(),
ComponentType.ReadOnly<Curve>(),
ComponentType.Exclude<Temp>(),
ComponentType.Exclude<Deleted>()
);
RequireForUpdate(m_EdgeQuery);
}
Notes and implementation details: - The main density calculation is Burst compiled and runs in parallel over entity chunks (IJobChunk + ScheduleParallel). - The system aggregates both household citizens (by buffer lengths) and workplace capacity (WorkProvider.m_MaxWorkers). It normalizes by edge length and stores the result in the Density component. - When density changes, a derived sqrt density is enqueued per car sub-lane (DensityActionData) so pathfinding or traffic systems can react to updated edge densities. - The system interacts with PathfindQueueSystem by creating a DensityAction (backed by NativeQueue) and enqueuing it with the job dependency, so consumer systems can process density updates safely after the job completes.