<#@ template language="C#" #> <#@ output extension="gen.cs" #> <#@ assembly name="System.Core" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ include file="Helpers.ttinclude" #> using Ghost.Core; namespace Ghost.Entities; public unsafe partial struct EntityQuery { <# for (var f = 0; f < 2; f++) { var isForEachWithEntity = f != 0; #> <# for (var i = 1; i <= Amount; i++) { var generics = AppendParameters(i, "T{0}"); var restrictions = AppendGenericRestrictionsMultiline(i, "unmanaged, IComponent", 2); var delegateTupe = isForEachWithEntity ? "ForEachWithEntity" : "ForEach"; #> public readonly void ForEach<<#= generics #>>(<#= delegateTupe #><<#= generics #>> action) <#= restrictions #> { var world = World.GetWorld(_worldID).GetValueOrThrow(); var compTypeIDs = stackalloc int[] { <#= AppendGenerics(i, "ComponentTypeID.value") #> }; var offsets = stackalloc int[<#= i #>]; var basePtrs = stackalloc byte*[<#= i #>]; for (var i = 0; i < _matchingArchetypes.Count; i++) { ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]); var hasAllComponents = true; for (var index = 0; index < <#= i #>; index++) { var layoutResult = archetype.GetLayout(compTypeIDs[index]); if (!layoutResult) { hasAllComponents = false; break; } offsets[index] = layoutResult.Value.offset; } if (!hasAllComponents) { continue; } for (var chunkIndex = 0; chunkIndex < archetype.ChunkCount; chunkIndex++) { ref var chunk = ref archetype.GetChunkReference(chunkIndex); var pChunkData = chunk.GetUnsafePtr(); for (var index = 0; index < <#= i #>; index++) { basePtrs[index] = pChunkData + offsets[index]; } for (var entityIndex = 0; entityIndex < chunk.Count; entityIndex++) { if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask)) { continue; } <# for (var localIndex = 0; localIndex < i; localIndex++) { #> var pComp<#= localIndex #> = (T<#= localIndex #>*)(basePtrs[<#= localIndex #>] + (sizeof(T<#= localIndex #>) * entityIndex)); <# } #> <# if (isForEachWithEntity) { #> var pEntity = (Entity*)(pChunkData + archetype.EntityIDsOffset + (sizeof(Entity) * entityIndex)); action(*pEntity, <#= AppendParameters(i, "ref *pComp{0}") #>); <# } else { #> action(<#= AppendParameters(i, "ref *pComp{0}") #>); <# } #> } } } } <# } #> <# } #> }