I am working on a Wave Function Collapse Burst Job with the following selling points:
-
Values can be any unmanaged IEquatable
-
Wave can be any struct to that implements IWave (so, it works for 1D, 2D, 3D, and for 4D+ just need to make a new Wave struct)
-
Conditions as generic as can be: Get Wave and position, return changes to be made in that position (eliminate impossible states, change probabilities of states, rescale probabilities so they add to 1). Any number of Conditions.
-
And the part that is giving me headaches: Some Condition Templates to which you may pass certain parameters and it returns to you a delegate that can be used in BurstCompiler.CompileFunctionPointer, so you only need to pass your delegates to a MakeCollapseConditions and it gives you a NativeArray of FunctionPointers
It goes as follows:
[BurstDiscard()]
public static CollapseConditionFunc<T, TWave> Count<T, TWave>(Predicate<T> predicate, int2 sizeAndStateCount, uint times = 1)
where T : unmanaged, IEquatable<T>
where TWave : IWave<T>
{
return (TWave a, int index) => Count<T, TWave, IPredicate<T>>(a, index, new BurstPredicate<T>(predicate), sizeAndStateCount, times);
}
[BurstCompile()]
private static NativeArray<State<T>> Count<T, TWave, TPredicate>(TWave a, int index, TPredicate predicate, int2 sizeAndStateCount, uint times)
where T : unmanaged, IEquatable<T>
where TWave : IWave<T>
where TPredicate : IPredicate<T>
{
// Assume this function body works with Burst
}
That is all inside a Burst static class. As you can see, there is generic delegate, generic interface, and lambda. All stuff that Burst isn’t exactly fond of. Lambda specially.
That is one of the templates, some other templates only work with 2D or 3D Waves specifically (RookConnect, to check if states of neighbooring positions satisfy a Connect() Func, will either only make sense in 2D or 3D, as I cannot implement Neighborhood generically for a N-Dimensional Wave).
Now, I understand that if someone passes a Predicate screws with the code safety, it won’t work. Consider the predicate to be of a function that works with Burst in the first place. (No ref types, has [BurstCompile], etc.)
So, the questions:
1- Is this even possible in the first place? Passing these made-on-the-fly functions to Burst, I mean.
2- Is a lambda of a BurstCompile also Burstable? If not, any other way to do this?
3- What do I actually need to do to make sure what I passing into the Predicate will work with Burst?
4- The bottleneck of the Collapse is on the conditon-checks, I’m pretty sure. Should the whole Collapse be a Job, or should only the conditions be parallel jobs?
5- Anything else I may have grossly overlooked? I cannot even compile the code right now because there are still too many things not done.