The burst compiler can now access static readonly managed arrays, yay!
However, there is a bug if the array is initialized with a value from another static readonly field.
You can reproduce the bug with the following code by commenting out line 36 and uncommenting line 42.
If the managed array is initialized with a static readonly field as one of its values, then Burst will throw errors about not being able to access the managed array in various ways. Otherwise, it works fine.
As a bonus, lines 13 + 16 show another bug where the auto generated job struct doesn’t work because it is generated with 0 size.
On a side note, I would love if Burst supported Span. Would be great to do Span<Tile> neighbors = stackalloc Tile[4];
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
namespace Game
{
public class NeighborsSystem : SystemBase
{
protected override void OnUpdate()
{
var nonzerosizejob = 0; // (0,0): Burst error BC1049: Zero-size empty struct `Game.NeighborsSystem/Game.<>c__DisplayClass_OnUpdate_LambdaJob0` is not supported. To fix this issue, apply this attribute to the struct: `[StructLayout(LayoutKind.Sequential, Size = 1)]`.
Job.WithCode(() =>
{
_ = nonzerosizejob;
var neighbors = new NativeArray<Tile>(4, Allocator.Temp);
var tile = new Tile(new int2(1, 2));
tile.GetNeighbors(neighbors);
neighbors.Dispose();
}).Run();
}
public enum Direction
{
Invalid,
North,
East,
South,
West
}
[BurstCompile]
public readonly struct Tile
{
private static readonly int2[] directions = new[] { default, new int2(0, 1), new int2(1, 0), new int2(0, -1), new int2(-1, 0) };
// the following array is broken. first you will get:
// NeighborsSystem.cs(54,21): Burst error BC1044: Accessing the managed array `Unity.Mathematics.int2[] Game.NeighborsSystem/Tile::directions` with non-constant length is not supported. To fix this issue, use a constant value for the array length.
// and if you change to using a constant length as suggested, you will then get:
// NeighborsSystem.cs(56,6): Burst error BC1022: Accessing a managed array is not supported
// private static readonly int2[] directions = new[] { int2.zero, new int2(0, 1), new int2(1, 0), new int2(0, -1), new int2(-1, 0) };
private readonly int2 coord;
public Tile(int2 coord)
{
this.coord = coord;
}
public Tile GetNeighbor(Direction direction) => new Tile(coord + directions[(int)direction]);
public void GetNeighbors(NativeArray<Tile> neighbors)
{
for (var i = 1; i < directions.Length; i++)
{
neighbors[i - 1] = new Tile(coord + directions[i]);
}
}
public override string ToString() => coord.ToString();
}
}
}