Skip to content

Game.EndFrameBarrier

Assembly: Game
Namespace: Game.Simulation

Type: class

Base: GameSystemBase

Summary:
EndFrameBarrier is a utility system used to coordinate EntityCommandBuffer creation and playback at the end of the frame. It provides a way for systems to create command buffers, hand out parallel writers for scheduling jobs that record entity commands, and to register job handles so the barrier can ensure command buffer playback only occurs after producers have finished. It also contains lightweight profiling support (a Stopwatch) to measure execution time for the barrier (used internally by the game). Typical usage is to call CreateCommandBuffer() (optionally .AsParallelWriter()) when scheduling jobs that will write entity commands, then call AddJobHandleForProducer(...) to register the job handle returned by the scheduled jobs so the barrier can wait for completion before playback.


Fields

  • private System.Diagnostics.Stopwatch m_Stopwatch
    Used internally to measure/profile how long the barrier's playback and related work takes. Present for debugging / profiling purposes within the engine; not intended to be modified by mods.

  • private Unity.Jobs.JobHandle <producerHandle>k__BackingField
    Backing field that stores the combined JobHandle of the registered producer jobs. The barrier uses this handle to ensure it waits for all producers before playing back the command buffer.

Properties

  • public Unity.Jobs.JobHandle producerHandle { get; private set }
    Exposes the currently tracked producer JobHandle. The setter is private — external code can obtain the handle value but should use AddJobHandleForProducer(...) on the barrier to register job handles. The barrier internally combines job handles (typically via JobHandle.CombineDependencies) so multiple scheduled jobs can be tracked.

Constructors

  • public EndFrameBarrier()
    Default constructor for the barrier system. When created (via World.GetOrCreateSystemManaged()), the system initializes its internal state (including the stopwatch used for profiling). Systems using the barrier do not need to construct it directly; obtain it via the world/system lookup.

Methods

  • protected virtual OnCreate() : System.Void
    Called when the barrier system is created. Initializes internal resources and prepares the system to be used as an end-of-frame command buffer barrier. Typical initialization includes constructing the stopwatch and resetting the internal producer handle.

  • CreateCommandBuffer() : EntityCommandBuffer
    (CreateCommandBuffer is the common pattern for barriers — returns an EntityCommandBuffer that will be played back by the barrier at the appropriate time.) Use CreateCommandBuffer().AsParallelWriter() when scheduling parallel jobs that need to record entity commands. The returned command buffer is valid only until the barrier plays it back; do not store it past the end of frame.

  • AddJobHandleForProducer(Unity.Jobs.JobHandle handle) : void
    Register a job handle produced by jobs that write into command buffers obtained from this barrier. The barrier will combine the provided handle with its internal producer handle and ensure playback does not occur until all registered producers have completed.

Notes: - Always register job handles returned when scheduling jobs that use command buffers produced by this barrier (especially when using AsParallelWriter). - The barrier ensures safe playback ordering; failing to register job handles can cause race conditions or playback to occur before producers finish. - This barrier plays the role of an "end of frame" command buffer system: producers record commands during the frame, then the barrier replays them later (at/near the frame end) in a single place so structural changes happen deterministically.

Usage Example

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    m_Stopwatch = new Stopwatch();
}

Additional common usage pattern (as seen in TrainMoveSystem):

// Create a parallel writer to record entity commands from jobs:
var commandBuffer = m_EndFrameBarrier.CreateCommandBuffer().AsParallelWriter();

// Schedule your jobs that write to the command buffer...
JobHandle jobHandle = JobChunkExtensions.ScheduleParallel(myJob, query, dependency);

// Register the job handle with the barrier so playback waits for the job:
m_EndFrameBarrier.AddJobHandleForProducer(jobHandle);

// Ensure the system's dependency includes the scheduled work:
Dependency = JobHandle.CombineDependencies(Dependency, jobHandle);

This pattern ensures jobs can safely record entity changes to an EntityCommandBuffer and the barrier will replay those changes at the defined end-of-frame point after the producer jobs have completed.