Skip to content

Game.SubNetReferencesSystem

Assembly:
Namespace: Game.Net

Type: class

Base: GameSystemBase

Summary:
SubNetReferencesSystem maintains SubNet buffer references on owner entities (nodes/edges). It scans chunks of SubNet entities and, depending on Created/Deleted/Temp flags and whether the owner entity exists and has a SubNet buffer, it adds or removes SubNet entries from the owner's SubNet dynamic buffer. The work is performed in a Burst-compiled IJobChunk (UpdateSubNetReferencesJob) and scheduled from OnUpdate. The system requires a specific entity query (m_SubNetQuery) so it only runs when relevant SubNet-related changes exist.


Fields

  • private EntityQuery m_SubNetQuery
    This EntityQuery is constructed in OnCreate to match SubNet entities that either have Created + Owner (and Node or Edge) or Deleted + Owner (and Node or Edge). The system calls RequireForUpdate(m_SubNetQuery) so it only updates when those archetypes are present.

  • private TypeHandle __TypeHandle
    Holds handles for the various Entity/Component type lookups used by the job (EntityTypeHandle, ComponentTypeHandle, ComponentTypeHandle, ComponentTypeHandle, ComponentLookup, ComponentLookup, BufferLookup). The nested __AssignHandles method fills these from the SystemState.

  • (nested) private struct UpdateSubNetReferencesJob
    Contains the job data fields:

  • EntityTypeHandle m_EntityType
  • ComponentTypeHandle<Owner> m_OwnerType (read-only)
  • ComponentTypeHandle<Created> m_CreatedType (read-only)
  • ComponentTypeHandle<Temp> m_TempType (read-only)
  • ComponentLookup<Temp> m_TempData (read-only)
  • ComponentLookup<Deleted> m_DeletedData (read-only)
  • BufferLookup<SubNet> m_SubNets (read/write) This Burst-compiled IJobChunk iterates entity chunks and updates the owner's SubNet buffer by adding or removing SubNet entries.

  • (nested) private struct TypeHandle
    See above field; this struct groups all type handles and provides __AssignHandles to populate them from SystemState.

Properties

  • (none public)
    This system does not expose public properties. All state is internal/private and the behavior is driven by the EntityQuery and the scheduled job.

Constructors

  • public SubNetReferencesSystem()
    Annotated with [Preserve]. Default constructor; no special initialization beyond base construction. The system does its setup in OnCreate.

Methods

  • protected override void OnCreate()
    Creates the m_SubNetQuery. The query is composed of two EntityQueryDesc entries: one matching entities with Created and Owner and either Node or Edge, and another matching Deleted and Owner and either Node or Edge. After creating the query the system calls RequireForUpdate(m_SubNetQuery) so the system only runs when relevant SubNet entities exist.

  • protected override void OnUpdate()
    Builds an UpdateSubNetReferencesJob, populates its type/lookup fields using InternalCompilerInterface helpers referencing __TypeHandle and base.CheckedStateRef, and schedules the job with JobChunkExtensions.Schedule(jobData, m_SubNetQuery, base.Dependency). The job updates owner SubNet buffers by adding unique SubNet entries for created subnets and removing entries for deleted subnets.

  • protected override void OnCreateForCompiler()
    Used by the generated code path to assign queries and type handles during compilation-time helper flows. Calls __AssignQueries and __TypeHandle.__AssignHandles.

  • private void __AssignQueries(ref SystemState state)
    Currently contains a no-op EntityQueryBuilder usage (new EntityQueryBuilder(Allocator.Temp).Dispose()) — kept for compiler-generated initialization patterns.

  • (nested) TypeHandle.__AssignHandles(ref SystemState state)
    Assigns all entity/component type handles and lookups from the provided SystemState:

  • state.GetEntityTypeHandle()
  • state.GetComponentTypeHandle(isReadOnly: true)
  • state.GetComponentTypeHandle(isReadOnly: true)
  • state.GetComponentTypeHandle(isReadOnly: true)
  • state.GetComponentLookup(isReadOnly: true)
  • state.GetComponentLookup(isReadOnly: true)
  • state.GetBufferLookup()

  • (nested & BurstCompile) UpdateSubNetReferencesJob.Execute(in ArchetypeChunk chunk, ...)
    Core logic:

  • Retrieves NativeArray and NativeArray from the chunk.
  • If chunk.Has(Created):
    • If chunk.Has(Temp): for each entity, if the owner entity has a Temp component AND has a SubNet buffer, call CollectionUtils.TryAddUniqueValue on that buffer with the SubNet constructed from the current entity.
    • Else: for each entity, call CollectionUtils.TryAddUniqueValue on the owner's SubNet buffer unconditionally (assuming buffer exists).
  • Else (no Created, implies Deleted case for this query): for each entity, if the owner does not have Deleted and the owner has a SubNet buffer, call CollectionUtils.RemoveValue to remove the SubNet entry.
  • Note: accesses to ComponentLookup and ComponentLookup are used to check component presence on the owner entity; BufferLookup is used to read/write the owner's SubNet dynamic buffer.
  • The method also provides the explicit interface implementation for IJobChunk.Execute that delegates to the typed Execute.

