Search Unity

Creating ArchetypeChunk not every update inside ComponentSystem

Discussion in 'Entity Component System' started by xman7c7, Jan 10, 2019.

  1. xman7c7

    xman7c7

    Joined:
    Oct 28, 2016
    Posts:
    28
    Hello,

    I have got question about creating NativeArray<ArchetypeChunk> from ComponentGroup or EntityManager for iterating data throught chunks. Is it alright if i recreate Chunks only if ComponentOrderVersion change? e.g. store inside variable (deallocate inside OnDestroyManager)

    I mean i have for example 10k entities who's match my EntityArchetypeQuery. Creating and destroing can only happened occasionally (only if i change settings).

    Code (CSharp):
    1.  
    2. public class TestSystem : ComponentSystem
    3. {
    4.     private ComponentGroup _group;
    5.     private NativeArray<ArchetypeChunk> _chunks;
    6.     private int _testComponentOrderVersion = -1;
    7.  
    8.     protected override void OnCreateManager()
    9.     {
    10.         base.OnCreateManager();
    11.         _group = GetComponentGroup(typeof(TestComponent));
    12.     }
    13.  
    14.     protected override void OnDestroyManager()
    15.     {
    16.         base.OnDestroyManager();
    17.         if (_chunks.IsCreated)
    18.         {
    19.             _chunks.Dispose();
    20.         }
    21.     }
    22.  
    23.     protected override void OnUpdate()
    24.     {
    25.         UpdateArchetypeChunks();
    26.         // work with chunks ...
    27.     }
    28.  
    29.     private void UpdateArchetypeChunks()
    30.     {
    31.         var testComponentOrderVersion = EntityManager.GetComponentOrderVersion<TestComponent>();
    32.         if (testComponentOrderVersion == _testComponentOrderVersion)
    33.         {
    34.             return;
    35.         }
    36.  
    37.         if (_chunks.IsCreated)
    38.         {
    39.             _chunks.Dispose();
    40.         }
    41.  
    42.         _chunks = _group.CreateArchetypeChunkArray(Allocator.Persistent);
    43.  
    44.         _testComponentOrderVersion = testComponentOrderVersion;
    45.     }
    46. }
    47.  
     
  2. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    The recommended API is to use ComponentGroup.GetCombinedComponentOrderVersion();

    In this case, but yes, caching archetypechunk array with this check is safe.
     
  3. xman7c7

    xman7c7

    Joined:
    Oct 28, 2016
    Posts:
    28
    it's working, but i have little problem. OrderVersion from ComponentGroup or EntityManager is not same, but i can accept it. But problem goes when i try to create new entities with different components (without components from cached archetypechunk). Suddenly OrderVersion from ComponentGroup (cached archetypechunk array) start increasing. Is this correct behaviour?

    Code (CSharp):
    1. public struct SomeData1 : IComponentData
    2. {
    3.     public int value;
    4. }
    5.  
    6. public struct SomeData2 : IComponentData
    7. {
    8.     public int value;
    9. }
    Code (CSharp):
    1. [ExecuteAlways]
    2. public class CreateSystem : ComponentSystem
    3. {
    4.     private EntityArchetype _entityArchetype;
    5.  
    6.     protected override void OnCreateManager()
    7.     {
    8.         base.OnCreateManager();
    9.         EntityManager.CreateEntity(EntityManager.CreateArchetype(typeof(SomeData1)));
    10.         EntityManager.CreateEntity(EntityManager.CreateArchetype(typeof(SomeData1)));
    11.         EntityManager.CreateEntity(EntityManager.CreateArchetype(typeof(SomeData1)));
    12.         EntityManager.CreateEntity(EntityManager.CreateArchetype(typeof(SomeData1)));
    13.      
    14.         _entityArchetype = EntityManager.CreateArchetype(typeof(SomeData2));
    15.     }
    16.  
    17.     protected override void OnUpdate()
    18.     {
    19.         PostUpdateCommands.CreateEntity(_entityArchetype);
    20.     }
    21. }
    22.  
    Code (CSharp):
    1. public class UpdateSystem : ComponentSystem
    2. {
    3.     private ComponentGroup _group;
    4.  
    5.     protected override void OnCreateManager()
    6.     {
    7.         base.OnCreateManager();
    8.         _group = GetComponentGroup(typeof(SomeData1));
    9.     }
    10.  
    11.     protected override void OnUpdate()
    12.     {
    13.         Debug.Log("----------------");
    14.         Debug.Log($"ComponentGroup: {_group.GetCombinedComponentOrderVersion()}");
    15.         Debug.Log($"EntityManager: {EntityManager.GetComponentOrderVersion<SomeData1>()}");
    16.     }
    17. }
     
    Last edited: Jan 18, 2019
  4. xman7c7

    xman7c7

    Joined:
    Oct 28, 2016
    Posts:
    28
    Can someone explain me previous post? I thought that ComponentOrderVersion from ComponentGroup would not change if i don't create new entity with same components. Is it bug or correct behaviour?
    Thanks
     
  5. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    GetCombinedComponentOrderVersion() changes when anything happens to a chunk that is compatible with the ComponentGroupQuery. In this case, any change to any entity containing SomeData1.
     
  6. xman7c7

    xman7c7

    Joined:
    Oct 28, 2016
    Posts:
    28
    Yeah this i know, but in my example i have two systems:
    1. CreateSystem - ExecuteAlways
      • OnCreateManager - create 4 entities with component SomeData1, none of it has SomeData2
      • OnUpdate - create new entity with component SomeData2, none of it has SomeData1
    2. UpdateSystem
      • OnCreateManager - ComponentGroup of entities with component SomeData1
      • OnUpdate - printing order version from coponent SomeData1 via ComponentGroup / EntityManager
    So I'm not creating any new entities with component SomeData1. Only creating entities with component SomeData2. So why is ComponentOrderVersion change from ComponentGroup if i dont modify any entity or create/delete with component type SomeData1?

    or maybe i something missing?