Game.Notifications.IconCommandSystem
Assembly:
Namespace: Game.Notifications
Type: class
Base: GameSystemBase
Summary:
IconCommandSystem collects icon commands (IconCommandBuffer.Command) produced by game code or jobs, and plays them back into the entity world as notification icon entities or updates to existing icon entities. It aggregates per-job command queues, flattens and sorts the commands each frame, then schedules a Burst-compiled IJob (IconCommandPlaybackJob) to perform the actual entity changes using an EntityCommandBuffer produced by a ModificationEndBarrier. The system handles add/remove/update semantics, temporary icons, clustering/animation choices, target and owner updates, and location resolution (transform/node/curve/route waypoint/etc.) for icon positioning.
Fields
-
private ModificationEndBarrier m_ModificationBarrier
Used to obtain an EntityCommandBuffer for safe structural changes produced by the playback job. The system gets the ModificationEndBarrier in OnCreate and uses it to create the command buffer given to IconCommandPlaybackJob. -
private EntityQuery m_ConfigurationQuery
Query used to find the icon configuration singleton entity (IconConfigurationData). The playback job reads animation configuration and configuration entity from this query. -
private List<NativeQueue<IconCommandBuffer.Command>> m_Queues
List of NativeQueue instances (one per created IconCommandBuffer) that collect commands produced by other systems/jobs. Each queue is drained and merged into a single NativeArray of commands on update. -
private JobHandle m_Dependencies
Aggregates dependencies from job writers (via AddCommandBufferWriter) so the system completes/waits for writers before consuming queues. -
private int m_BufferIndex
Counter used to assign each created IconCommandBuffer a unique buffer index (passed into the returned IconCommandBuffer). -
private TypeHandle __TypeHandle
Container used to cache multiple ComponentLookup/BufferLookup/EntityStorageInfoLookup handles. These are assigned in OnCreateForCompiler and passed into the playback job to obtain component/buffer access.
Properties
- None (no public properties on this type).
Constructors
public IconCommandSystem()
Default constructor (marked [Preserve] on the class methods). Standard system construction. Initialization happens in OnCreate rather than the constructor.
Methods
-
protected override void OnCreate()
Initializes the system: obtains the ModificationEndBarrier, creates the m_Queues list, and builds the m_ConfigurationQuery for IconConfigurationData. Called once when the system is created. -
protected override void OnStopRunning()
Called when the system stops running: completes any outstanding m_Dependencies, disposes all NativeQueues in m_Queues and clears the list. Ensures no NativeQueue memory leaks. -
public IconCommandBuffer CreateCommandBuffer()
Creates and returns a new IconCommandBuffer backed by a NativeQueue with Allocator.TempJob. The created queue is added to m_Queues and a buffer index is assigned. The returned IconCommandBuffer is intended to be used by other systems/jobs (its writer can be used in parallel jobs). -
public void AddCommandBufferWriter(JobHandle handle)
Add a job dependency from code that writes to command buffers. The passed JobHandle is combined with the system's current m_Dependencies to ensure the system waits for writers before consuming the queues. -
protected override void OnUpdate()
Main per-frame logic: - Completes m_Dependencies to ensure all writers finished.
- Counts total commands across all queues; early-exits if there are no commands or the icon configuration is missing.
- Creates a single NativeArray
, drains all queues into it, disposes the queues. - Schedules the Burst-compiled IconCommandPlaybackJob (IJob) with a freshly created EntityCommandBuffer from m_ModificationBarrier and many ComponentLookup/BufferLookup handles (supplied via __TypeHandle).
-
Adds the produced job handle to the modification barrier and sets it as the system dependency.
-
protected override void OnCreateForCompiler()
Internal setup used by the generated code path: assigns queries and component lookup handles by calling __AssignQueries and __TypeHandle.__AssignHandles. (Part of how DOTS-style systems are compiled/structured.) -
private void __AssignQueries(ref SystemState state)
Internal helper for query assignments (used by OnCreateForCompiler in the compiled system). In this implementation the method creates an EntityQueryBuilder (no persistent query is assigned besides m_ConfigurationQuery set in OnCreate). -
(Nested) IconCommandPlaybackJob : IJob (private, BurstCompile)
Summary: The core worker job that executes on a background thread. It receives:- Read-only component lookups (PrefabRef, NotificationIconData, geometry, transforms, node/curve/position, owner/target/currentX, buffers like RouteWaypoint, IconAnimationElement).
- Read/write lookups for Icon components and owner IconElement buffers.
- m_ConfigurationEntity and m_DeltaTime.
- A NativeArray
(DeallocateOnJobCompletion) with all collected commands. - An EntityCommandBuffer for structural/component changes. Behavior:
- Sorts commands by owner and processes them in owner groups.
- For Add commands: tries to find existing icon instances (in owner IconElement dynamic buffer or by creating/setting a dynamic buffer), updates existing icon components (Icon, Target, Temp, Hidden) or creates new notification icon entities using NotificationIconData archetype. Adds Animation component (appear) for non-temp icons, and handles DisallowCluster flag and Transaction layer specifics. If a matching icon is found but deleted, Deleted component is removed.
- For Remove commands: removes icons either by marking Deleted or adding resolve Animation and Updated. Supports removing "All" icons of a priority, using temporary de-duplication table to track which priorities/buffer indices were removed this frame.
- For Update commands: recalculates icon locations (unless IconFlags.CustomLocation) using FindLocation and updates Icon component if the position changed.
- Location resolution via FindLocation: resolves connected entities, current building, transport, vehicle, then checks Transform component, Node/Curve/Position components, or route waypoints; uses geometry to adjust height when appropriate (object bounds, net surface height, destroyed/cleared state).
- Helper methods: GetIconData, GetTempData, DeleteIcon, FindIcon, GetAppearAnimation/GetResolveAnimation. Notes:
- The job uses DeallocateOnJobCompletion for the commands array; the job is responsible for consuming and sorting commands.
- All structural changes (create, add/remove component, set component, add buffer) are performed via the provided EntityCommandBuffer.
-
private void __AssignHandles(ref SystemState state)
(on TypeHandle)
Populates the TypeHandle's ComponentLookup/BufferLookup fields by calling GetComponentLookup/GetBufferLookup/GetEntityStorageInfoLookup on the provided SystemState. Called from OnCreateForCompiler to prepare handles that will be passed into the job.
Usage Example
// Example: create a command buffer and register a writer dependency from a job.
// This runs from managed system code (or mod initialization code).
[Preserve]
public class MyIconProducerSystem : GameSystemBase
{
private IconCommandSystem _iconSystem;
protected override void OnCreate()
{
base.OnCreate();
// Obtain IconCommandSystem instance (ensure it exists in the same World)
_iconSystem = base.World.GetOrCreateSystemManaged<Game.Notifications.IconCommandSystem>();
}
protected override void OnUpdate()
{
// Create a command buffer that other jobs/systems can write to:
var cmdBuffer = _iconSystem.CreateCommandBuffer();
// Example: if you schedule a job that writes to cmdBuffer.AsParallelWriter(),
// obtain the job handle and register it with the icon system so it waits:
// JobHandle writerHandle = myJob.Schedule(...);
// _iconSystem.AddCommandBufferWriter(writerHandle);
// The IconCommandSystem will collect all created command buffers, wait for
// registered writers, and then play back commands into the entity world.
}
}
Notes and tips: - Always call AddCommandBufferWriter when you schedule jobs that write to icon command buffers so IconCommandSystem will wait for those writers to complete before consuming queues. - Command queues are created with Allocator.TempJob and disposed automatically by the system after OnUpdate drains them; do not attempt to dispose those queues yourself. - The playback job runs under Burst and uses component lookups and an EntityCommandBuffer — avoid relying on immediate structural changes; inspect resulting icon entities/components after the system completes its job (or read back via a safe sync). - The system expects a singleton IconConfigurationData entity to be present (m_ConfigurationQuery); if it's missing OnUpdate will early-exit and commands will be dropped/queues cleared. Ensure configuration entity is created by the game or mod that provides notification icon config.