Game.Simulation.ResidentPurposeCounterSystem
Assembly: Assembly-CSharp (Game code)
Namespace: Game.Simulation
Type: class
Base: GameSystemBase
Summary:
ResidentPurposeCounterSystem is a game simulation system that samples all resident (human creature) entities and tallies what purpose they are currently travelling for. It iterates resident archetype chunks and counts destinations/purposes into a persistent NativeArray
Nested types
- enum
CountPurpose
The index mapping for the results array (m_Results). Values: - GoingHome = 0
- GoingToSchool = 1
- GoingToWork = 2
- Leisure = 3
- MovingAway = 4
- Shopping = 5
- Travel = 6
- None = 7
- Other = 8
- TouristLeaving = 9
- Mail = 10
- MovingIn = 11
-
Count = 12
-
struct
PurposeCountJob
(BurstCompiled, implements IJob)
Job that receives a snapshot list of archetype chunks and component handles/lookups and produces counts into the supplied NativeArray(m_Results). It: - Zeroes the results array.
- Iterates each resident in the chunks.
- Skips residents that have no PathElement buffer entries (buffer length == 0).
- Resolves the resident's citizen entity and household via HouseholdMember.
- If the household has MovingAway: increments TouristLeaving (if TouristHousehold) or MovingAway.
- Else if the household exists, the citizen has TravelPurpose and does not have CurrentBuilding:
- Increments MovingIn if the household flag indicates the household hasn't finished moving in.
- Reads TravelPurpose.m_Purpose (overridden by a Divert component if present) and increments the appropriate counter (GoingHome, GoingToSchool, GoingToWork, Leisure, Shopping, Traveling, SendMail -> Mail). Unknown purposes fall back to Other.
-
Otherwise increments None.
-
struct
TypeHandle
Internal container of EntityTypeHandle, ComponentTypeHandle, BufferTypeHandle and ComponentLookup entries used to prepare the job's handles. It exposes __AssignHandles(ref SystemState) to populate these handles.
Fields
-
private EntityQuery m_CreatureQuery
EntityQuery used to find relevant resident entities. It filters for Resident, Human, PrefabRef, UpdateFrame, PathOwner, Target and excludes Unspawned, Deleted, Temp and Stumbling. -
private NativeArray<int> m_Results
NativeArray of length 12 (Allocator.Persistent). Holds counts for each CountPurpose index. Annotated with [EnumArray(typeof(CountPurpose))] and [DebugWatchValue(historyLength = 1024)] so it's intended for debugging/inspection. The array is created in OnCreate and disposed in OnDestroy. Other code must not dispose it. Values are written by the scheduled PurposeCountJob. -
private TypeHandle __TypeHandle
Internal storage of the various type handles / lookups to be passed into the job. Initialized by OnCreateForCompiler (calling __AssignHandles).
Properties
- None (no public properties exposed by this system).
Constructors
public ResidentPurposeCounterSystem()
Default constructor. No custom logic; initialization occurs in OnCreate. The constructor is marked with [Preserve] attribute in the source.
Methods
-
public override int GetUpdateInterval(SystemUpdatePhase phase)
Returns 256. This instructs the update scheduler that this system should run with an interval of 256 frames (i.e., infrequent sampling). -
protected override void OnCreate()
- Builds m_CreatureQuery to select all human resident creatures that are active for path/travel checking.
- Allocates m_Results = new NativeArray
(12, Allocator.Persistent). -
Sets base.Enabled = false (system disabled by default). Marked [Preserve].
-
protected override void OnDestroy()
- Disposes m_Results.
-
Calls base.OnDestroy(). Marked [Preserve].
-
protected override void OnUpdate()
- Creates and schedules PurposeCountJob:
- Uses m_CreatureQuery.ToArchetypeChunkListAsync to get the chunk list and an async dependency (outJobHandle).
- Initializes the job's handles via InternalCompilerInterface.GetEntityTypeHandle / GetComponentTypeHandle / GetBufferTypeHandle / GetComponentLookup passing references from __TypeHandle and the system's CheckedStateRef.
- Passes m_Results to the job so the job writes the counters directly into the NativeArray.
- Schedules the job via IJobExtensions.Schedule and combines dependencies into base.Dependency.
-
Marked [Preserve].
-
private void __AssignQueries(ref SystemState state)
Compiler helper that currently only constructs and disposes a temporary EntityQueryBuilder. Present for compiler-generated plumbing. -
protected override void OnCreateForCompiler()
Called by compiler-infrastructure; it invokes __AssignQueries and assigns handles via __TypeHandle.__AssignHandles(ref base.CheckedStateRef). -
Other generated/utility methods exist to support the job system (e.g., TypeHandle.__AssignHandles).
Notes about concurrency, safety and behavior:
- PurposeCountJob is Burst-compiled and runs as an IJob scheduled from OnUpdate. It writes to the NativeArray
Usage Example
// Example: enable the system and read counts via reflection.
// Note: m_Results is private and a NativeArray<int>. Accessing it directly requires care
// to respect jobs/dependencies and to avoid disposing it. This example demonstrates
// how to get the system instance and read the counts (safely blocking until completion).
using System;
using System.Reflection;
using Unity.Collections;
using Unity.Entities;
// Obtain system (Entities API / world injection may differ in your project)
var world = World.DefaultGameObjectInjectionWorld;
var system = world.GetExistingSystemManaged<Game.Simulation.ResidentPurposeCounterSystem>();
if (system != null)
{
// Ensure the system is enabled so it runs on its interval:
system.Enabled = true;
// Force update to run immediately (or let scheduler run by interval).
world.Update();
// Wait for the system's job to finish by completing world dependency:
world.EntityManager.CompleteAllJobs();
// Reflectively get the private m_Results field:
var fi = typeof(Game.Simulation.ResidentPurposeCounterSystem)
.GetField("m_Results", BindingFlags.NonPublic | BindingFlags.Instance);
var results = (NativeArray<int>)fi.GetValue(system);
int goingHome = results[(int)Game.Simulation.ResidentPurposeCounterSystem.CountPurpose.GoingHome];
int movingIn = results[(int)Game.Simulation.ResidentPurposeCounterSystem.CountPurpose.MovingIn];
Console.WriteLine($"Going home: {goingHome}, Moving in: {movingIn}");
}
Additional notes: - Preferably extend the system or expose a safe API if you need regular access to the counts instead of using reflection. - Be mindful of NativeArray lifetime: do not dispose m_Results from external code. - The enum CountPurpose maps directly to indices used in m_Results; CountPurpose.Count equals 12, which is the allocated array length.