Skip to content

Game.Net.EdgeIterator

Assembly: Game
Namespace: Game.Net

Type: struct

Base: System.ValueType

Summary:
EdgeIterator is a low-level, non-allocating iterator used in the ECS-based networking/road logic to enumerate edges connected to a node. It walks the DynamicBuffer for a given node, taking into account temporary overlays (Temp), hidden edges (Hidden), and deletion flags. It can include or exclude "middle" connections (connections where the node is neither start nor end), and can be driven either relative to a specific edge (to consider delete overrides) or just a node. Typical usage is inside game systems that operate on connections between nodes and edges (e.g., building placement, road editing, removal).


Fields

  • private BufferLookup<ConnectedEdge> m_Edges
    BufferLookup used to retrieve the DynamicBuffer of a node. Required to access the per-node list of connected edges.

  • private ComponentLookup<Edge> m_EdgeData
    ComponentLookup for the Edge component which provides edge metadata such as start/end node. Used to determine whether an edge is connected to the current node as start/end or as a middle.

  • private ComponentLookup<Temp> m_TempData
    ComponentLookup for Temp overlay data. Temp components indicate temporary entities (e.g., during edits) and carry flags (like Delete) and an m_Original mapping to the original entity.

  • private ComponentLookup<Hidden> m_HiddenData
    ComponentLookup for Hidden component. Hidden edges can be skipped by the iterator unless deletion rules override.

  • private DynamicBuffer<ConnectedEdge> m_Buffer
    The current DynamicBuffer instance being iterated. This points to the buffer for the current node (may be the original node if iterating through a temp mapping).

  • private int m_Iterator
    Index-of-next element within m_Buffer. Advances as edges are returned.

  • private Entity m_Node
    Current node entity whose connected-edge buffer is (or will be) iterated.

  • private Entity m_Edge
    Optional edge entity supplied in the constructor. When provided, it is used in delete/override checks.

  • private Entity m_OriginalEdge
    When m_Edge is a temporary edge, this holds the mapped original edge Entity (from Temp component) for comparison against hidden edges.

  • private bool m_Permanent
    True when the starting node is not a temp overlay (i.e., a permanent/original node). Determined by presence/absence of Temp on the starting node.

  • private bool m_Delete
    Whether the iterator is operating in a "delete" mode due to temp flags on either the provided edge or the node. Affects which edges are returned (special-case includes).

  • private bool m_Middles
    If true, the iterator will also return "middle" connections (edges where the node is neither start nor end). If false, only start/end connections are returned.

Properties

  • This struct does not expose any public properties.

Constructors

  • public EdgeIterator(Entity edge, Entity node, BufferLookup<ConnectedEdge> edges, ComponentLookup<Edge> edgeData, ComponentLookup<Temp> tempData, ComponentLookup<Hidden> hiddenData, bool includeMiddleConnections = false)
    Constructs an EdgeIterator for a given node (and optionally driven by a specific edge). The constructor:
  • Stores the provided lookups (m_Edges, m_EdgeData, m_TempData, m_HiddenData).
  • Initializes m_Buffer to the buffer for the provided node and resets m_Iterator to 0.
  • Sets m_Permanent by checking whether the node has a Temp component.
  • If an edge Entity is supplied, calls GetDelete(edge, out m_OriginalEdge) to set m_Delete and map original edge.
  • Otherwise if the node is temporary, sets m_Delete based on the node's Temp flags.
  • Sets m_Middles based on includeMiddleConnections. This prepares the iterator to enumerate edges while respecting temp/hidden/delete logic.

Methods

  • public int GetMaxCount()
    Returns the maximum number of edges that GetNext may enumerate for the current node. This is the length of the current buffer plus, when the node is temporary and an original node buffer exists, the length of the original node's buffer. Useful for sizing arrays or preallocating.

  • public void AddSorted(ref ComponentLookup<BuildOrder> buildOrderData, ref StackList<EdgeIteratorValueSorted> list)
    Iterates all edges with GetNext, builds EdgeIteratorValueSorted entries and appends them to the provided StackList without resizing. For each edge it reads the BuildOrder component to compute m_SortIndex (the midpoint derived from componentData.m_Start and componentData.m_End), sets m_End and m_Middle from the iterator value, then sorts the list (calls list.AsArray().Sort()). Useful for producing a deterministic, spatially sorted list of connected edges.

  • private bool GetDelete(Entity entity)
    Checks whether the given entity has a Temp component and whether the TempFlags.Delete bit is set. Returns true if the entity is marked for deletion in temp state; otherwise false.

  • private bool GetDelete(Entity entity, out Entity original)
    Checks Temp on the entity and, if present, returns the mapped original entity in out parameter original. Returns whether the TempFlags.Delete flag is set. If no Temp component exists, original is set to Entity.Null and returns false.

  • public bool GetNext(out EdgeIteratorValue value)
    Main iterator routine. On each call it advances through the current m_Buffer and yields the next edge that fits the iterator rules:

  • If m_Permanent is true: yields edges where this node is the start or end (sets m_End accordingly). If m_Middles is true, also yields middle connections.
  • If not permanent and m_Delete is true: yields edges that are either equal to m_Edge or are Hidden but equal to m_OriginalEdge (special-case behavior for deletion overlays), applying the same start/end/middle checks.
  • If not permanent and not delete: yields edges that are not Hidden and not marked deleted by Temp.
  • If the current buffer is exhausted and the node has a Temp component mapping to an original node, the iterator switches to the original node buffer and continues.
  • When no more eligible edges remain, sets value.m_Edge to Entity.Null and returns false. The method returns true each time a valid EdgeIteratorValue is produced.

Usage Example

// Example usage inside a SystemBase/ISystem context where lookups are obtained beforehand:
var edgesLookup = SystemAPI.GetBufferLookup<ConnectedEdge>(true);
var edgeLookup = SystemAPI.GetComponentLookup<Edge>(true);
var tempLookup = SystemAPI.GetComponentLookup<Temp>(true);
var hiddenLookup = SystemAPI.GetComponentLookup<Hidden>(true);

Entity driverEdge = /* some edge entity or Entity.Null */;
Entity node = /* node entity to iterate */;

// Create iterator: include middle connections? true/false depending on need
EdgeIterator it = new EdgeIterator(driverEdge, node, edgesLookup, edgeLookup, tempLookup, hiddenLookup, includeMiddleConnections: false);

EdgeIteratorValue val;
while (it.GetNext(out val))
{
    // val.m_Edge : the connected edge entity (may be Entity.Null when exhausted)
    // val.m_End  : true if this node is the edge's end
    // val.m_Middle: true if this is a middle connection (returned only if includeMiddleConnections was true)
    if (val.m_Edge != Entity.Null)
    {
        // process connection
    }
}

// Example using AddSorted to collect and sort connections by build order:
StackList<EdgeIteratorValueSorted> sortedList = default; // ensure initialized appropriately
ComponentLookup<BuildOrder> buildOrderLookup = SystemAPI.GetComponentLookup<BuildOrder>(true);
it = new EdgeIterator(driverEdge, node, edgesLookup, edgeLookup, tempLookup, hiddenLookup, includeMiddleConnections: false);
it.AddSorted(ref buildOrderLookup, ref sortedList);
// sortedList now contains sorted EdgeIteratorValueSorted entries.

Notes: - EdgeIterator is designed to be used with ECS ComponentLookup/BufferLookup obtained from a system with the required access mode (read-only here). - It avoids extra allocations by reusing DynamicBuffer and by using StackList for sorting when desired. - Be careful with lifetime of lookups/buffers: use inside systems or jobs where the lookups are valid.