Game.NetCompositionMeshSystem
Assembly: Assembly-CSharp (typical Unity game assembly)
Namespace: Game.Prefabs
Type: class
Base: GameSystemBase
Summary:
NetCompositionMeshSystem is an ECS system that maintains a concurrent mapping from a mesh hash (int) to the Entities that reference that mesh ( NativeParallelMultiHashMap
Fields
-
private EntityQuery m_MeshQuery
Holds the query used to find entities that have NetCompositionMeshData and either Created or Deleted components. The query is constructed in OnCreate. -
private NativeParallelMultiHashMap<int, Entity> m_MeshEntities
The central concurrent map from mesh hash to entity. Allocated with Allocator.Persistent in OnCreate and disposed in OnDestroy. Used by the internal CompositionMeshJob to add/remove entities. -
private JobHandle m_Dependencies
Tracks job dependencies of readers that want to access m_MeshEntities. Systems that read the map should pass their JobHandle to AddMeshEntityReader so this system can combine dependencies before scheduling its update. -
private TypeHandle __TypeHandle
Holds cached Entity/Component type handles (EntityTypeHandle, ComponentTypeHandle, ComponentTypeHandle ) to be used when scheduling the job. Populated via __AssignHandles. -
private struct CompositionMeshJob
(nested)
IJobChunk implementation that iterates matching chunks and either adds or removes entries in m_MeshEntities depending on whether the chunk contains Deleted components. Uses GetNativeArray for Entity and NetCompositionMeshData to process each element in the chunk. -
private struct TypeHandle
(nested)
Helper struct used to store per-system type handles and to assign them from the SystemState via __AssignHandles.
Properties
- None exposed publicly.
(Internally the system uses fields and exposes accessors via methods below.)
Constructors
public NetCompositionMeshSystem()
Default parameterless constructor. No special runtime logic beyond what GameSystemBase provides; actual initialization happens in OnCreate.
Methods
-
protected override void OnCreate()
Initializes the EntityQuery to select entities that have NetCompositionMeshData and either Created or Deleted. Allocates m_MeshEntities as a NativeParallelMultiHashMapwith initial capacity 100 and Allocator.Persistent. Calls RequireForUpdate(m_MeshQuery) so the system runs only when relevant entities exist. -
protected override void OnDestroy()
Completes any outstanding dependencies (m_Dependencies.Complete()), disposes m_MeshEntities, and calls base.OnDestroy(). Ensures no jobs are left using the map before it's freed. -
public NativeParallelMultiHashMap<int, Entity> GetMeshEntities(out JobHandle dependencies)
Returns the internal m_MeshEntities and outputs the JobHandle (m_Dependencies) representing dependencies that must be respected by readers. Callers should use the returned dependencies to avoid race conditions (e.g., combine dependencies before scheduling readers). -
public void AddMeshEntityReader(JobHandle dependencies)
Called by external readers to provide their JobHandle so this system can track combined dependencies. The provided handle is stored in m_Dependencies and is later combined when scheduling the CompositionMeshJob. -
protected override void OnUpdate()
Schedules the CompositionMeshJob (IJobChunk) against m_MeshQuery. The job receives EntityTypeHandle, Deleted component type handle (read-only), NetCompositionMeshData component type handle (read-only), and the m_MeshEntities map. The system combines base.Dependency with m_Dependencies when scheduling, then assigns the resulting JobHandle to both base.Dependency and m_Dependencies. -
protected override void OnCreateForCompiler()
Compiler/IL-generation helper to assign queries and type handles during code-gen. Calls __AssignQueries and __TypeHandle.__AssignHandles. -
private void __AssignQueries(ref SystemState state)
Used by OnCreateForCompiler to initialize query related compiler plumbing. No runtime query creation is performed here (OnCreate constructs the runtime query). -
(CompositionMeshJob)
void Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
Per-chunk processing: gets NativeArrayand NativeArray . If the chunk Has Deleted, iterates entities and removes any m_MeshEntities entries where the mapped entity equals the chunk entity (removing by iterator). Otherwise adds entries mapping nativeArray2[j].m_Hash -> nativeArray[j] for each element. Implementation uses NativeParallelMultiHashMap TryGetFirstValue / TryGetNextValue for removals and Add for insertions. Note: this modifies the shared m_MeshEntities map from within a job; NativeParallelMultiHashMap supports concurrent operations if used correctly.
Usage Example
// Example: initialization inside the system (already present in the class)
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
m_MeshQuery = GetEntityQuery(new EntityQueryDesc
{
All = new ComponentType[1] { ComponentType.ReadOnly<NetCompositionMeshData>() },
Any = new ComponentType[2]
{
ComponentType.ReadOnly<Created>(),
ComponentType.ReadOnly<Deleted>()
}
});
m_MeshEntities = new NativeParallelMultiHashMap<int, Entity>(100, Allocator.Persistent);
RequireForUpdate(m_MeshQuery);
}
// Example: how another system can read the map safely
public void SomeOtherSystemMethod()
{
// Acquire the current dependency and the map
JobHandle deps;
var map = netCompositionMeshSystem.GetMeshEntities(out deps);
// If scheduling jobs that read 'map', combine their JobHandle with 'deps'
JobHandle myReaderHandle = /* schedule your reader job that reads map */;
netCompositionMeshSystem.AddMeshEntityReader(myReaderHandle);
// If you need synchronous access on main thread:
deps.Complete();
// Now safe to read map on main thread
if (map.TryGetFirstValue(someHash, out var entity, out var it))
{
do
{
// use entity
} while (map.TryGetNextValue(out entity, ref it));
}
}
Notes and caveats: - The NativeParallelMultiHashMap is allocated with Allocator.Persistent; callers must not attempt to dispose it — the owning system disposes it in OnDestroy. - Readers must coordinate via JobHandle: call GetMeshEntities to obtain the current dependencies and combine them with their own scheduled jobs; pass their JobHandle back to this system via AddMeshEntityReader so the system can avoid races on the next update. - The CompositionMeshJob treats chunks with Deleted specially by removing entries for entities in that chunk; for non-deleted chunks it simply adds mappings. This means duplicate keys (same hash) may map to multiple Entities, which is why a multi-hashmap is used.