Boat Attack使用了Universal RP的许多新图形功能,可以用于探索 Universal RP 的使用方式和技巧。
您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

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)));
#>