Skip to content

Game.UI.InGame.PostInfoviewUISystem

Assembly: Assembly-CSharp (game)
Namespace: Game.UI.InGame

Type: class

Base: InfoviewUISystemBase

Summary:
A UI system that updates the "post" (mail) information infoview in-game. It collects statistics about mail production, collection and delivery by scanning mail-producing buildings (MailProducer) and computing a mail production rate based on prefab accumulation data and the number of residents/workers associated with each building. It also reads city-level statistics for collected/delivered mail and publishes an availability indicator used by the UI. The system uses a Burst-compiled IJobChunk (UpdateMailRateJob) to parallelize counting/accumulation across entities and stores intermediate results in a NativeArray that is created on system creation and disposed on destruction.


Fields

  • private const string kGroup = "postInfo"
    Provides the binding group name used for ValueBindings.

  • private const float kAccumulationFactor = 72.81778f
    Constant factor used to convert/scale accumulation values from prefabs to the final mail production rate.

  • private CityStatisticsSystem m_CityStatisticsSystem
    Reference to the city statistics system (used to query delivered/collected mail totals).

  • private EntityQuery m_PostFacilityModifiedQuery
    EntityQuery that matches Building + PostFacility and changes (Created/Updated/Deleted) to detect modified post facilities.

  • private EntityQuery m_MailProducerQuery
    EntityQuery for mail-producing buildings: Building + MailProducer + PrefabRef (excludes Deleted/Temp). Used as the input query for the UpdateMailRateJob.

  • private EntityQuery m_MailProducerModifiedQuery
    EntityQuery that matches building mail producers and changes (Created/Updated/Deleted) to detect modified mail producers.

  • private ValueBinding<int> m_CollectedMail
    Binding that exposes the number of collected mail to the infoview UI.

  • private ValueBinding<int> m_DeliveredMail
    Binding that exposes the number of delivered mail to the infoview UI.

  • private ValueBinding<float> m_MailProductionRate
    Binding that exposes the computed mail production rate to the infoview UI.

  • private ValueBinding<IndicatorValue> m_PostServiceAvailability
    Binding that provides a combined availability indicator for post services (calculated from produced vs processed mail).

  • private NativeArray<float2> m_Result
    A one-element NativeArray used by UpdateMailRateJob to accumulate X/Y components of accumulation results. Allocated in OnCreate and disposed in OnDestroy.

  • private TypeHandle __TypeHandle
    Container struct holding the EntityTypeHandle, ComponentTypeHandles and BufferLookups used to set up the job's handles. Assigned in OnCreateForCompiler.

Notes: - The system relies on ValueBinding infrastructure to push values to the UI group "postInfo". - m_Result is persistent and must be disposed — the system handles this in OnDestroy.


Properties

  • protected override bool Active { get; }
    Determines whether the system should be considered active for the UI update. Returns true if base.Active is true, or any of the bindings (m_CollectedMail, m_DeliveredMail, m_MailProductionRate, m_PostServiceAvailability) are active. In short, the system is active if the base is active or any of the bound UI values are active.

  • protected override bool Modified { get; }
    Indicates if relevant data changed and a UI update should occur. Returns true if m_MailProducerModifiedQuery is non-empty (i.e. producers changed) or if m_PostFacilityModifiedQuery is non-empty. If no mail-producer changes, but post facility query is non-empty, Modified is true.


Constructors

  • public PostInfoviewUISystem()
    Default constructor. The system uses OnCreate to initialize runtime state and bindings.

