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

409 行
15 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" #>
<#@ 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>
//------------------------------------------------------------------------------
<# var combinations = InitCombinations(); #>
// Generated by EntityQueryBuilder.tt (<#=combinations.Count * 2 - 1#> `foreach` combinations)
using System;
using System.ComponentModel;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Jobs;
namespace Unity.Entities
{
public partial struct EntityQueryBuilder
{
<#
foreach (var categories in combinations) {
foreach (var hasEntity in new[] { true, false }) {
if (!categories.Any() && !hasEntity)
continue;
var mappedCategories = categories.Select((c, i) => (c: (int)c, i: i));
var delegateName = GetDelegateName(categories, hasEntity);
var delegateParameters = GetDelegateParameters(categories, hasEntity);
var genericTypes = categories.Any() ? ("<" + Series("T{0}", categories.Length, ", ") + ">") : "";
var genericTypesWithJob = "<TJob" + (categories.Any() ? (", " + Series("T{0}", categories.Length, ", ")) : "") + ">";
var genericConstraints = GetGenericConstraints(categories);
var actionParams = GetActionParams(categories, hasEntity);
#>
public delegate void <#=delegateName#><#=genericTypes#>(<#=delegateParameters#>)<#=categories.Any() ? "" : ";"#>
<# foreach (var constraint in Smart(genericConstraints)) {#>
<#=constraint.Value#><#=constraint.IfLast(";")#>
<# }#>
public unsafe void ForEach<#=genericTypes#>(<#=delegateName#><#=genericTypes#> action)
<# foreach (var constraint in genericConstraints) {#>
<#=constraint#>
<# }#>
{
#if ENABLE_UNITY_COLLECTIONS_CHECKS
using (InsideForEach())
#endif
{
var query = m_Query;
if (query == null)
{
<# if (categories.Any()) {#>
var delegateTypes = stackalloc[]
{
<# foreach (var (c, i) in mappedCategories) { #>
TypeManager.GetTypeIndex<T<#=i#>>(),
<# }#>
};
<# }#>
query = ResolveEntityQuery(<#=categories.Any() ? "delegateTypes" : "null"#>, <#=categories.Length#>);
}
<# if (hasEntity) {#>
var entityType = m_System.GetArchetypeChunkEntityType();
<# }#>
<# foreach (var (c, i) in mappedCategories) {#>
var chunkComponentType<#=i#> = m_System.<#=AccessFunction[c]#><T<#=i#>>(<#=IsReadOnly[c]#>);
<# }#>
using (var chunks = query.CreateArchetypeChunkArray(Allocator.TempJob))
{
foreach (var chunk in chunks)
{
<# foreach (var (c, i) in mappedCategories) {#>
var array<#=i#> = chunk.<#=string.Format(ChunkGetArray[c], i)#>;
<# }#>
<# if (hasEntity) {#>
var entityArray = (Entity*)chunk.GetNativeArray(entityType).GetUnsafeReadOnlyPtr();
<# }#>
for (int i = 0, count = chunk.Count; i < count; ++i)
action(<#=actionParams#>);
}
}
}
}
<#}}#>
}
// Schedule() implementation for DOTS-standalone.
// The IDE calls Schedule(), and then code-gen is used to
// replace the call to the correct Schedule_D method, With
// known types.
#if UNITY_DOTSPLAYER
public static partial class JobForEachExtensions
{
<#
string GetScheduleParams(Category[] categories, bool hasEntity)
{
var parts = categories.Select((c, i) => string.Format(ArrayAccess[(int)c], i));
if (hasEntity) {
parts = parts.Prepend("entityArray[i].Index");
parts = parts.Prepend("entityArray[i]");
}
return string.Join(", ", parts);
}
foreach (var categories in combinations) {
foreach (var hasEntity in new[] { false, true }) {
if (!categories.Any())
continue;
var mappedCategories = categories.Select((c, i) => (c: (int)c, i: i));
var delegateName = GetDelegateName(categories, hasEntity);
var delegateParameters = GetDelegateParameters(categories, hasEntity);
var genericTypes = categories.Any() ? ("<" + Series("T{0}", categories.Length, ", ") + ">") : "";
var genericTypesWithJob = "<TJob" + (categories.Any() ? (", " + Series("T{0}", categories.Length, ", ")) : "") + ">";
var genericConstraints = GetGenericConstraints(categories);
var actionParams = GetScheduleParams(categories, hasEntity);
var dName = (hasEntity ? "E" : "") + Series("D", categories.Length, "");
var jobInterface = hasEntity ? "IJobForEachWithEntity" : "IJobForEach";
// See "Code-Gen of Schedule()" IJobForEach.cs for an explanation of the code-gen steps and how this works.
#>
<# if (categories.Any() && !categories.Any(c => c != Category.D)) { #>
[EditorBrowsable(EditorBrowsableState.Never)]
internal unsafe static void Execute_<#=dName#><#=genericTypesWithJob#>(TJob job, ComponentSystemBase system, EntityQuery query, JobHandle dependsOn = default(JobHandle))
where TJob : struct, <#=jobInterface#><#=genericTypes#>
<# foreach (var constraint in genericConstraints) {#>
<#=constraint#>
<# }#>
{
<# if (hasEntity) {#>
var entityType = system.GetArchetypeChunkEntityType();
<# }#>
<# foreach (var (c, i) in mappedCategories) {#>
var chunkComponentType<#=i#> = system.<#=AccessFunction[c]#><T<#=i#>>(<#=IsReadOnly[c]#>);
<# }#>
using (var chunks = query.CreateArchetypeChunkArray(Allocator.TempJob))
{
foreach (var chunk in chunks)
{
<# foreach (var (c, i) in mappedCategories) {#>
var array<#=i#> = chunk.<#=string.Format(ChunkGetArray[c], i)#>;
<# }#>
<# if (hasEntity) {#>
var entityArray = (Entity*)chunk.GetNativeArray(entityType).GetUnsafeReadOnlyPtr();
<# }#>
for (int i = 0, count = chunk.Count; i < count; ++i)
job.Execute(<#=actionParams#>);
}
}
DoDeallocateOnJobCompletion(job);
}
<#
for(int bits=0; bits < (1 << categories.Length); ++bits) {
var accessID = hasEntity ? "E" : "";
String[] accessName = new String[categories.Length];
for(int i=0; i<categories.Length; ++i) {
if ((bits & (1<<i)) != 0) {
accessID += "wD";
accessName[i] = "ReadWrite";
}
else {
accessID += "rD";
accessName[i] = "ReadOnly";
}
}
#>
<# // See "Code-Gen of Schedule()" IJobForEach.cs for an explanation of the code-gen steps and how this works.
#>
[EditorBrowsable(EditorBrowsableState.Never)]
internal unsafe static JobHandle Schedule_<#=accessID#><#=genericTypesWithJob#>(TJob job, ComponentSystemBase system, JobHandle dependsOn = default(JobHandle))
where TJob : struct, <#=jobInterface#><#=genericTypes#>
<# foreach (var constraint in genericConstraints) {#>
<#=constraint#>
<# }#>
{
{
<# if (categories.Any()) {#>
var delegateTypes = stackalloc ComponentType[<#=categories.Length#>]
{
<# foreach (var (c, i) in mappedCategories) { #>
ComponentType.<#=accessName[i]#><T<#=i#>>(),
<# }#>
};
<# }#>
EntityQuery query = /*ResolveEntityQuery*/system.GetEntityQueryInternal(<#=categories.Any() ? "delegateTypes" : "null"#>, <#=categories.Length#>);
Execute_<#=dName#><#=genericTypesWithJob#>(job, system, query, dependsOn);
}
return new JobHandle();
}
<#
}
#>
<# } #>
<#}}#>
}
#endif // UNITY_DOTSPLAYER
// BACK-COMPAT
public partial class ComponentSystem
{
<#
foreach (var categories in combinations) {
foreach (var hasEntity in new[] { true, false }) {
if (!categories.Any() && !hasEntity)
continue;
var delegateName = GetDelegateName(categories, hasEntity);
var genericTypes = categories.Any() ? ("<" + Series("T{0}", categories.Length, ", ") + ">") : "";
var genericConstraints = GetGenericConstraints(categories);
#>
[System.Obsolete("Call Entities.ForEach() or Entities.With(query).ForEach() instead (RemovedAfter 2019-07-11)")]
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public unsafe void ForEach<#=genericTypes#>(EntityQueryBuilder.<#=delegateName#><#=genericTypes#> action, EntityQuery query = null)
<#=string.Join(" ", genericConstraints)#>
{
var q = Entities;
if (query != null)
q = q.With(query);
q.ForEach(action);
}
<#}}#>
}
} // namespace Unity.Entities
<#+
enum Category
{
// note: 'in' is broken in c# (very easy for user to accidentally cause a copy) so we do not
// include it in the combos we support yet.
D, // ref ComponentData
I, // in ComponentData
C, // class
B, // IBufferElementData
K, // in IBufferElementData
S, // ISharedComponentData
}
static string GetDelegateName(Category[] categories, bool hasEntity)
{
var parts = string.Join("", categories.Select(c => c.ToString()));
return $"F_{(hasEntity ? "E" : "")}{parts}";
}
string[] Param =
{
"ref T{0} d{0}", // ref ComponentData
"in T{0} i{0}", // in ComponentData
"T{0} c{0}", // class
"DynamicBuffer<T{0}> b{0}", // IBufferElementData
"in DynamicBuffer<T{0}> k{0}", // in IBufferElementData
"T{0} s{0}", // ISharedComponentData
};
string[] FwdParam =
{
"ref d{0}", // ref ComponentData
"i{0}", // in ComponentData
"c{0}", // class
"b{0}", // IBufferElementData
"k{0}", // in IBufferElementData
"s{0}", // ISharedComponentData
};
string GetDelegateParameters(Category[] categories, bool hasEntity)
{
var parts = categories.Select((c, i) => string.Format(Param[(int)c], i));
if (hasEntity)
parts = parts.Prepend("Entity entity");
return string.Join(", ", parts);
}
string[] GenericConstraints =
{
"where T{0} : struct, IComponentData", // ref ComponentData
"where T{0} : struct, IComponentData", // in ComponentData
"where T{0} : class", // class
"where T{0} : struct, IBufferElementData", // IBufferElementData
"where T{0} : struct, IBufferElementData", // in IBufferElementData
"where T{0} : struct, ISharedComponentData", // ISharedComponentData
};
IEnumerable<string> GetGenericConstraints(Category[] categories) =>
categories.Select((c, i) => string.Format(GenericConstraints[(int)c], i));
string[] AccessFunction =
{
"GetArchetypeChunkComponentType", // ref ComponentData
"GetArchetypeChunkComponentType", // in ComponentData
"GetArchetypeChunkComponentType", // class
"GetArchetypeChunkBufferType", // IBufferElementData
"GetArchetypeChunkBufferType", // in IBufferElementData
"GetArchetypeChunkSharedComponentType", // ISharedComponentData
};
static string[] IsReadOnly=
{
"false", // ref ComponentData
"true", // in ComponentData
"", // class
"false", // IBufferElementData
"true", // in IBufferElementData
"", // ISharedComponentData
};
string[] ChunkGetArray =
{
"GetNativeArray(chunkComponentType{0}).GetUnsafePtr()", // ref ComponentData
"GetNativeArray(chunkComponentType{0}).GetUnsafeReadOnlyPtr()", // in ComponentData
"GetComponentObjects(chunkComponentType{0}, m_System.EntityManager)", // class
"GetBufferAccessor(chunkComponentType{0})", // IBufferElementData
"GetBufferAccessor(chunkComponentType{0})", // in IBufferElementData
"GetSharedComponentData(chunkComponentType{0}, m_System.EntityManager)", // ISharedComponentData
};
string[] ArrayAccess =
{
"ref UnsafeUtilityEx.ArrayElementAsRef<T{0}>(array{0}, i)", // ref ComponentData
"in UnsafeUtilityEx.ArrayElementAsRef<T{0}>(array{0}, i)", // in ComponentData
"array{0}[i]", // class
"array{0}[i]", // IBufferElementData
"array{0}[i]", // in IBufferElementData
"array{0}", // ISharedComponentData
};
string GetActionParams(Category[] categories, bool hasEntity)
{
var parts = categories.Select((c, i) => string.Format(ArrayAccess[(int)c], i));
if (hasEntity)
parts = parts.Prepend("entityArray[i]");
return string.Join(", ", parts);
}
static List<Category[]> InitCombinations()
{
var combinations = new List<Category[]>();
GetCombinations(new[] { Category.D, Category.C, Category.B, Category.S }, new Category[0], 1);
var baseCount = combinations.Count;
for (int i = 0; i != baseCount; ++i)
GetCombinations(new[] { Category.D }, combinations[i], 5);
for (int i = 0; i != baseCount; ++i)
GetCombinations(new[] { Category.C }, combinations[i], 5);
for (int i = 0; i != baseCount; ++i)
GetCombinations(new[] { Category.B }, combinations[i], 5);
combinations.Insert(0, new Category[0]);
void GetCombinations(Category[] supported, Category[] parent, int depth)
{
for (int i = 0; i != supported.Length; ++i)
{
var categories = new Category[parent.Length + 1];
parent.CopyTo(categories, 0);
categories[categories.Length - 1] = supported[i];
combinations.Add(categories);
if (depth-1 > 0)
GetCombinations(supported, categories, depth-1);
}
}
return combinations;
}
// misc support utils
class SmartElement<T>
{
public T Value;
public int Index;
public int Count;
public bool First => Index == 0;
public bool Last => Index == Count - 1;
public string IfFirst(string text) => First ? text : "";
public string IfLast(string text) => Last ? text : "";
}
static IEnumerable<SmartElement<T>> Smart<T>(IEnumerable<T> items)
{
var list = items.ToList();
for (var i = 0; i < list.Count; ++i)
yield return new SmartElement<T> { Value = list[i], Index = i, Count = list.Count };
}
static string Series(string formatString, int count, string separator) =>
string.Join(separator, Enumerable.Range(0, count).Select(i => string.Format(formatString, i)));
#>