Skip to content

Game.Simulation.ElectricityRoadConnectionGraphSystem

Assembly: Assembly-CSharp.dll (Game)
Namespace: Game.Simulation

Type: class

Base: GameSystemBase

Summary:
This system maintains the electrical graph connections for road edges in the simulation. It listens for RoadConnectionUpdated events, collects the affected road-edge entities into a persistent NativeQueue, and ensures the electricity flow graph contains (or removes) a flow-edge from a road-edge node to the global sink node whenever the road edge has electricity consumers that are not connected to a building sink. The system coordinates two main units of work:

  • UpdateRoadConnectionsJob (IJobChunk, scheduled parallel): scans RoadConnectionUpdated components and enqueues affected road-edge entities for later processing if the updated building is an electricity consumer and the edge is not deleted.
  • UpdateRoadEdgesJob (IJob, single job): dequeues unique edges, examines connected buildings and consumers, and creates/updates or removes flow-edges to the sink node using a command buffer from a ModificationBarrier. It uses NativeParallelHashSet to deduplicate edges during processing.

The system interacts with the ElectricityFlowSystem (to get sink node and edge archetype) and uses ModificationBarrier5 to safely issue structural changes. It exposes the NativeQueue so other jobs can produce edge updates; AddQueueWriter is used to track producer job dependencies.


Fields

  • private ElectricityFlowSystem m_ElectricityFlowSystem
    Holds a reference to the ElectricityFlowSystem used to obtain the sink node and edge archetype required to create flow edges.

  • private ModificationBarrier5 m_ModificationBarrier
    Barrier system used to create an EntityCommandBuffer for structural changes (creating/deleting flow-edge entities) safely from jobs.

  • private EntityQuery m_EventQuery
    Query that matches entities with RoadConnectionUpdated components; used to decide whether to schedule the chunk job.

  • private NativeQueue<Entity> m_UpdatedEdges
    Persistent NativeQueue (Allocator.Persistent) that stores road-edge entities that need their sink connections evaluated/updated. Producers (jobs or systems) can write to it; the system drains it in UpdateRoadEdgesJob.

  • private JobHandle m_WriteDependencies
    Tracks external producer JobHandle dependencies (jobs that will write into m_UpdatedEdges). Combined into the system dependency to ensure safety.

  • private TypeHandle __TypeHandle
    Generated container for ComponentTypeHandle / ComponentLookup / BufferLookup / etc. used to obtain the component access handles used in jobs.

Properties

  • (none public)
    There are no public auto-properties on this class. Interaction is via methods GetEdgeUpdateQueue and AddQueueWriter.

Constructors

  • public ElectricityRoadConnectionGraphSystem()
    Default constructor. The system performs full initialization in OnCreate().

