Search Unity

Resolved Use NativeList / NativeArray in two jobs without Complete()

Discussion in 'Entity Component System' started by toomasio, Jan 23, 2021.

  1. toomasio

    toomasio

    Joined:
    Nov 19, 2013
    Posts:
    198
    Is this possible?

    Code (CSharp):
    1. protected override void OnUpdate()
    2.         {
    3.             var deltaDatas = new NativeList<DamageableDeltaData>(0, Allocator.TempJob);
    4.  
    5.             var entJob = Entities
    6.                 .ForEach((ref DynamicBuffer<EntityEventBuffer> buffer, in EntityEventDamageableDelta dam) =>
    7.                 {
    8.                     for (int i = 0; i < buffer.Length; i++)
    9.                     {
    10.                         deltaDatas.Add(new DamageableDeltaData { entity = buffer[i].affected, dam = dam });
    11.                     }
    12.                 })
    13.                 .Schedule(Dependency);
    14.  
    15.             var addJob = new AddDamageableDeltaJob
    16.             {
    17.                 data = deltaDatas,
    18.                 buffer = GetBufferFromEntity<DamageableDeltaBuffer>()
    19.             }
    20.             .Schedule(entJob);
    21.  
    22.             deltaDatas.Dispose();
    23.         }
     
  2. brunocoimbra

    brunocoimbra

    Joined:
    Sep 2, 2015
    Posts:
    679
    Change
    deltaDatas.Dispose();
    to
    deltaDatas.Dispose(addJob);
    and you are all set.
     
    toomasio likes this.
  3. toomasio

    toomasio

    Joined:
    Nov 19, 2013
    Posts:
    198
    Beauty thanks! I also had to update my dependency. new code:

    Code (CSharp):
    1. protected override void OnUpdate()
    2.         {
    3.             var deltaDatas = new NativeList<DamageableDeltaData>(0, Allocator.TempJob);
    4.  
    5.             var entJob = Entities
    6.                 .ForEach((ref DynamicBuffer<EntityEventBuffer> buffer, in EntityEventDamageableDelta dam) =>
    7.                 {
    8.                     for (int i = 0; i < buffer.Length; i++)
    9.                     {
    10.                         deltaDatas.Add(new DamageableDeltaData { entity = buffer[i].affected, dam = dam });
    11.                     }
    12.                 })
    13.                 .Schedule(Dependency);
    14.  
    15.             Dependency = new AddDamageableDeltaJob
    16.             {
    17.                 data = deltaDatas,
    18.                 buffer = GetBufferFromEntity<DamageableDeltaBuffer>()
    19.             }
    20.             .Schedule(entJob);
    21.  
    22.             deltaDatas.Dispose(Dependency);
    23.         }
     
  4. RecursiveEclipse

    RecursiveEclipse

    Joined:
    Sep 6, 2018
    Posts:
    298
    Dispose with a JobHandle returns the dependency, so you can do:

    Code (CSharp):
    1. Dependency = deltaDatas.Dispose(addJob);
    I don't think it matters here, but there are situations where this can cause problems because the next Dependency is not aware of the array.
     
    Last edited: Jan 23, 2021
    toomasio likes this.
  5. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,759
    Is there? Because we never do it. If you know of a specific case be great to share.
     
  6. RecursiveEclipse

    RecursiveEclipse

    Joined:
    Sep 6, 2018
    Posts:
    298
    I think that thought stemmed from my post here, where the arrays gave a memory leak warning when when I didn't use the given handles, despite that I was calling .Complete() on the final:

    https://forum.unity.com/threads/can-asdeferredjobarray-only-be-used-once.899765/#post-5908391

    Granted that is using jobs outside of SystemBase. I can't immediately think of a specific case for SystemBase where this would certainly happen, I just do it automatically now juuuust in case.
     
    Last edited: Jan 23, 2021