public unsafe void ShoudlCopyPtrData() { //arrange using var memory = new DynamicAllocator(_logFactory); var specifcation = new EntitySpec( ComponentType <Position> .Type ); var specIndex = 0; using var chunkArray = new EntityChunkList(_logFactory, memory, specifcation, specIndex); using var entityPool = new EntityPool(_logFactory, memory); var entity = entityPool.TakeRef();; chunkArray.Create(entity); var componentType = stackalloc[] { ComponentType <Position> .Type }; var componentIndex = chunkArray.Specification.GetComponentIndex(*componentType); var span = chunkArray.AllChunks[entity.ChunkIndex].PackedArray.GetComponentData <Position>(); //act var ptr = stackalloc[] { new Position(100, 100), new Position(200, 200), new Position(400, 100), new Position(100, 400) }; var src = (void *)ptr; Span <EntityRef> entityRefs = stackalloc[] { entity }; chunkArray.Copy(specIndex, componentType, ref src, entityRefs, false); //assert span[0].X.ShouldBe(100); span[0].Y.ShouldBe(100); }
public unsafe void ShouldCreateManyEntities() { //arrange using var memory = new DynamicAllocator(_logFactory); var specification = new EntitySpec( ComponentType <Position> .Type, ComponentType <Velocity> .Type ); using var entityChunk = new EntityChunk(_logFactory, memory, specification, 0, 0); using var entityPool = new EntityPool(_logFactory, memory); Span <EntityRef> ids = stackalloc EntityRef[entityChunk.Free + 1]; entityPool.Take(ids); //act var created = entityChunk.Create(ids); //assert entityChunk.Entities[0].ShouldBe(ids[0]); entityChunk.Entities[created - 1].ShouldBe(ids[created - 1]); entityChunk.Count.ShouldBe(created); entityChunk.Free.ShouldBe(0); created.ShouldBe(Entity.ENTITY_MAX); }
public void ShouldDeleteAndMove() { //arrange using var memory = new DynamicAllocator(_logFactory); var specifcation = new EntitySpec( ComponentType <Position> .Type ); using var chunkArray = new EntityChunkList(_logFactory, memory, specifcation, 0); using var entityPool = new EntityPool(_logFactory, memory); var id0 = entityPool.TakeRef(); var id1 = entityPool.TakeRef(); //act chunkArray.Create(id0); chunkArray.Create(id1); var span = chunkArray.AllChunks[0].PackedArray.GetComponentData <Position>(); span[id1.Index] = new Position(10, 20); chunkArray.Delete(id0); //assert span[id0.Index].X.ShouldBe(10); span[id0.Index].Y.ShouldBe(20); }
public void ShouldCreateOneEntity() { //arrange using var memory = new DynamicAllocator(_logFactory); var specification = new EntitySpec( ComponentType <Position> .Type, ComponentType <Velocity> .Type ); using var entityChunk = new EntityChunk(_logFactory, memory, specification, 0, 0); using var entityPool = new EntityPool(_logFactory, memory); var id0 = entityPool.TakeRef(); //act var free = entityChunk.Free; entityChunk.Create(id0); //assert id0.Index.ShouldBe(0); entityChunk.Entities[0].ShouldBe(id0); entityChunk.Count.ShouldBe(1); entityChunk.Free.ShouldBe(free - 1); }
public void ShouldHaveAny() { var spec = new EntitySpec( ComponentType <Valid> .Type, ComponentType <Valid2> .Type, ComponentType <Valid3> .Type, ComponentType <Valid4> .Type ); var valid = new[] { new EntitySpec(ComponentType <Valid> .Type, ComponentType <Valid2> .Type, ComponentType <Valid3> .Type), new EntitySpec(ComponentType <Valid2> .Type, ComponentType <Valid6> .Type, ComponentType <Valid4> .Type), new EntitySpec(ComponentType <Valid> .Type, ComponentType <Valid4> .Type), new EntitySpec(ComponentType <Valid> .Type), new EntitySpec(ComponentType <Valid5> .Type, ComponentType <Valid2> .Type, ComponentType <Valid3> .Type, ComponentType <Valid4> .Type) }; for (var i = 0; i < valid.Length; i++) { spec.HasAny(valid[i]).ShouldBe(true); } var invalid = new[] { new EntitySpec(ComponentType <Valid6> .Type), new EntitySpec(ComponentType <Valid5> .Type), new EntitySpec(ComponentType <Valid6> .Type, ComponentType <Valid5> .Type) }; for (var i = 0; i < invalid.Length; i++) { spec.HasAny(invalid[i]).ShouldBe(false); } }
public void ShouldDeleteOneEntity() { //arrange using var memory = new DynamicAllocator(_logFactory); var specification = new EntitySpec(ComponentType <Position> .Type); using var entityChunk = new EntityChunk(_logFactory, memory, specification, 0, 0); var span = entityChunk.PackedArray.GetComponentData <Position>(0); using var entityPool = new EntityPool(_logFactory, memory); //act span[0] = new Position(1); span[1] = new Position(2); var id0 = entityPool.TakeRef(); var id1 = entityPool.TakeRef(); var free = entityChunk.Free; entityChunk.Create(id0); entityChunk.Create(id1); entityChunk.Delete(id0); //assert entityChunk.Count.ShouldBe(1); entityChunk.Free.ShouldBe(free - 1); //entityChunk.Get(id0).ShouldBe(id1); span[0].ShouldBe(new Position(2)); }
public void ShouldDeleteManyEntities() { using var memory = new HeapAllocator(_logFactory); using var em = new EntityManager(_logFactory, memory); using var buffer = new EntityCommandBuffer(em, memory); var spec = new EntitySpec(ComponentType <Position> .Type, ComponentType <Velocity> .Type); const int samples = 32; var ids = new uint[samples]; em.Create(spec, ids); var idsToDelete = new[] { ids[0], ids[11], ids[22], ids[23], ids[3], ids[2], ids[15], ids[17], ids[29], ids[21] }; buffer.Delete(idsToDelete); buffer.Execute(); em.EntityCount.ShouldBe(samples - idsToDelete.Length); em.EntityArrays[0].EntityCount.ShouldBe(samples - idsToDelete.Length); var entities = em.EntityArrays[0].AllChunks[0].Entities.ToArray(); var remainingIds = entities.Select(x => x.ID).ToArray(); remainingIds.Any(x => idsToDelete.Contains(x)).ShouldBe(false); var otherIds = ids.Where(x => !idsToDelete.Contains(x)).ToArray(); remainingIds.All(x => otherIds.Contains(x)).ShouldBe(true); }
public void ShouldAssignManyWithOne() { using var memory = new HeapAllocator(_logFactory); using var em = new EntityManager(_logFactory, memory); using var buffer = new EntityCommandBuffer(em, memory); var spec = new EntitySpec(ComponentType <Velocity> .Type); var position = new Position(10, 10); const int samples = 32; var ids = new uint[samples]; em.Create(spec, ids); buffer.Assign(ids, position); buffer.Execute(); em.EntityCount.ShouldBe(32); em.EntityArrays.Count.ShouldBe(2); em.EntityArrays[0].EntityCount.ShouldBe(0); em.EntityArrays[1].EntityCount.ShouldBe(32); var positions = ids.Select(id => em.Get <Position>(id)).ToArray(); positions.ShouldAllBe(x => x == position); }
public void ShouldCreateChunkArray() { //arrange using var memory = new DynamicAllocator(_logFactory); var specifcation = new EntitySpec( ComponentType <Position> .Type ); using var chunkArray = new EntityChunkList(_logFactory, memory, specifcation, 0); using var entityPool = new EntityPool(_logFactory, memory); var id0 = entityPool.TakeRef(); var id1 = entityPool.TakeRef(); //act chunkArray.Create(id0); chunkArray.Create(id1); //assert chunkArray.EntityCount.ShouldBe(2); id0.Index.ShouldBe(0); id1.Index.ShouldBe(1); id0.ChunkIndex.ShouldBe(0); id1.ChunkIndex.ShouldBe(0); }
public void ShouldReplaceManyWithMany() { using var memory = new HeapAllocator(_logFactory); using var em = new EntityManager(_logFactory, memory); using var buffer = new EntityCommandBuffer(em, memory); var spec = new EntitySpec(ComponentType <Position> .Type, ComponentType <Velocity> .Type); const int samples = 32; var positions = Enumerable.Range(0, samples).Select(x => new Position(x, 10)).ToArray(); var ids = new uint[samples]; em.Create(spec, ids); buffer.Replace(ids, positions.AsSpan()); buffer.Execute(); em.EntityCount.ShouldBe(32); em.EntityArrays[0].EntityCount.ShouldBe(32); var positionResults = ids.Select(id => em.Get <Position>(id)).ToArray(); positionResults.ShouldBe(positions); }
public unsafe void ShouldCreateManyEntities() { //arrange using var memory = new DynamicAllocator(_logFactory); var specifcation = new EntitySpec(ComponentType <Position> .Type); using var chunkArray = new EntityChunkList(_logFactory, memory, specifcation, 0); using var entityPool = new EntityPool(_logFactory, memory); var entities = new EntityRef[Entity.ENTITY_MAX * 2]; entityPool.Take(entities); //act chunkArray.Create(entities); // //assert // var created = createdEntities.ToArray(); // var first = created.Take(Entity.ENTITY_MAX).ToArray(); // var firstSet = Enumerable.Range(0, Entity.ENTITY_MAX).Select(x => new CreatedEntity(0, x)).ToArray(); // first.ShouldBe(firstSet); // var second = created.Skip(Entity.ENTITY_MAX).Take(Entity.ENTITY_MAX).ToArray(); // var secondSet = Enumerable.Range(0, Entity.ENTITY_MAX).Select(x => new CreatedEntity(1, x)).ToArray(); // second.ShouldBe(secondSet); chunkArray.ChunkCount.ShouldBe(2); chunkArray.EntityCount.ShouldBe(entities.Length); }
public EntityChunkList(ILoggerFactory logFactory, IAllocator allocator, EntitySpec specification, int specIndex) { _logFactory = logFactory; _logger = logFactory.CreateLogger <EntityChunkList>(); _allocator = allocator; Specification = specification; SpecIndex = specIndex; }
internal EntityChunk(ILoggerFactory logFactory, IAllocator allocator, EntitySpec specifcation, int specIndex, int chunkIndex) { _logFactory = logFactory; _logger = _logFactory.CreateLogger <EntityChunk>(); _allocator = allocator; Specification = specifcation; PackedArray = new ComponentPackedArray(logFactory, _allocator, specifcation); _entityRefs = new NativeList <EntityRef>(_allocator, PackedArray.Length); SpecIndex = specIndex; ChunkIndex = chunkIndex; }
public void ShouldRemoveManyWithMany() { using var memory = new HeapAllocator(_logFactory); using var em = new EntityManager(_logFactory, memory); using var buffer = new EntityCommandBuffer(em, memory); var spec = new EntitySpec(ComponentType <Velocity> .Type, ComponentType <Position> .Type, ComponentType <Filler> .Type); const int samples = 32; var ids = new uint[samples]; em.Create(spec, ids); var idsToChange = new[] { ids[0], ids[11], ids[22], ids[23], ids[3], ids[2], ids[15], ids[17], ids[29], ids[21] }; var remainingIds = ids.Where(x => !idsToChange.Contains(x)).ToArray(); var typesToRemove = new[] { spec.ComponentTypes[1], spec.ComponentTypes[2] }; buffer.Remove(idsToChange, typesToRemove); buffer.Execute(); em.EntityCount.ShouldBe(samples); em.EntityArrays.Count.ShouldBe(2); em.EntityArrays[0].EntityCount.ShouldBe(samples - idsToChange.Length); em.EntityArrays[1].EntityCount.ShouldBe(idsToChange.Length); var entities0 = em.EntityArrays[0].AllChunks[0].Entities.ToArray(); entities0.Any(x => idsToChange.Contains(x.ID)).ShouldBe(false); entities0.All(x => remainingIds.Contains(x.ID)).ShouldBe(true); var entities1 = em.EntityArrays[1].AllChunks[0].Entities.ToArray(); entities1.Any(x => remainingIds.Contains(x.ID)).ShouldBe(false); entities1.All(x => idsToChange.Contains(x.ID)).ShouldBe(true); var positionResults = idsToChange.Select(id => em.Has <Position>(id)).ToArray(); positionResults.ShouldAllBe(x => x == false); var fillerResults = idsToChange.Select(id => em.Has <Filler>(id)).ToArray(); fillerResults.ShouldAllBe(x => x == false); var velocityResults = idsToChange.Select(id => em.Has <Velocity>(id)).ToArray(); velocityResults.ShouldAllBe(x => x == true); }
public void EntitySpecGroupShouldNotMatchDifferentGroup() { var a = new EntitySpec(new IEntitySpecGroup[] { new GroupA() { HashCode = 1 } }, ComponentType <Valid> .Type, ComponentType <Valid2> .Type); var b = new EntitySpec(new IEntitySpecGroup[] { new GroupB() { HashCode = 1 } }, ComponentType <Valid2> .Type, ComponentType <Valid> .Type); a.ID.ShouldNotBe(b.ID); a.GetGroupData <GroupA>().HashCode.ShouldBe(1); b.GetGroupData <GroupB>().HashCode.ShouldBe(1); }
public void ShouldCreateManyEntity() { using var memory = new HeapAllocator(_logFactory); using var em = new EntityManager(_logFactory, memory); using var buffer = new EntityCommandBuffer(em, memory, 8); var spec = new EntitySpec(ComponentType <Position> .Type, ComponentType <Velocity> .Type); buffer.Create(spec, 16384); buffer.Execute(); em.EntityCount.ShouldBe(16384); em.EntityArrays[0].EntityCount.ShouldBe(16384); }
internal ComponentPackedArray(ILoggerFactory logFactory, IAllocator allocator, EntitySpec specification) { _logFactory = logFactory; _logger = _logFactory.CreateLogger <ComponentPackedArray>(); _allocator = allocator; Specification = specification; var _componentTypes = Specification.ComponentTypes; _componentData = new ComponentDataArray[_componentTypes.Length]; for (var i = 0; i < _componentTypes.Length; i++) { _componentData[i] = new ComponentDataArray(_logFactory, _allocator, _componentTypes[i], Entity.ENTITY_MAX); } }
public void ShouldReplaceOne() { using var memory = new HeapAllocator(_logFactory); using var em = new EntityManager(_logFactory, memory); using var buffer = new EntityCommandBuffer(em, memory); var spec = new EntitySpec(ComponentType <Position> .Type, ComponentType <Velocity> .Type); var id = em.Create(spec); buffer.Replace(id, new Position(10, 10)); buffer.Execute(); em.EntityCount.ShouldBe(1); em.EntityArrays[0].EntityCount.ShouldBe(1); em.Get <Position>(id).ShouldBe(new Position(10, 10)); }
public void Setup() { _logFactory = LoggerFactory.Create(builder => { builder.AddConsole(); }); _memory = new HeapAllocator(_logFactory); _entities = new EntityManager(_logFactory, _memory); var spec = EntitySpec.Create <Position, Velocity>(); for (var i = 0; i < N; i++) { //TODO: bulk insert API var entity = _entities.Create(spec); } }
public void CanCreatePackedArray() { //arrange using var memory = new DynamicAllocator(_logFactory); var specification = new EntitySpec( ComponentType <Position> .Type, ComponentType <Velocity> .Type ); using var entityGroup = new ComponentPackedArray(_logFactory, memory, specification); //act var positions = entityGroup.GetComponentData <Position>(); var velocities = entityGroup.GetComponentData <Velocity>(); //assert for (var i = 0; i < entityGroup.Length; i++) { ref var p = ref positions[i]; ref var v = ref velocities[i];
public void ShouldRemoveOne() { using var memory = new HeapAllocator(_logFactory); using var em = new EntityManager(_logFactory, memory); using var buffer = new EntityCommandBuffer(em, memory); var spec = new EntitySpec(ComponentType <Velocity> .Type, ComponentType <Position> .Type); var id = em.Create(spec); buffer.Remove <Position>(id); buffer.Execute(); em.EntityCount.ShouldBe(1); em.EntityArrays.Count.ShouldBe(2); em.EntityArrays[0].EntityCount.ShouldBe(0); em.EntityArrays[1].EntityCount.ShouldBe(1); em.Has <Position>(id).ShouldBe(false); }
public void ShouldDeleteEntityOnLastComponentOne() { using var memory = new HeapAllocator(_logFactory); using var em = new EntityManager(_logFactory, memory); using var buffer = new EntityCommandBuffer(em, memory); var spec = new EntitySpec(ComponentType <Position> .Type, ComponentType <Velocity> .Type); const int samples = 32; var ids = new uint[samples]; em.Create(spec, ids); buffer.Remove(ids, spec.ComponentTypes); buffer.Execute(); em.EntityCount.ShouldBe(0); em.EntityArrays.Count.ShouldBe(1); em.EntityArrays[0].EntityCount.ShouldBe(0); }
public void ShouldUpdateManyWithMany() { using var memory = new HeapAllocator(_logFactory); using var em = new EntityManager(_logFactory, memory); using var buffer = new EntityCommandBuffer(em, memory); var spec = new EntitySpec(ComponentType <Velocity> .Type); const int samples = 32; var ids = new uint[samples]; em.Create(spec, ids); var idsToChange = new[] { ids[0], ids[11], ids[22], ids[23], ids[3], ids[2], ids[15], ids[17], ids[29], ids[21] }; var remainingIds = ids.Where(x => !idsToChange.Contains(x)).ToArray(); var positions = idsToChange.Select(x => new Position((int)x, 10)).ToArray(); buffer.Update(idsToChange, positions.AsSpan()); buffer.Execute(); em.EntityCount.ShouldBe(samples); em.EntityArrays.Count.ShouldBe(2); em.EntityArrays[0].EntityCount.ShouldBe(samples - idsToChange.Length); em.EntityArrays[1].EntityCount.ShouldBe(idsToChange.Length); var entities0 = em.EntityArrays[0].AllChunks[0].Entities.ToArray(); entities0.Any(x => idsToChange.Contains(x.ID)).ShouldBe(false); entities0.All(x => remainingIds.Contains(x.ID)).ShouldBe(true); var entities1 = em.EntityArrays[1].AllChunks[0].Entities.ToArray(); entities1.Any(x => remainingIds.Contains(x.ID)).ShouldBe(false); entities1.All(x => idsToChange.Contains(x.ID)).ShouldBe(true); var positionResults = idsToChange.Select(id => em.Get <Position>(id)).ToArray(); positionResults.ShouldBe(positions); }
public unsafe void ShouldCopyMoreThanOne() { //arrange using var memory = new DynamicAllocator(_logFactory); var specifcation = new EntitySpec( ComponentType <Position> .Type ); var specIndex = 0; using var chunkArray = new EntityChunkList(_logFactory, memory, specifcation, specIndex); using var entityPool = new EntityPool(_logFactory, memory); var entity0 = entityPool.TakeRef(); var entity1 = entityPool.TakeRef(); var entity2 = entityPool.TakeRef(); var entity3 = entityPool.TakeRef(); chunkArray.Create(entity0); chunkArray.Create(entity1); chunkArray.Create(entity2); chunkArray.Create(entity3); var componentType = stackalloc[] { ComponentType <Position> .Type }; var componentIndex = chunkArray.Specification.GetComponentIndex(*componentType); var span = chunkArray.AllChunks[entity0.ChunkIndex].PackedArray.GetComponentData <Position>(); var ptr = stackalloc[] { new Position(100, 100), new Position(200, 200), new Position(400, 100), new Position(100, 400) }; var src = (void *)ptr; Span <EntityRef> entityRefs = stackalloc[] { entity0, entity1, //swapping 2 and 3 to see if we can resume correctly entity3, entity2, }; //act chunkArray.Copy(specIndex, componentType, ref src, entityRefs, true); //assert span[0].X.ShouldBe(100); span[0].Y.ShouldBe(100); span[1].X.ShouldBe(200); span[1].Y.ShouldBe(200); span[3].X.ShouldBe(400); span[3].Y.ShouldBe(100); span[2].X.ShouldBe(100); span[2].Y.ShouldBe(400); } // public void ShouldMoveToAnotherArray() // { // //arrange // var specifcation = new EntitySpec( // ComponentType<Position>.Type // ); // var srcArray = new EntityChunkArray(_logFactory, specifcation); // var dstArray = new EntityChunkArray(_logFactory, specifcation); // //act // var srcIndex = srcArray.Create(1, out var chunkIndex); // Console.WriteLine(chunkIndex); // var srcSpan = srcArray.AllChunks[chunkIndex].PackedArray.GetComponentSpan<Position>(); // srcSpan[srcIndex] = new Position(10, 20); // var tempIndex = dstArray.Create(2, out var tempChunkIndex); //pushing the datain dst to check that it inserted correctly // EntityChunkArray.MoveTo(1, srcArray, chunkIndex, srcIndex, dstArray, out var dstChunkIndex, out var dstIndex); // //assert // chunkIndex.ShouldBe(0); // srcIndex.ShouldBe(0); // srcArray.EntityCount.ShouldBe(0); // dstChunkIndex.ShouldBe(0); // dstIndex.ShouldBe(1); // dstArray.EntityCount.ShouldBe(2); // var dstSpan = dstArray.AllChunks[dstChunkIndex].PackedArray.GetComponentSpan<Position>(); // dstSpan[dstIndex].X.ShouldBe(10); // dstSpan[dstIndex].Y.ShouldBe(20); // } }
public unsafe void ShouldDeleteManyEntities() { //arrange using var memory = new DynamicAllocator(_logFactory); var specification = new EntitySpec(ComponentType <Position> .Type); using var entityChunk = new EntityChunk(_logFactory, memory, specification, 0, 0); using var entityPool = new EntityPool(_logFactory, memory); var ids = new EntityRef[entityChunk.Free + 1]; entityPool.Take(ids); var created = entityChunk.Create(ids); var span = entityChunk.PackedArray.GetComponentData <Position>(); for (var i = 0; i < span.Length; i++) { span[i] = new Position(i + 1); } //act Span <EntityRef> deleteIndicies = stackalloc EntityRef[128]; for (var i = 0; i < deleteIndicies.Length; i++) { deleteIndicies[i] = ids[i + 128]; } entityChunk.Delete(deleteIndicies); //assert var first = Enumerable.Range(0, 128).Select(x => ids[x]).ToArray(); var second = Enumerable.Range(0, 128).Select(x => ids[Entity.ENTITY_MAX - x - 1]).ToArray(); var third = Enumerable.Range(256, Entity.ENTITY_MAX - 256 - 128).Select(x => ids[x]).ToArray(); var fourth = Enumerable.Range(0, 128).Select(x => 0).Select(x => 0u).ToArray(); var firstSet = entityChunk.Entities.Slice(0, 128).ToArray(); var secondSet = entityChunk.Entities.Slice(128, 128).ToArray(); var thirdSet = entityChunk.Entities.Slice(256, Entity.ENTITY_MAX - 256 - 128).ToArray(); //var fourthSet = entityChunk.Entities.Slice(Entity.ENTITY_MAX - 128, 128).ToArray(); firstSet.ShouldBe(first); secondSet.ShouldBe(second); thirdSet.ShouldBe(third); //fourthSet.ShouldBe(fourth); entityChunk.Entities.Length.ShouldBe(Entity.ENTITY_MAX - 128); var firstPosition = Enumerable.Range(0, 128).Select(x => new Position(x + 1)).ToArray(); var secondPosition = Enumerable.Range(0, 128).Select(x => new Position(Entity.ENTITY_MAX - x)).ToArray(); var thirdPosition = Enumerable.Range(256, Entity.ENTITY_MAX - 256 - 128).Select(x => new Position(x + 1)).ToArray(); var firstSetPosition = span.Slice(0, 128).ToArray(); var secondSetPosition = span.Slice(128, 128).ToArray(); var thirdSetPosition = span.Slice(256, Entity.ENTITY_MAX - 256 - 128).ToArray(); firstSetPosition.ShouldBe(firstPosition); secondSetPosition.ShouldBe(secondPosition); thirdSetPosition.ShouldBe(thirdPosition); #if DEBUG //we only reset the data in debug mode for performance reasons var fourthPosition = Enumerable.Range(0, 128).Select(x => new Position(0)).ToArray(); var fourthSetPosition = span.Slice(Entity.ENTITY_MAX - 128, 128).ToArray(); fourthSetPosition.ShouldBe(fourthPosition); #endif entityChunk.Count.ShouldBe(Entity.ENTITY_MAX - 128); entityChunk.Free.ShouldBe(128); }