Notes and constraints: - The job is Burst-compiled for performance, so data types used must be Burst-compatible; the code relies on CollectionUtils.TryAddUniqueValue / RemoveValue which operate on DynamicBuffer. - The logic relies on correct Owner ownership semantics: Owner.m_Owner refers to the owner Entity that hosts the SubNet buffer. - The system checks m_TempData.HasComponent(owner) before adding when a Temp component exists on the SubNet chunk — this appears to avoid adding temporary subnets for owners that are not currently present/temporary.

Usage Example

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    // Builds the query so this system only runs when SubNet entities are created/removed.
    m_SubNetQuery = GetEntityQuery(new EntityQueryDesc
    {
        All = new ComponentType[] {
            ComponentType.ReadOnly<Created>(),
            ComponentType.ReadOnly<Owner>()
        },
        Any = new ComponentType[] {
            ComponentType.ReadOnly<Node>(),
            ComponentType.ReadOnly<Edge>()
        }
    }, new EntityQueryDesc
    {
        All = new ComponentType[] {
            ComponentType.ReadOnly<Deleted>(),
            ComponentType.ReadOnly<Owner>()
        },
        Any = new ComponentType[] {
            ComponentType.ReadOnly<Node>(),
            ComponentType.ReadOnly<Edge>()
        }
    });
    RequireForUpdate(m_SubNetQuery);
}

[Preserve]
protected override void OnUpdate()
{
    var jobData = new UpdateSubNetReferencesJob {
        m_EntityType = InternalCompilerInterface.GetEntityTypeHandle(ref __TypeHandle.__Unity_Entities_Entity_TypeHandle, ref base.CheckedStateRef),
        m_OwnerType = InternalCompilerInterface.GetComponentTypeHandle(ref __TypeHandle.__Game_Common_Owner_RO_ComponentTypeHandle, ref base.CheckedStateRef),
        m_CreatedType = InternalCompilerInterface.GetComponentTypeHandle(ref __TypeHandle.__Game_Common_Created_RO_ComponentTypeHandle, ref base.CheckedStateRef),
        m_TempType = InternalCompilerInterface.GetComponentTypeHandle(ref __TypeHandle.__Game_Tools_Temp_RO_ComponentTypeHandle, ref base.CheckedStateRef),
        m_TempData = InternalCompilerInterface.GetComponentLookup(ref __TypeHandle.__Game_Tools_Temp_RO_ComponentLookup, ref base.CheckedStateRef),
        m_DeletedData = InternalCompilerInterface.GetComponentLookup(ref __TypeHandle.__Game_Common_Deleted_RO_ComponentLookup, ref base.CheckedStateRef),
        m_SubNets = InternalCompilerInterface.GetBufferLookup(ref __TypeHandle.__Game_Net_SubNet_RW_BufferLookup, ref base.CheckedStateRef)
    };
    base.Dependency = JobChunkExtensions.Schedule(jobData, m_SubNetQuery, base.Dependency);
}

Additional notes: - Required components referenced by this system: Owner, Created, Deleted, Temp, SubNet, Node, Edge. - The system is compiler-generated-friendly and uses InternalCompilerInterface helpers (typical in generated ECS code paths). - Because it manipulates dynamic buffers on owner entities, ensure owner entities actually have a DynamicBuffer field defined; otherwise BufferLookup.HasBuffer checks will prevent invalid access.