Methods

  • protected override void OnCreate()
    Initializes the system. Actions performed:
  • Calls base.OnCreate().
  • Obtains/creates the CityStatisticsSystem reference.
  • Builds three EntityQuery instances:
    • m_PostFacilityModifiedQuery: matches Building + PostFacility with Created/Updated/Deleted (ignoring Temp).
    • m_MailProducerQuery: matches Building + MailProducer + PrefabRef (excludes Deleted/Temp).
    • m_MailProducerModifiedQuery: matches Building + MailProducer with Created/Updated/Deleted (ignoring Temp).
  • Adds ValueBindings for collected/delivered mail, mail production rate, and post service availability (IndicatorValue).
  • Allocates m_Result as a NativeArray(1) with Allocator.Persistent. Notes:
  • [Preserve] attribute present to keep method from being stripped.
  • Also assigns component handles later via OnCreateForCompiler.

  • protected override void OnDestroy()
    Disposes m_Result (NativeArray) and calls base.OnDestroy(). Ensures no memory leaks.

  • protected override void PerformUpdate()
    Main update entry called by the UI system. It performs:

  • UpdateMailRate() — compute mail production rate by scanning mail producers.
  • UpdateProcessingRate() — read delivered/collected mail statistics from CityStatisticsSystem and update bindings.
  • UpdateAvailability() — compute the service availability indicator and update bound value.

  • private void ResetResults()
    Zeros the m_Result array before scheduling the job. Ensures accumulation starts from zero each update.

  • private void UpdateMailRate()
    Schedules and runs the Burst-compiled UpdateMailRateJob over m_MailProducerQuery. It:

  • Resets m_Result.
  • Fills job handles/lookup fields by calling InternalCompilerInterface helpers and passing __TypeHandle entries and base.CheckedStateRef.
  • Schedules the job with JobChunkExtensions.Schedule, completes it synchronously, reads back m_Result[0], multiplies by kAccumulationFactor (72.81778f), and updates m_MailProductionRate with sum of x and y components. Notes:
  • The job writes results into a float2 (two channels) that are summed.

  • private void UpdateProcessingRate()
    Fetches statistics from m_CityStatisticsSystem:

  • m_DeliveredMail <- GetStatisticValue(StatisticType.DeliveredMail)
  • m_CollectedMail <- GetStatisticValue(StatisticType.CollectedMail)

  • private void UpdateAvailability()
    Updates m_PostServiceAvailability by calculating IndicatorValue.Calculate(processed, production), where processed = delivered + collected, production = mail production rate.

  • private void __AssignQueries(ref SystemState state)
    Compiler helper that currently constructs and disposes a temporary EntityQueryBuilder (placeholder in compiled code). Called from OnCreateForCompiler.

  • protected override void OnCreateForCompiler()
    Compiler-time initialization: calls base, calls __AssignQueries and __TypeHandle.__AssignHandles to populate type handles from the system state. Marked to be used by generated code paths.

  • private struct TypeHandle
    Holds the various EntityTypeHandle, ComponentTypeHandle, ComponentLookup, ComponentLookup, ComponentLookup, BufferLookups for Renter/Employee/HouseholdCitizen. Has method __AssignHandles(ref SystemState state) that populates each handle/lookup using state.GetEntityTypeHandle, state.GetComponentTypeHandle, and state.GetComponentLookup / state.GetBufferLookup. This struct is used to build the job input handles.

  • private struct UpdateMailRateJob : IJobChunk (Burst compiled)
    A detailed description:

  • Purpose: iterate over chunks of mail-producing buildings and accumulate mail accumulation rate weighted by the number of residents and workers associated with each building. The final result is written into an external NativeArray m_Result.
  • Fields:
    • ReadOnly EntityTypeHandle m_EntityHandle
    • ReadOnly ComponentTypeHandle m_PrefabRefHandle
    • ReadOnly ComponentLookup m_ServiceObjectFromEntity
    • ReadOnly ComponentLookup m_SpawnableDataFromEntity
    • ReadOnly ComponentLookup m_MailAccumulationFromEntity
    • ReadOnly BufferLookup m_RenterFromEntity
    • ReadOnly BufferLookup m_EmployeeFromEntity
    • ReadOnly BufferLookup m_HouseholdCitizenFromEntity
    • NativeArray m_Result (accumulator)
  • Execute logic (per chunk):
    • For each entity in the chunk:
    • Retrieve PrefabRef and determine mail accumulation rate:
      • If prefab has SpawnableBuildingData, then look up MailAccumulationData on componentData.m_ZonePrefab.
      • Else if prefab has ServiceObjectData, look up MailAccumulationData on componentData3.m_Service.
      • If found, read m_AccumulationRate (float2) into local variable.
    • Determine number of relevant citizens for that building:
      • If entity has Renters buffer, iterate renters and sum household/employee counts by using GetCitizenCounts on renter targets.
      • Otherwise, call GetCitizenCounts(entity, ...) which uses BufferLookup.HasBuffer to count HouseholdCitizen and Employee buffers attached to the entity.
    • Accumulate into m_Result[0] by adding accumulationRate * totalCitizenCount.
  • Helper methods within job:
    • GetCitizenCounts(DynamicBuffer renters, BufferLookup, BufferLookup, out residentCount, out workerCount)
    • GetCitizenCounts(Entity entity, BufferLookup, BufferLookup, out residentCount, out workerCount)
  • The job writes into m_Result which is later multiplied by kAccumulationFactor in UpdateMailRate.
  • The job is Burst-compiled and uses low-level Unity ECS chunk iteration.