Methods

  • protected override void OnCreate()
    Initializes references to required systems (ElectricityFlowSystem and ModificationBarrier5), creates the EntityQuery for RoadConnectionUpdated and allocates the persistent NativeQueue m_UpdatedEdges.

  • protected override void OnDestroy()
    Disposes the persistent NativeQueue m_UpdatedEdges and calls base.OnDestroy(). Ensures native memory is freed when the system is destroyed.

  • public NativeQueue<Entity> GetEdgeUpdateQueue(out JobHandle deps)
    Returns the persistent NativeQueue m_UpdatedEdges and outputs current producer dependencies via the out parameter deps (which is m_WriteDependencies). Useful for other systems/jobs that want to enqueue edge updates.

  • public void AddQueueWriter(JobHandle handle)
    Registers an external producer job handle by combining it into m_WriteDependencies. Call this after scheduling a job that writes into the queue so the system will wait on it before draining.

  • protected override void OnUpdate()
    Main scheduling method:

  • Combines internal dependencies with m_WriteDependencies to ensure exclusive access to the queue.
  • If there are RoadConnectionUpdated events, schedules UpdateRoadConnectionsJob as a parallel JobChunk. That job enqueues affected edges into m_UpdatedEdges (using AsParallelWriter()).
  • Schedules UpdateRoadEdgesJob (IJob) to drain the queue and reconcile flow edges to the sink. The job is given a command buffer from m_ModificationBarrier to perform creations/deletions.
  • Adds the producer handle to m_ModificationBarrier and stores the combined dependency into m_WriteDependencies.

  • protected override void OnCreateForCompiler()
    Compiler-time initialization: assigns queries and component handles using the generated __TypeHandle and helpers. Called by the DOTS/IL2CPP codegen glue.

  • private void __AssignQueries(ref SystemState state)
    Generated helper; currently no queries beyond the event query are created here (kept for compiler-generated wiring).

  • Nested structs:

  • UpdateRoadConnectionsJob : IJobChunk

    • Reads RoadConnectionUpdated components and enqueues old/new edge entities when the associated building is an electricity consumer and the old edge is not deleted. Uses ComponentTypeHandle / ComponentLookup lookup handles and writes into a NativeQueue.ParallelWriter.
  • UpdateRoadEdgesJob : IJob

    • Drains the m_UpdatedEdges queue, deduplicates using NativeParallelHashSet, examines ConnectedBuilding buffers for each road edge, sums consumption of electricity consumers that do NOT have a building sink connection, and ensures a forward flow-edge exists from the road-edge node to the sink node with the required capacity. If no such consumers exist, any existing flow-edge to the sink is removed by adding a Deleted component to the edge entity via the command buffer.
    • Uses ElectricityGraphUtils helper methods to set/create/get flow edges.
    • Uses ComponentLookup and BufferLookup handles for data access and an EntityCommandBuffer for structural changes.

Notes on threading and safety: - UpdateRoadConnectionsJob is scheduled parallel and writes to m_UpdatedEdges via AsParallelWriter; producers from other systems should use GetEdgeUpdateQueue and schedule their writer jobs, then call AddQueueWriter with the job handle so this system waits. - UpdateRoadEdgesJob is scheduled as a single IJob but accesses the same queue and uses a NativeParallelHashSet to deduplicate work. Structural changes are issued via the ModificationBarrier's command buffer and deleted entities are marked through that buffer (ensures safety with the ECS structural change rules). - m_UpdatedEdges is persistent and must be disposed (done in OnDestroy). Producers must not access the queue after the system is destroyed.

Usage Example

// Example: Another system schedules a job that finds edges to update and enqueues them
public partial class ExampleProducerSystem : SystemBase
{
    private ElectricityRoadConnectionGraphSystem m_RoadConnSystem;

    protected override void OnCreate()
    {
        m_RoadConnSystem = World.GetOrCreateSystemManaged<ElectricityRoadConnectionGraphSystem>();
    }

    protected override void OnUpdate()
    {
        // Acquire the queue and current dependencies
        JobHandle deps;
        NativeQueue<Entity> queue = m_RoadConnSystem.GetEdgeUpdateQueue(out deps);

        // Schedule a job that writes to the queue (pseudo-job shown)
        var writerJob = new EnqueueEdgesJob
        {
            EdgeQueue = queue.AsParallelWriter(),
            // ... other lookups
        }.ScheduleParallel(this.Dependency);

        // Tell the graph system about our writer job so it waits for it
        m_RoadConnSystem.AddQueueWriter(writerJob);

        // Use writerJob as part of this system's dependency chain
        this.Dependency = writerJob;
    }
}

Additional tips: - Always call AddQueueWriter after scheduling jobs that write into the queue to avoid race conditions. - Because UpdateRoadEdgesJob uses a command buffer from the ModificationBarrier, created/removed flow-edge entities will not be visible until the barrier plays back; that's intended to satisfy ECS structural-change constraints. - The system deduplicates edge processing each frame; enqueuing the same edge multiple times in the same frame is acceptable but redundant.