Generic Burst Job

Im getting overran with repeating code so I did a reading on how to implement Burst generics. So took my first attempt and I got it running in burst but the results are unexpected. Wondering if anyone can seen anyting im doing terrible wrong here or can improve on.

public static class PlanetGraphUtils
{

    #region Interface

    public interface IFilter<T>
    {
        bool IsDone(int index);
        bool InFilter(int index);
        void SetOutput(int srcIndex, int destIndex);

    }
  
    public interface IPlanetFilter<T> : IFilter<T>
    {
        int GetVerticesLength();
      
        int GetTriangleLength();
    }
  
    #endregion

  
    #region Utills

    static int GetGraphVerticesLength(  [ReadOnly] ref BlobAssetReference<PlanetGraphData> graph)
    {
        return graph.Value.Vertices.Length;
    }
  
    static int GetGraphTriangleLength(  [ReadOnly] ref BlobAssetReference<PlanetGraphData> graph)
    {
        return graph.Value.Triangles.Length;
    }
  
    static float3 GetGraphVertexPosition( [ReadOnly] ref BlobAssetReference<PlanetGraphData> graph, int index)
    {
        return new float3(
            graph.Value.Vertices[index].PositionX,
            graph.Value.Vertices[index].PositionY,
            graph.Value.Vertices[index].PositionZ);
    }

    #endregion

  
    #region Filters

    public struct GraphFilerByDot : IPlanetFilter<int>
    {
        public BlobAssetReference<PlanetGraphData> GraphInput;
        [ReadOnly] public float3 VectorNormalized;
        [ReadOnly] public float Tolerance;
        [WriteOnly] public NativeQueue<int> Output;

        public bool IsDone(int index)
        {
            return index >= GetGraphVerticesLength(ref GraphInput);
        }

        public bool InFilter(int index)
        {
            float3 v1 = GetGraphVertexPosition(ref GraphInput, index);
            var d = math.dot(math.normalize(v1), VectorNormalized);
            return d > Tolerance;
        }

        public void SetOutput(int srcIndex, int destIndex)
        {
            Output.Enqueue(srcIndex);
        }

        public int GetVerticesLength()
        {
            return GetGraphTriangleLength(ref GraphInput);
        }

        public int GetTriangleLength()
        {
            return GetGraphTriangleLength(ref GraphInput);
        }
    }
  

    #endregion


    #region Jobs

    [BurstCompile]
    public struct JobFilterGraph<T, TFilter> : IJob
        where T : struct
        where TFilter : IFilter<T>
    {
        public TFilter FilterJob;

        public void Execute()
        {
            for (int i = 0; !FilterJob.IsDone(i); ++i)
            {
                if (FilterJob.InFilter(i))
                {
                    FilterJob.SetOutput(i, i);
                }
            }

        }
    }
  
    #endregion
}
new PlanetGraphUtils.JobFilterGraph<int, PlanetGraphUtils.GraphFilerByDot>
{
    FilterJob = new PlanetGraphUtils.GraphFilerByDot
    {
        GraphInput = g.PlanetGraph,
        VectorNormalized = math.normalize(_los),
        Tolerance = UpdateFocus,
        Output = triangleToBuild,
    }
}.Run();

Iā€™m in a similar situation.

You need to use JobProducerType, see this post

I have to be honest, this feels like a massive limitation. Having to do a bunch of source-code digging and custom boilerplate to avoid having tons of copies of a piece of code is a terrible workflow. =/

2 Likes

It would be nice to have a simple explanation of what JobProducerTypeAttribute is, and how it should be used.

2 Likes