Game.UI.InGame.RoadsInfoviewUISystem
Assembly:
Assembly-CSharp (Unity game assembly where game systems live)
Namespace:
Game.UI.InGame
Type:
class RoadsInfoviewUISystem
Base:
InfoviewUISystemBase
Summary:
RoadsInfoviewUISystem is an ECS-based UI system used by the Roads (traffic) infoview in Cities: Skylines 2. It collects and exposes parking-related statistics (total parking capacity, parked cars, parking income and availability indicator) by querying parking-related entities and scheduling a Burst-compiled job (UpdateParkingJob) to count parking slots and parked cars efficiently using Unity's Jobs/ECS APIs. The system also reads city income statistics for parking income and updates ValueBinding objects that drive the UI indicators. It contains entity queries to track parking facilities and handles persistent native data required for the job runs.
Fields
-
private const string kGroup
A constant string identifier ("roadsInfo") used when creating ValueBindings for the UI. -
private CityStatisticsSystem m_CityStatisticsSystem
Reference to the CityStatisticsSystem used to query income/statistics (used for parking income). -
private ValueBinding<float> m_ParkingCapacity
UI binding for parking capacity (float). Updated each frame the system runs. -
private ValueBinding<int> m_ParkedCars
UI binding for number of parked cars (int). Updated each frame the system runs. -
private ValueBinding<int> m_ParkingIncome
UI binding for parking-related income (int). Updated from CityStatisticsSystem. -
private ValueBinding<IndicatorValue> m_ParkingAvailability
UI binding representing the availability indicator for parking (calculated from capacity and parked cars). -
private EntityQuery m_ParkingFacilityQuery
EntityQuery selecting parking facility entities that contain SubLane/SubNet/SubObject buffers (used to schedule the counting job). -
private EntityQuery m_ParkingFacilityModifiedQuery
EntityQuery used to detect modifications (Created/Deleted/Updated) of parking facilities for the system's Modified property. -
private NativeArray<int> m_Results
Persistent NativeArray (length 2) used to accumulate results from the UpdateParkingJob: index 0 = total slots, index 1 = parked cars. Allocated in OnCreate and disposed in OnDestroy. -
private TypeHandle __TypeHandle
Generated type handle container used to obtain Entity/Buffer/Component lookups for the job and queries. Populated in OnCreateForCompiler. -
private enum Result { Slots, Parked, ResultCount }
Internal enum used to index the m_Results array (Slots = 0, Parked = 1). -
private struct UpdateParkingJob : IJobChunk
A Burst-compiled chunk job that iterates parking facility chunks and counts parking slots and parked cars. Uses many BufferTypeHandle/ComponentLookup/BufferLookup fields to traverse SubNet/SubLane/SubObject hierarchies and to inspect ParkingLane, GarageLane, PrefabRef, ParkingLaneData, LaneObject and ParkedCar components. The job writes aggregated results into the provided NativeArraym_Results. -
private struct TypeHandle
Container for EntityTypeHandle, BufferTypeHandle, ComponentLookup and BufferLookup instances used by the job and the system. Has an __AssignHandles(ref SystemState) method that initializes those handles.
Properties
-
protected override bool Active { get; }
System activity flag. Returns true when the system is active or when any of the parking-related UI bindings (m_ParkedCars, m_ParkingAvailability, m_ParkingCapacity, m_ParkingIncome) are active. This allows the system to run only when the UI needs parking information. -
protected override bool Modified { get; }
Reflects whether parking facilities have been modified. Returns true when m_ParkingFacilityModifiedQuery is not empty (i.e., there are Created/Deleted/Updated events for parking facilities). Used to short-circuit updates when nothing changed.
Constructors
public RoadsInfoviewUISystem()
Default constructor. The system relies on OnCreate to perform initialization.
Methods
[Preserve] protected override void OnCreate()
Initializes the system:- Gets or creates CityStatisticsSystem.
- Builds two EntityQuery instances (m_ParkingFacilityQuery and m_ParkingFacilityModifiedQuery) to find parking facilities and detect modifications.
- Adds ValueBinding instances for "roadsInfo" group: parkingCapacity (float), parkedCars (int), parkingIncome (int), parkingAvailability (IndicatorValue).
-
Allocates m_Results = new NativeArray
(2, Allocator.Persistent). This method wires up all data sources the system needs to update the UI. -
[Preserve] protected override void OnDestroy()
Disposes persistent native data (m_Results.Dispose()) and calls base.OnDestroy(). -
protected override void PerformUpdate()
Main update entry called by the framework when the system runs. It calls: - UpdateCapacity() — schedules and completes the UpdateParkingJob to compute capacity and parked cars, then updates bindings.
- UpdateAvailability() — calculates and updates the parking availability indicator.
-
UpdateIncome() — updates parking income using CityStatisticsSystem.
-
private void ResetResults()
Zeroes the m_Results NativeArray before scheduling the job. -
private void UpdateCapacity()
Prepares and schedules the UpdateParkingJob (Burst compiled) over m_ParkingFacilityQuery using the prepared TypeHandle lookups and the m_Results array. The job completes synchronously (Complete()) before this method updates m_ParkingCapacity and m_ParkedCars bindings from m_Results. -
private void UpdateAvailability()
Updates m_ParkingAvailability binding by computing an IndicatorValue from current parking capacity and parked cars using IndicatorValue.Calculate. -
private void UpdateIncome()
Queries m_CityStatisticsSystem.GetStatisticValue(StatisticType.Income, 9) and updates m_ParkingIncome binding with the result (the index 9 corresponds to parking-related income). -
private void __AssignQueries(ref SystemState state)
Generated helper used by the compiler/OnCreateForCompiler; currently it creates/disposes an EntityQueryBuilder (no-op here) but exists for completeness of generated code. -
protected override void OnCreateForCompiler()
Compiler-time helper that calls __AssignQueries and assigns handles inside __TypeHandle via __TypeHandle.__AssignHandles(ref base.CheckedStateRef). Ensures lookups/handles are ready for job scheduling. -
(Nested Job)
UpdateParkingJob.Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
The job's chunk-execution method. For each entity in the chunk it: - Traverses SubLane/SubNet/SubObject buffers to find parking lanes and garage lanes.
- For parking lanes, uses prefab ParkingLaneData and Curve to compute parking slot count via NetUtils.GetParkingSlotCount; if slot interval is zero, marks slots as effectively "infinite/unusable" by setting slots to a large negative sentinel (-1000000).
- Counts parked cars by checking LaneObject buffers for ParkedCar components.
- For garage lanes, adds vehicle capacity and vehicle count directly.
- Aggregates results into local counters and finally adds them to the shared m_Results NativeArray (index 0 = slots, index 1 = parked).
Notes on job behavior: - The job uses many ComponentLookup and BufferLookup fields (read-only) to traverse entities and buffers. - It is Burst-compiled for performance and scheduled as a JobChunk over m_ParkingFacilityQuery. - The job completes synchronously (Complete()) in UpdateCapacity before bindings are updated.
Usage Example
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
// The system initializes its bindings and native results array here:
// - m_ParkingCapacity, m_ParkedCars, m_ParkingIncome, m_ParkingAvailability
// - m_Results = new NativeArray<int>(2, Allocator.Persistent);
//
// As a modder: you typically do not need to call these directly.
// The system will update the UI bindings automatically in PerformUpdate().
}
Additional notes for modders: - This system is designed to run only when the roads infoview UI is active (or when its specific bindings are active), minimizing overhead. - If you add new parking-related components or change prefab ParkingLaneData semantics (slot interval), ensure the UpdateParkingJob logic (NetUtils.GetParkingSlotCount usage and slot-interval handling) remains consistent. - Avoid directly accessing the private m_Results or internal TypeHandle; instead add/consume UI bindings or extend the system via your own systems that either expose additional bindings or update CityStatisticsSystem/statistics used for income. If you must hook into the counting process, consider creating an additional system that queries the same parking entities or schedules a similar job.