Please attribute NativeArray.ReadOnly with NativeContainerSupportsDeferredConvertListToArray

Hey,

we currently have some inconsistencies with deferring NativeLists.

In short, calling list.AsDeferredJobArray().AsReadOnly() will yield an empty NativeArray<int>.ReadOnly array in the job.

Passing list.AsDeferredJobArray() into [ReadOnly] NativeArray<int> works, but you lose compile-time checks. There also works readonly NativeArray<int>, but I am not sure how well supported is readonly within the job system, I don’t remember seeing it documented anywhere.

Anyway, in project I work on, we have our own .ReadOnly type attributed with NativeContainerSupportsDeferredConvertListToArray and it simply works, but it would be nice to have such behaviour in the core.

Reproduction code:

public static class Test
{
    public struct AddJob : IJob
    {
        public NativeList<int> data;
        public void Execute()
        {
            data.Add(1);
            data.Add(2);
            data.Add(3);
        }
    }

    public struct SumDeferredJob : IJob
    {
        [ReadOnly]
        public NativeArray<int> data;

        public void Execute()
        {
            var sum = 0;
            foreach (var i in data)
            {
                sum += i;
            }
            Debug.Log($"SumDeferredJob {sum}");
        }
    }

    public struct SumDeferredReadonlyArray: IJob
    {
        public readonly NativeArray<int> data { get; init; }

        public void Execute()
        {
            var sum = 0;
            foreach (var i in data)
            {
                sum += i;
            }
            Debug.Log($"SumDeferredReadonlyArray {sum}");
        }
    }

    public struct SumDeferredArrayReadOnlyJob : IJob
    {
        public NativeArray<int>.ReadOnly data;

        public void Execute()
        {
            var sum = 0;
            foreach (var i in data)
            {
                sum += i;
            }
            Debug.Log($"SumDeferredArrayReadOnlyJob {sum}");
        }
    }

    [UnityEditor.MenuItem("Test/DeferredNativeList")]
    public static void Foo()
    {
        using var data = new NativeList<int>(1, Allocator.TempJob);
        var deps = new AddJob() { data = data }.Schedule();
        deps = new SumDeferredJob { data = data.AsDeferredJobArray() }.Schedule(deps);
        deps = new SumDeferredReadonlyArray { data = data.AsDeferredJobArray() }.Schedule(deps);
        deps = new SumDeferredArrayReadOnlyJob { data = data.AsDeferredJobArray().AsReadOnly() }.Schedule(deps);
        deps.Complete();
    }
}
1 Like

You’re better off posting on the correct DOTS forum here.

I can of course move your post there if you wish.

@MelvMay I guess there will be less burden if you simply move my post. Thanks in advance :slight_smile:

1 Like