Search Unity

Request: ISystemStateBufferElementData

Discussion in 'Entity Component System' started by Jay-Pavlina, Jan 25, 2019.

  1. Jay-Pavlina

    Jay-Pavlina

    Joined:
    Feb 19, 2012
    Posts:
    195
    It would be good to have a system state version of IBufferElementData. A use case would be to destroy all children of an entity when it is destroyed. I am storing children in an IBufferElementData.
     
  2. RecursiveEclipse

    RecursiveEclipse

    Joined:
    Sep 6, 2018
    Posts:
    298
    To suggest an alternative, this is a system I use to destroy my child entities. It uses TransformSystem's ParentToChildTree MultiHashMap, which tracks all children for a parent:

    Code (CSharp):
    1. [UpdateAfter(typeof(TransformSystem))]
    2. [UpdateBefore(typeof(EndFrameBarrier))]
    3. public class DestroyHierarchySystem : JobComponentSystem {
    4.     [Inject] EndFrameBarrier barrier;
    5.     bool isInitialized;
    6.     NativeMultiHashMap<Entity, Entity> parentToChildTree;
    7.    
    8.     void Init() {
    9.         //Using reflection to get the existing ParentToChildTree HashMap of TransformSystem.
    10.         var transformSystem = World.GetExistingManager<TransformSystem>();
    11.         var parentToChildInfo = typeof(TransformSystem).GetField(
    12.             "ParentToChildTree", BindingFlags.NonPublic | BindingFlags.Instance);
    13.         parentToChildTree = (NativeMultiHashMap<Entity, Entity>)parentToChildInfo.GetValue(transformSystem);
    14.         isInitialized = true;
    15.     }
    16.  
    17.     [BurstCompile]
    18.     struct DestroyHierarchyJob : IJobProcessComponentDataWithEntity<DestroyEntityTag> {
    19.         public EntityCommandBuffer.Concurrent CommandBuffer;
    20.         [ReadOnly] public NativeMultiHashMap<Entity, Entity> ParentToChildTree;
    21.         [ReadOnly] public ComponentDataFromEntity<DestroyEntityTag> DestroyEntityTags;
    22.        
    23.         public void Execute(Entity entity, int jobIndex, [ReadOnly] ref DestroyEntityTag tag) {
    24.             DestroyTreeIterative(jobIndex, entity);
    25.         }
    26.        
    27.         void DestroyTreeIterative(int jobIndex, Entity parent) {
    28.             CommandBuffer.DestroyEntity(jobIndex, parent);
    29.             if(!ParentToChildTree.TryGetFirstValue(parent, out Entity foundChild, out var iterator)) {
    30.                 return;
    31.             }
    32.             do {
    33.                 DestroyTreeIterative(jobIndex, foundChild);
    34.                 //Check that child does not already have a tag so it is not deleted twice.
    35.                 if(!DestroyEntityTags.Exists(foundChild)) {
    36.                     CommandBuffer.DestroyEntity(jobIndex, foundChild);
    37.                 }
    38.             } while(ParentToChildTree.TryGetNextValue(out foundChild, ref iterator));
    39.         }
    40.     }
    41.  
    42.     protected override JobHandle OnUpdate(JobHandle inputDeps) {
    43.         if(!isInitialized) {
    44.             Init();
    45.         }
    46.         return new DestroyHierarchyJob {
    47.             CommandBuffer = barrier.CreateCommandBuffer().ToConcurrent(),
    48.             ParentToChildTree = parentToChildTree,
    49.             DestroyEntityTags = GetComponentDataFromEntity<DestroyEntityTag>(isReadOnly:true)
    50.         }.Schedule(this, inputDeps);
    51.     }
    52. }
    I just add DestroyEntityTag component to the parent in the hierarchy where I want to destroy, when TransformSystem runs again it cleans up the hashmap for me.
     
  3. Jay-Pavlina

    Jay-Pavlina

    Joined:
    Feb 19, 2012
    Posts:
    195
    I appreciate it but I have already implemented an alternative. It was just an example use case to justify the request. There will always be alternate ways to do things but I think it’s a valid request and fits well with the existing API. I think dynamic buffers should have all of the same features as component data.
     
    nicolasgramlich and JesOb like this.