Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

Creating ArchetypeChunk not every update inside ComponentSystem

Discussion in 'Data Oriented Technology Stack' 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:
    4,571
    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:
    4,571
    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?