Search Unity

Dynamic Buffer From Buffer From Entity Incorrect Safety Check Results?

Discussion in 'Entity Component System' started by desertGhost_, Dec 14, 2019.

  1. desertGhost_

    desertGhost_

    Joined:
    Apr 12, 2018
    Posts:
    260
    I have a system that writes to a buffer on another entity if it exists.

    Here is the code:
    Code (CSharp):
    1.  
    2.     public class EquippedAnimatorSystem : JobComponentSystem
    3.     {
    4.         [BurstCompile]
    5.         struct OnEquipJob : IJobForEachWithEntity<OnEquip, EquippedIntegerAnimParam>
    6.         {
    7.             [ReadOnly]
    8.             public BufferFromEntity<IntegerParameter> lookup;
    9.  
    10.             public void Execute(Entity entity, int index,
    11.                                 [ReadOnly] ref OnEquip onEquip,
    12.                                 [ReadOnly] ref EquippedIntegerAnimParam animParam)
    13.             {
    14.                 if (lookup.Exists(onEquip.equipperEntity))
    15.                 {
    16.                     var buffer = lookup[onEquip.equipperEntity];
    17.  
    18.                     buffer.Add(new IntegerParameter
    19.                     {
    20.                         Hash = animParam.hash,
    21.                         Value = animParam.equippedState
    22.                     });
    23.                 }
    24.             }
    25.         }
    26.  
    27.         [BurstCompile]
    28.         struct OnUnequipJob : IJobForEachWithEntity<OnUnequip, EquippedIntegerAnimParam>
    29.         {
    30.             [ReadOnly]
    31.             public BufferFromEntity<IntegerParameter> lookup;
    32.  
    33.             public void Execute(Entity entity, int index,
    34.                                 [ReadOnly] ref OnUnequip onUnequip,
    35.                                 [ReadOnly] ref EquippedIntegerAnimParam animParam)
    36.             {
    37.                 if (lookup.Exists(onUnequip.equipperEntity))
    38.                 {
    39.                     var buffer = lookup[onUnequip.equipperEntity];
    40.  
    41.                     buffer.Add(new IntegerParameter
    42.                     {
    43.                         Hash = animParam.hash,
    44.                         Value = -1
    45.                     });
    46.                 }
    47.             }
    48.         }
    49.  
    50.         protected override JobHandle OnUpdate(JobHandle inputDependencies)
    51.         {
    52.             var handle = new OnEquipJob
    53.             {
    54.                 lookup = GetBufferFromEntity<IntegerParameter>()
    55.             }.Schedule(this, inputDependencies);
    56.  
    57.             handle = new OnUnequipJob
    58.             {
    59.                 lookup = GetBufferFromEntity<IntegerParameter>()
    60.             }.Schedule(this, handle);
    61.  
    62.             return handle;
    63.         }
    64.     }
    This code ran without any problems in 2019.2 with Entities 0.1.1, but using 2019.3.0f3 with Entities 0.3 I am getting an error whenever this system runs (I disabled burst compilation to get the error message).

    The error is:

    InvalidOperationException: The native container has been declared as [ReadOnly] in the job, but you are writing to it.
    Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckWriteAndThrowNoEarlyOut (Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle handle)


    An exception is thrown when trying to add an element to a buffer that I looked up in a job, but the docs seem to show a similar use case.

    Anyone else run into this issue? Am I accessing the buffer incorrectly? Is there a work around?
     
  2. thelebaron

    thelebaron

    Joined:
    Jun 2, 2013
    Posts:
    857
    youve set your buffer to readonly when it looks like you are writing to it. use [NativeDisableParallelForRestriction] instead of readonly
     
  3. desertGhost_

    desertGhost_

    Joined:
    Apr 12, 2018
    Posts:
    260
    I'll try using
    [NativeDisableParallelForRestriction]
    .

    Code (CSharp):
    1. [ReadOnly]
    2. public BufferFromEntity<IntegerParameter> lookup;
    My impression was that this sets the BufferFromEntity as readonly not the buffer itself. Is this not the case? This code worked fine using older versions of the entity package (albeit that could have an error in older versions of the package).

    Wouldn't I need to

    call
    lookup = GetBufferFromEntity<IntegerParameter>(true)
    when scheduling

    to set the buffer as read only?

    Edit: using
    [NativeDisableParallelForRestriction]
    did the trick. Thanks.
     
    Last edited: Dec 14, 2019