Skip to content

Commit

Permalink
Engine - ECS: simplify / optimize Archetype.CreateEntities()
Browse files Browse the repository at this point in the history
  • Loading branch information
friflo committed May 28, 2024
1 parent 772fd49 commit 58f604e
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 34 deletions.
23 changes: 6 additions & 17 deletions Engine/src/ECS/Archetype/Archetype.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,30 +121,19 @@ public Entity CreateEntity(int id)
return entity;
}

public EntityList CreateEntities(int count, EntityList list = null)
public Entities CreateEntities(int count)
{
if (list == null) {
list = new EntityList(entityStore);
} else {
list.Clear();
list.SetStore(entityStore);
}
list.Capacity = count;
var localStore = entityStore;
var ids = list.ids;
localStore.NewIds(ids, count);
list.count = count;
var maxId = list.ids[count - 1];
var localStore = entityStore;
int compIndexStart = entityCount;
localStore.CreateEntityNodes(this, ids, count, maxId);
localStore.CreateEntityNodes(this, count);

foreach (var heap in structHeaps) {
heap.SetComponentsDefault(compIndexStart, count);
}

// Send event. See: SEND_EVENT notes
localStore.CreateEntityEvents(ids, count);
return list;
var entities = new Entities(entityIds, localStore, compIndexStart, count);
localStore.CreateEntityEvents(entities);
return entities;
}

/// <summary>
Expand Down
6 changes: 3 additions & 3 deletions Engine/src/ECS/Archetype/Entities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Friflo.Engine.ECS;
internal readonly int[] ids; // 8
internal readonly EntityStore store; // 8
internal readonly int start; // 4
public readonly int count; // 4
internal readonly int count; // 4
#endregion

#region general
Expand Down Expand Up @@ -49,13 +49,13 @@ public struct EntityEnumerator : IEnumerator<Entity>
private readonly int[] ids; // 8
private readonly EntityStore store; // 8
private readonly int start; // 4
private readonly int last; // 8
private readonly int last; // 4
private int index; // 4

internal EntityEnumerator(in Entities entities) {
ids = entities.ids;
store = entities.store;
start = entities.start;
start = entities.start - 1;
last = start + entities.count;
index = start;
}
Expand Down
11 changes: 6 additions & 5 deletions Engine/src/ECS/Entity/Store/Entities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,16 +172,17 @@ private int CreateEntityNode(Archetype archetype, int id)
return node.compIndex;
}

internal void CreateEntityNodes(Archetype archetype, int[] ids, int count, int maxId)
internal void CreateEntityNodes(Archetype archetype, int count)
{
int maxId = intern.sequenceId + count;
EnsureNodesLength(maxId + 1);
archetype.EnsureCapacity(count);
int compIndexStart = archetype.entityCount;
var entityIds = archetype.entityIds;
var localNodes = nodes;
for (int n = 0; n < count; n++)
{
var id = ids[n];
var id = NewId();
AssertIdInNodes(id);
ref var node = ref localNodes[id];
if ((node.flags & Created) != 0) {
Expand Down Expand Up @@ -218,14 +219,14 @@ private QueryEntities GetEntities() {
return query.Entities;
}

internal void CreateEntityEvents(int[] ids, int count)
internal void CreateEntityEvents(Entities entities)
{
var create = intern.entityCreate;
if (create == null) {
return;
}
for (int n = 0; n < count; n++) {
create(new EntityCreate(new Entity(this, ids[n])));
foreach (var entity in entities) {
create(new EntityCreate(entity));
}
}

Expand Down
19 changes: 10 additions & 9 deletions Engine/src/Tests/ECS/Entity/Test_StructHeap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,18 +109,19 @@ public static void Test_StructHeap_CreateEntities()
Mem.AreEqual(evId++, create.Entity.Id);
};
for (int n = 0; n < repeat; n++) {
var start = Mem.GetAllocatedBytes();
type.CreateEntities(count, list);
var start = Mem.GetAllocatedBytes();
var entities = type.CreateEntities(count);
Mem.AssertNoAlloc(start);
for (int i = 0; i < count; i++) {
var entity = list[i];
foreach (var entity in entities) {
Assert.AreSame(type, entity.Archetype);
Assert.AreEqual(seqId++, entity.Id);
}
}
list = type.CreateEntities(count); // list = null
for (int i = 0; i < count; i++) {
Assert.AreEqual(seqId++, list[i].Id);
{
var entities = type.CreateEntities(count); // list = null
foreach (var entity in entities) {
Assert.AreEqual(seqId++, entity.Id);
}
}
var entityCount = (1 + repeat) * count;
Assert.AreEqual(entityCount, store.Count);
Expand Down Expand Up @@ -189,14 +190,14 @@ public static void Test_StructHeap_CreateEntities_Perf()
/* #PC:
Archetype.CreateEntities() Entity count: 100000, repeat: 1000, duration: 1,479 ms
*/
var list = new EntityList();
var sw = new Stopwatch();
sw.Start();
for (int i = 0; i < repeat; i++)
{
var store = new EntityStore();
var type = store.GetArchetype(ComponentTypes.Get<MyComponent1, MyComponent2, MyComponent3>());
type.CreateEntities(count, list);
var entities = type.CreateEntities(count);
Mem.AreEqual(count, entities.Count);
}
var duration = (double)sw.ElapsedMilliseconds / repeat;
Console.WriteLine($"Archetype.CreateEntities() Entity count: {count}, repeat: {repeat}, duration: {duration} ms");
Expand Down

0 comments on commit 58f604e

Please sign in to comment.