Notes: - The job calls m_Result[0] += @float * num which means it accumulates counts for all processed buildings into element 0; the float2 is used (probably X/Y correspond to different mail types or sub-accumulations).


Usage Example

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();

    // Typical initialization the system performs:
    m_CityStatisticsSystem = base.World.GetOrCreateSystemManaged<CityStatisticsSystem>();

    m_PostFacilityModifiedQuery = GetEntityQuery(new EntityQueryDesc
    {
        All = new ComponentType[2] { ComponentType.ReadOnly<Building>(), ComponentType.ReadOnly<Game.Buildings.PostFacility>() },
        Any = new ComponentType[3] { ComponentType.ReadOnly<Deleted>(), ComponentType.ReadOnly<Updated>(), ComponentType.ReadOnly<Created>() },
        None = new ComponentType[1] { ComponentType.ReadOnly<Temp>() }
    });

    m_MailProducerQuery = GetEntityQuery(ComponentType.ReadOnly<Building>(),
                                         ComponentType.ReadOnly<MailProducer>(),
                                         ComponentType.ReadOnly<PrefabRef>(),
                                         ComponentType.Exclude<Deleted>(),
                                         ComponentType.Exclude<Temp>());

    AddBinding(m_CollectedMail = new ValueBinding<int>("postInfo", "collectedMail", 0));
    AddBinding(m_DeliveredMail = new ValueBinding<int>("postInfo", "deliveredMail", 0));
    AddBinding(m_MailProductionRate = new ValueBinding<float>("postInfo", "mailProductionRate", 0f));
    AddBinding(m_PostServiceAvailability = new ValueBinding<IndicatorValue>("postInfo", "postServiceAvailability", default(IndicatorValue), new ValueWriter<IndicatorValue>()));

    m_Result = new NativeArray<float2>(1, Allocator.Persistent);
}

Additional implementation notes ({{ YOUR_INFO }}): - The system mixes Unity ECS and traditional managed systems: it obtains a managed CityStatisticsSystem via base.World.GetOrCreateSystemManaged(). - The computed mail production rate comes from prefab MailAccumulationData multiplied by a constant factor (72.81778f). That factor likely converts per-tick accumulation from internal units to the UI's displayed per-minute or per-day rate — treat it as an internal conversion constant. - Because the job accumulates into a single NativeArray element and the job is completed (Complete()) immediately, this system uses synchronous results. If you adapt this for performance, consider letting the job run asynchronously and chaining dependencies properly via base.Dependency. - Always ensure m_Result is disposed in OnDestroy (as done here) to avoid NativeArray leaks. - If you need to extend or filter which mail producers are considered, adjust m_MailProducerQuery accordingly or modify UpdateMailRateJob logic. - The UpdateMailRateJob assumes certain prefab relationships: - For spawnable buildings: SpawnableBuildingData.m_ZonePrefab -> MailAccumulationData - For service objects: ServiceObjectData.m_Service -> MailAccumulationData Ensure prefabs in your mod follow those conventions if you want mail accumulation to be detected.