Pointers and Queries in IJobEntity

I have a single entity with a Random IComponentData that is used across multiple systems.

For a unsafe pointer in a parallel IJobEntity, if that job would last longer then the SimulationSystemGroup would the ECS Sync point stop that pointer from becoming invalid? Is there other things I need to check for when using pointers in a parallel IJobEntity?

Or instead of using pointers, can IJobEntity do 2 queries? One for the random component and the other for the multiple entities that will use it.

public partial struct AISystem : ISystem
{
    [BurstCompile]
    public void OnCreate(ref SystemState state)
    {
        state.RequireForUpdate<RNG_Data>();
    }

    [BurstCompile]
    public void OnUpdate(ref SystemState state)
    {
        var Data = SystemAPI.GetSingletonRW<RNG_Data>();

        new AIJob
        {
            rng = Data,
            delta = SystemAPI.Time.DeltaTime,
        }.ScheduleParallel();
    }
}
[BurstCompile]
public partial struct AIJob : IJobEntity
{
    [ReadOnly] public float delta;
    [NativeDisableUnsafePtrRestriction] public RefRW<RNG_Data> rng;
    public void Execute(ref AIInstructions instructions, in FlyingAIData flying, ref LocalTransform transform)
    {
        if (instructions.task == AITask.Roaming)
        {
            Kapisi.Math.CountDown(ref instructions.MoveTime, delta);

            if (instructions.MoveTime <= 0)
            {
                instructions.MoveTime = rng.ValueRW.random.NextFloat(1, 3);
            }
        }
    }
}

The previous (final output) job handle for the system gets forcefully completed (internal method SystemState.BeforeOnUpdate) before updating the system, so you don’t need to worry about that part. Since the system is registered with read-write access to the singleton, dependency chaining should take care of multiple writers being scheduled as writing to that component type, and sync points would also forcefully complete tracked jobs, so things should generally be safe.

The one thing that troubles me is writing to a single instance in a parallel job. Unity.Mathematics.Random does not have inherent thread safety, so there’s a race condition between different threads for the job. It’s possible two executions grab the state at the same time and end up producing the same result. You can use the Interlocked class for exclusive access as seen in the collections package.

1 Like