您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
573 行
20 KiB
573 行
20 KiB
<#/*THIS IS A T4 FILE - see t4_text_templating.md for what it is and how to run codegen*/#>
|
|
<#@ assembly name="System.Collections" #>
|
|
<#@ assembly name="System.Core" #>
|
|
<#@ assembly name="System.Linq" #>
|
|
<#@ import namespace="System.Collections.Generic" #>
|
|
<#@ import namespace="System.Linq" #>
|
|
<#@ import namespace="System.Text" #>
|
|
<#@ output extension=".gen.cs" #>
|
|
//------------------------------------------------------------------------------
|
|
// <auto-generated>
|
|
// This code was generated by a tool.
|
|
//
|
|
// Changes to this file may cause incorrect behavior and will be lost if
|
|
// the code is regenerated.
|
|
// </auto-generated>
|
|
//------------------------------------------------------------------------------
|
|
// Generated by T4 (TextTransform.exe) from the file IJobForEach.tt
|
|
//
|
|
|
|
using Unity.Collections;
|
|
using Unity.Collections.LowLevel.Unsafe;
|
|
using Unity.Jobs;
|
|
using Unity.Jobs.LowLevel.Unsafe;
|
|
using System.Runtime.InteropServices;
|
|
using UnityEngine.Scripting;
|
|
using System;
|
|
|
|
namespace Unity.Entities
|
|
{
|
|
|
|
<#
|
|
var basicCombinations = GenCombinations();
|
|
foreach(var combination in basicCombinations) {
|
|
foreach (var withEntity in new[] { false, true }) {
|
|
if(combination[0] == Category.B)
|
|
continue;
|
|
var comboString = GetComboString(withEntity, combination);
|
|
var name = GetName(withEntity, comboString);
|
|
#>
|
|
<#=BasicInterface(combination, withEntity, comboString)#>
|
|
|
|
<#
|
|
}
|
|
}
|
|
#>
|
|
|
|
<#
|
|
var combinations = GenCombinations();
|
|
foreach(var combination in combinations) {
|
|
foreach (var withEntity in new[] { false, true }) {
|
|
var comboString = GetComboString(withEntity, combination);
|
|
#>
|
|
<#=Interface(combination, withEntity, comboString)#>
|
|
|
|
<#
|
|
}
|
|
}
|
|
#>
|
|
|
|
public static partial class JobForEachExtensions
|
|
{
|
|
<#
|
|
string[] funcNames = new string[]{"Schedule", "ScheduleSingle", "Run"};
|
|
int [] forEachVals = new int[]{1, -1, -1};
|
|
string[] scheduleMode = new string[]{"ScheduleMode.Batched", "ScheduleMode.Batched", "ScheduleMode.Run"};
|
|
for(int i=0; i<funcNames.Length; ++i) {
|
|
#>
|
|
#if !UNITY_DOTSPLAYER
|
|
public static JobHandle <#=funcNames[i]#><T>(this T jobData, ComponentSystemBase system, JobHandle dependsOn = default(JobHandle))
|
|
where T : struct, IBaseJobForEach
|
|
{
|
|
var typeT = typeof(T);
|
|
<#
|
|
foreach(var combination in combinations) {
|
|
var comboStringD = GetComboString(false, combination);
|
|
var comboStringE = GetComboString(true, combination);
|
|
#>
|
|
if (typeof(IBaseJobForEach_<#=comboStringD#>).IsAssignableFrom(typeT))
|
|
return ScheduleInternal_<#=comboStringD#>(ref jobData, system, null, <#=forEachVals[i]#>, dependsOn, <#=scheduleMode[i]#>);
|
|
if (typeof(IBaseJobForEach_<#=comboStringE#>).IsAssignableFrom(typeT))
|
|
return ScheduleInternal_<#=comboStringE#>(ref jobData, system, null, <#=forEachVals[i]#>, dependsOn, <#=scheduleMode[i]#>);
|
|
<#
|
|
}
|
|
#>
|
|
throw new System.ArgumentException("Not supported");
|
|
}
|
|
#endif
|
|
<#
|
|
}
|
|
#>
|
|
|
|
<#
|
|
string[] groupFuncNames = new string[]{"Schedule", "ScheduleSingle", "Run"};
|
|
for(int i=0; i<funcNames.Length; ++i) {
|
|
#>
|
|
#if !UNITY_DOTSPLAYER
|
|
public static JobHandle <#=groupFuncNames[i]#><T>(this T jobData, EntityQuery query, JobHandle dependsOn = default(JobHandle))
|
|
where T : struct, IBaseJobForEach
|
|
{
|
|
var typeT = typeof(T);
|
|
<#
|
|
foreach(var combination in combinations) {
|
|
var comboStringD = GetComboString(false, combination);
|
|
var comboStringE = GetComboString(true, combination);
|
|
#>
|
|
if (typeof(IBaseJobForEach_<#=comboStringD#>).IsAssignableFrom(typeT))
|
|
return ScheduleInternal_<#=comboStringD#>(ref jobData, null, query, <#=forEachVals[i]#>, dependsOn, <#=scheduleMode[i]#>);
|
|
if (typeof(IBaseJobForEach_<#=comboStringE#>).IsAssignableFrom(typeT))
|
|
return ScheduleInternal_<#=comboStringE#>(ref jobData, null, query, <#=forEachVals[i]#>, dependsOn, <#=scheduleMode[i]#>);
|
|
<#
|
|
}
|
|
#>
|
|
throw new System.ArgumentException("Not supported");
|
|
}
|
|
#endif
|
|
<#
|
|
}
|
|
#>
|
|
|
|
<#
|
|
foreach(var combination in combinations) {
|
|
foreach (var withEntity in new[] { false, true }) {
|
|
var comboString = GetComboString(withEntity, combination);
|
|
var untypedGenericParams = new StringBuilder();
|
|
var genericParams = new StringBuilder();
|
|
var genericConstraints = GenericConstraints(combination);
|
|
|
|
var executeParams = ExecuteParams(withEntity, combination);
|
|
var executeCallParams = ExecuteCallParams(withEntity, combination);
|
|
var ptrs = DataAccessors(withEntity, combination);
|
|
var typeLookupCache = new StringBuilder();
|
|
|
|
var interfaceName = GetName(withEntity, comboString);
|
|
|
|
for (int i = 0; i != combination.Length; i++)
|
|
{
|
|
|
|
typeLookupCache.AppendLine($@" var typeLookupCache{i} = 0;");
|
|
|
|
untypedGenericParams.Append(",");
|
|
|
|
genericParams.Append($"T{i}");
|
|
if (i != combination.Length - 1)
|
|
genericParams.Append(", ");
|
|
}
|
|
#>
|
|
#if !UNITY_DOTSPLAYER
|
|
internal static unsafe JobHandle ScheduleInternal_<#=comboString#><T>(ref T jobData, ComponentSystemBase system, EntityQuery query, int innerloopBatchCount, JobHandle dependsOn, ScheduleMode mode)
|
|
where T : struct
|
|
{
|
|
JobStruct_ProcessInfer_<#=comboString#><T> fullData;
|
|
fullData.Data = jobData;
|
|
|
|
var isParallelFor = innerloopBatchCount != -1;
|
|
Initialize(system, query, typeof(T), typeof(JobStruct_Process_<#=comboString#><<#=untypedGenericParams#>>), isParallelFor, ref JobStruct_ProcessInfer_<#=comboString#><T>.Cache, out fullData.Iterator);
|
|
|
|
var unfilteredChunkCount = fullData.Iterator.m_Length;
|
|
var iterator = JobStruct_ProcessInfer_<#=comboString#><T>.Cache.EntityQuery.GetComponentChunkIterator();
|
|
|
|
var prefilterHandle = ComponentChunkIterator.PreparePrefilteredChunkLists(unfilteredChunkCount, iterator.m_MatchingArchetypeList, iterator.m_Filter, dependsOn, mode, out fullData.PrefilterData, out var deferredCountData);
|
|
|
|
return Schedule(UnsafeUtility.AddressOf(ref fullData), fullData.PrefilterData, fullData.Iterator.m_Length, innerloopBatchCount, isParallelFor, iterator.RequiresFilter(), ref JobStruct_ProcessInfer_<#=comboString#><T>.Cache, deferredCountData, prefilterHandle, mode);
|
|
}
|
|
#endif
|
|
|
|
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
|
public interface IBaseJobForEach_<#=comboString#> : IBaseJobForEach {}
|
|
|
|
#if !UNITY_DOTSPLAYER
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
private struct JobStruct_ProcessInfer_<#=comboString#><T> where T : struct
|
|
{
|
|
public static JobForEachCache Cache;
|
|
|
|
public ProcessIterationData Iterator;
|
|
public T Data;
|
|
|
|
[DeallocateOnJobCompletion]
|
|
[NativeDisableContainerSafetyRestriction]
|
|
public NativeArray<byte> PrefilterData;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
internal struct JobStruct_Process_<#=comboString#><T, <#=genericParams#>>
|
|
where T : struct, <#=interfaceName#><<#=genericParams#>>
|
|
<#
|
|
foreach(var constraint in genericConstraints){
|
|
#>
|
|
<#=constraint#>
|
|
<#
|
|
}
|
|
#>
|
|
{
|
|
public ProcessIterationData Iterator;
|
|
public T Data;
|
|
|
|
[DeallocateOnJobCompletion]
|
|
[NativeDisableContainerSafetyRestriction]
|
|
public NativeArray<byte> PrefilterData;
|
|
|
|
[Preserve]
|
|
public static IntPtr Initialize(JobType jobType)
|
|
{
|
|
return JobsUtility.CreateJobReflectionData(typeof(JobStruct_Process_<#=comboString#><T, <#=genericParams#>>), typeof(T), jobType, (ExecuteJobFunction) Execute);
|
|
}
|
|
|
|
delegate void ExecuteJobFunction(ref JobStruct_Process_<#=comboString#><T, <#=genericParams#>> data, IntPtr additionalPtr, IntPtr bufferRangePatchData, ref JobRanges ranges, int jobIndex);
|
|
|
|
public static unsafe void Execute(ref JobStruct_Process_<#=comboString#><T, <#=genericParams#>> jobData, IntPtr additionalPtr, IntPtr bufferRangePatchData, ref JobRanges ranges, int jobIndex)
|
|
{
|
|
ComponentChunkIterator.UnpackPrefilterData(jobData.PrefilterData, out var chunks, out var entityIndices, out var chunkCount);
|
|
|
|
if (jobData.Iterator.m_IsParallelFor)
|
|
{
|
|
int begin, end;
|
|
while (JobsUtility.GetWorkStealingRange(ref ranges, jobIndex, out begin, out end))
|
|
ExecuteChunk(ref jobData, bufferRangePatchData, begin, end, chunks, entityIndices);
|
|
}
|
|
else
|
|
{
|
|
ExecuteChunk(ref jobData, bufferRangePatchData, 0, chunkCount, chunks, entityIndices);
|
|
}
|
|
}
|
|
|
|
static unsafe void ExecuteChunk(ref JobStruct_Process_<#=comboString#><T, <#=genericParams#>> jobData, IntPtr bufferRangePatchData, int begin, int end, ArchetypeChunk* chunks, int* entityIndices)
|
|
{
|
|
<#=typeLookupCache#>
|
|
for (var blockIndex = begin; blockIndex != end; ++blockIndex)
|
|
{
|
|
var chunk = chunks[blockIndex];
|
|
int beginIndex = entityIndices[blockIndex];
|
|
var count = chunk.Count;
|
|
#if ENABLE_UNITY_COLLECTIONS_CHECKS
|
|
JobsUtility.PatchBufferMinMaxRanges(bufferRangePatchData, UnsafeUtility.AddressOf(ref jobData), beginIndex, beginIndex + count);
|
|
#endif
|
|
<#=ptrs#>
|
|
|
|
for (var i = 0; i != count; i++)
|
|
{
|
|
jobData.Data.Execute(<#=executeCallParams#>);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
<#
|
|
}
|
|
}
|
|
#>
|
|
|
|
#if UNITY_DOTSPLAYER
|
|
<#
|
|
foreach(var combination in combinations) {
|
|
foreach (var withEntity in new[] { false, true }) {
|
|
var comboString = GetComboString(withEntity, combination);
|
|
var isBuffer = comboString.Contains("B");
|
|
if(isBuffer)
|
|
continue;
|
|
|
|
var interfaceName = GetName(withEntity, comboString);
|
|
var addFunctionName = withEntity ? "E" : "";
|
|
var genericTypes = "<" + Series("T{0}", combination.Length, ", ") + ">";
|
|
var genericTypesWithJob = "<TJob, " + Series("T{0}", combination.Length, ", ") + ">";
|
|
for(int bits=0; bits < (1 << combination.Length); ++bits) {
|
|
var accessID = "";
|
|
bool[] readOnly = new bool[combination.Length];
|
|
for(int i=0; i<combination.Length; ++i) {
|
|
if ((bits & (1<<i)) != 0) {
|
|
accessID += isBuffer ? "wB" : "wD";
|
|
readOnly[i] = false;
|
|
}
|
|
else {
|
|
accessID += isBuffer ? "rB" : "rD";
|
|
readOnly[i] = true;
|
|
}
|
|
}
|
|
|
|
// See "Code-Gen of Schedule()" IJobForEach.cs for an explanation of the code-gen steps and how this works.
|
|
#>
|
|
internal unsafe static JobHandle Schedule_Query_<#=(addFunctionName + accessID)#><#=genericTypesWithJob#>(this TJob job, EntityQuery query, JobHandle dependsOn = default(JobHandle))
|
|
where TJob : struct, <#=interfaceName#><#=genericTypes#>
|
|
<#
|
|
var genericConstraints = GenericConstraints(combination);
|
|
foreach(var constraint in genericConstraints){
|
|
#>
|
|
<#=constraint#>
|
|
<# } #>
|
|
{
|
|
<# if (withEntity) {#>
|
|
ArchetypeChunkEntityType entityType = World.Active.EntityManager.GetArchetypeChunkEntityType();
|
|
<# }#>
|
|
<# if(!isBuffer){ #>
|
|
<# for(var i=0; i<combination.Length; ++i) {#>
|
|
ArchetypeChunkComponentType<T<#=i#>> chunkComponentType<#=i#> = World.Active.EntityManager.GetArchetypeChunkComponentType<T<#=i#>>(<#=(readOnly[i] ? "true" : "false")#>);
|
|
<# }#>
|
|
<# }else{ #>
|
|
<# for(var i=0; i<combination.Length; ++i) {#>
|
|
ArchetypeChunkBufferType<T<#=i#>> chunkBufferType<#=i#> = World.Active.EntityManager.GetArchetypeChunkBufferType<T<#=i#>>(<#=(readOnly[i] ? "true" : "false")#>);
|
|
<# }#>
|
|
<# } #>
|
|
|
|
using (var chunks = query.CreateArchetypeChunkArray(Allocator.TempJob))
|
|
{
|
|
foreach (var chunk in chunks)
|
|
{
|
|
<# if (withEntity) {#>
|
|
var entityArray = (Entity*)chunk.GetNativeArray(entityType).GetUnsafeReadOnlyPtr();
|
|
<# }#>
|
|
<# if (!isBuffer){ #>
|
|
<# for(var i=0; i<combination.Length; ++i) {#>
|
|
var array<#=i#> = chunk.GetNativeArray(chunkComponentType<#=i#>).<#=(readOnly[i] ? "GetUnsafeReadOnlyPtr()" : "GetUnsafePtr()")#>;
|
|
<# }#>
|
|
<# } else { #>
|
|
<# for(var i=0; i<combination.Length; ++i) {#>
|
|
var array<#=i#> = chunk.GetBufferAccessor(chunkBufferType<#=i#>);
|
|
<# }#>
|
|
<# } #>
|
|
for (int i = 0, count = chunk.Count; i < count; ++i)
|
|
job.Execute(
|
|
<# if (withEntity) { #>
|
|
entityArray[i], entityArray[i].Index,
|
|
<# }#>
|
|
<# if(!isBuffer) { #>
|
|
<# for(int i=0; i<combination.Length; ++i) {#>
|
|
ref UnsafeUtilityEx.ArrayElementAsRef<T<#=i#>>(array<#=i#>, i)<#=(i < combination.Length - 1 ? "," : "")#>
|
|
<# }#>
|
|
<# } else { #>
|
|
<# for(int i=0; i<combination.Length; ++i) {#>
|
|
array<#=i#>[i]<#=(i < combination.Length - 1 ? "," : "")#>
|
|
<# }#>
|
|
<# } #>
|
|
);
|
|
}
|
|
}
|
|
DoDeallocateOnJobCompletion(job);
|
|
return new JobHandle();
|
|
}
|
|
|
|
<#
|
|
}
|
|
}
|
|
}
|
|
#>
|
|
#endif
|
|
}
|
|
}
|
|
|
|
<#+
|
|
// keep these alphabetical as a general rule
|
|
enum Category
|
|
{
|
|
B, // IBufferElementData
|
|
C // IComponentData
|
|
}
|
|
|
|
List<Category[]> GenCombinations()
|
|
{
|
|
var combinations = new List<Category[]>();
|
|
|
|
var categories = Enum.GetValues(typeof(Category));
|
|
|
|
for(int combinationLength = 1; combinationLength <= 6; ++combinationLength)
|
|
{
|
|
for(int numBs = 0; numBs <= combinationLength; ++numBs)
|
|
{
|
|
var array = new Category[combinationLength];
|
|
|
|
for(int i = 0; i < numBs; ++i)
|
|
{
|
|
array[i] = Category.B;
|
|
}
|
|
|
|
var numCs = combinationLength - numBs;
|
|
for(int i = 0; i < numCs; ++i)
|
|
{
|
|
array[numBs + i] = Category.C;
|
|
}
|
|
|
|
combinations.Add(array);
|
|
}
|
|
|
|
}
|
|
|
|
return combinations;
|
|
}
|
|
|
|
string GetComboString(bool withEntity, Category[] combination)
|
|
{
|
|
var baseType = new StringBuilder();
|
|
|
|
if (withEntity)
|
|
baseType.Append("E");
|
|
foreach (var c in combination)
|
|
baseType.Append(Enum.GetName(typeof(Category), c));
|
|
return baseType.ToString();
|
|
}
|
|
|
|
string GetName(bool withEntity, string comboString)
|
|
{
|
|
var name = new StringBuilder();
|
|
|
|
name.Append("IJobForEach");
|
|
if (withEntity)
|
|
name.Append("WithEntity");
|
|
|
|
name.Append("_");
|
|
name.Append(comboString);
|
|
|
|
return name.ToString();
|
|
}
|
|
|
|
string GetUntypedGenericParams(Category[] combination) {
|
|
return new String(',', combination.Length);
|
|
}
|
|
|
|
string GenericParams(Category[] combination) {
|
|
StringBuilder genericParams = new StringBuilder();
|
|
for(int i=0; i<combination.Length; ++i) {
|
|
genericParams.Append($"T{i}");
|
|
if (i != combination.Length - 1)
|
|
genericParams.Append(", ");
|
|
}
|
|
return genericParams.ToString();
|
|
}
|
|
|
|
string[] _GenericConstraints =
|
|
{
|
|
"where T{0} : struct, IBufferElementData", // IBufferElementData
|
|
"where T{0} : struct, IComponentData", // ref ComponentData
|
|
};
|
|
|
|
IEnumerable<string> GenericConstraints(Category[] categories) =>
|
|
categories.Select((c, i) => string.Format(_GenericConstraints[(int)c], i));
|
|
|
|
string ExecuteParams(bool withEntity, Category[] combination)
|
|
{
|
|
var executeParams = new StringBuilder();
|
|
if (withEntity) {
|
|
executeParams.Append("Entity entity, int index, ");
|
|
}
|
|
for(int i=0; i<combination.Length; ++i)
|
|
{
|
|
if(combination[i] == Category.C)
|
|
executeParams.Append($"ref T{i} c{i}");
|
|
else if(combination[i] == Category.B)
|
|
executeParams.Append($"DynamicBuffer<T{i}> b{i}");
|
|
|
|
if (i != combination.Length - 1)
|
|
executeParams.Append(", ");
|
|
}
|
|
return executeParams.ToString();
|
|
}
|
|
|
|
string ExecuteCallParams(bool withEntity, Category[] combination)
|
|
{
|
|
var callParams = new StringBuilder();
|
|
|
|
if (withEntity)
|
|
{
|
|
callParams.Append($"ptrE[i], i + beginIndex, ");
|
|
}
|
|
|
|
for(int i=0; i<combination.Length; ++i)
|
|
{
|
|
if(combination[i] == Category.C)
|
|
callParams.Append($"ref UnsafeUtilityEx.ArrayElementAsRef<T{i}>(ptr{i}, i)");
|
|
else if(combination[i] == Category.B)
|
|
callParams.Append($"buffer{i}[i]");
|
|
|
|
if (i != combination.Length - 1)
|
|
callParams.Append(", ");
|
|
}
|
|
return callParams.ToString();
|
|
}
|
|
|
|
string DataAccessors(bool withEntity, Category[] combination)
|
|
{
|
|
var accessors = new StringBuilder();
|
|
|
|
if (withEntity)
|
|
{
|
|
accessors.AppendLine
|
|
(
|
|
$" var ptrE = (Entity*)UnsafeUtilityEx.RestrictNoAlias(ComponentChunkIterator.GetChunkComponentDataPtr(chunk.m_Chunk, false, 0, jobData.Iterator.GlobalSystemVersion));"
|
|
);
|
|
}
|
|
|
|
for (int i = 0; i != combination.Length; i++)
|
|
{
|
|
accessors.AppendLine($" ChunkDataUtility.GetIndexInTypeArray(chunk.m_Chunk->Archetype, jobData.Iterator.TypeIndex{i}, ref typeLookupCache{i});" );
|
|
}
|
|
|
|
bool insertSafetyChecks = (combination[0] == Category.B);
|
|
if(insertSafetyChecks)
|
|
accessors.AppendLine($@"#if ENABLE_UNITY_COLLECTIONS_CHECKS");
|
|
|
|
int numBs = 0;
|
|
for(;numBs < combination.Length; ++numBs)
|
|
{
|
|
if(combination[numBs] != Category.B)
|
|
break;
|
|
|
|
accessors.AppendLine($@" var buffer{numBs} = ComponentChunkIterator.GetChunkBufferAccessor<T{numBs}>(chunk.m_Chunk, jobData.Iterator.IsReadOnly{numBs} == 0, typeLookupCache{numBs}, jobData.Iterator.GlobalSystemVersion, jobData.Iterator.m_Safety{numBs}, jobData.Iterator.m_BufferSafety{numBs});");
|
|
}
|
|
|
|
if(insertSafetyChecks)
|
|
accessors.AppendLine("#else");
|
|
|
|
for(int i = 0; i < numBs; ++i)
|
|
accessors.AppendLine($@" var buffer{i} = ComponentChunkIterator.GetChunkBufferAccessor<T{i}>(chunk.m_Chunk, jobData.Iterator.IsReadOnly{i} == 0, typeLookupCache{i}, jobData.Iterator.GlobalSystemVersion);");
|
|
|
|
if(insertSafetyChecks)
|
|
accessors.AppendLine("#endif");
|
|
|
|
int numCs = combination.Length - numBs;
|
|
for(int i = numBs; i < combination.Length; ++i)
|
|
{
|
|
accessors.AppendLine($@" var ptr{i} = UnsafeUtilityEx.RestrictNoAlias(ComponentChunkIterator.GetChunkComponentDataPtr(chunk.m_Chunk, jobData.Iterator.IsReadOnly{i} == 0, typeLookupCache{i}, jobData.Iterator.GlobalSystemVersion));");
|
|
}
|
|
|
|
return accessors.ToString();
|
|
}
|
|
|
|
string Interface( Category[] combination, bool withEntity, string comboString )
|
|
{
|
|
var name = GetName(withEntity, comboString);
|
|
var interfaceDec = new StringBuilder();
|
|
|
|
interfaceDec.Append(
|
|
$@"#if !UNITY_ZEROPLAYER
|
|
[JobProducerType(typeof(JobForEachExtensions.JobStruct_Process_{comboString}<{GetUntypedGenericParams(combination)}>))]
|
|
#endif
|
|
public interface {name}<{GenericParams(combination)}> : JobForEachExtensions.IBaseJobForEach_{comboString}
|
|
");
|
|
|
|
var genericConstraints = GenericConstraints(combination);
|
|
foreach(var constraint in genericConstraints)
|
|
{
|
|
interfaceDec.AppendLine(" " + constraint);
|
|
}
|
|
|
|
interfaceDec.Append($@" {{
|
|
void Execute({ExecuteParams(withEntity, combination)});
|
|
}}");
|
|
return interfaceDec.ToString();
|
|
}
|
|
|
|
string BasicInterface( Category[] combination, bool withEntity, string comboString )
|
|
{
|
|
var name = withEntity ? "IJobForEachWithEntity" : "IJobForEach";
|
|
var interfaceDec = new StringBuilder();
|
|
|
|
interfaceDec.AppendLine(
|
|
$@"#if !UNITY_ZEROPLAYER
|
|
[JobProducerType(typeof(JobForEachExtensions.JobStruct_Process_{comboString}<{GetUntypedGenericParams(combination)}>))]
|
|
#endif
|
|
public interface {name}<{GenericParams(combination)}> : {name}_{comboString}<{GenericParams(combination)}>");
|
|
|
|
var genericConstraints = GenericConstraints(combination);
|
|
foreach(var constraint in genericConstraints)
|
|
{
|
|
interfaceDec.AppendLine(" " + constraint);
|
|
}
|
|
|
|
interfaceDec.Append($@" {{}}");
|
|
return interfaceDec.ToString();
|
|
}
|
|
|
|
static string Series(string formatString, int count, string separator) =>
|
|
string.Join(separator, Enumerable.Range(0, count).Select(i => string.Format(formatString, i)));
|
|
|
|
#>
|