Hey,
we currently have some inconsistencies with deferring NativeList
s.
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();
}
}