diff --git a/internal/storage/storage.go b/internal/storage/storage.go index 3f79ac8..c1aeab1 100644 --- a/internal/storage/storage.go +++ b/internal/storage/storage.go @@ -24,6 +24,9 @@ func NewStorage() *Storage { // PushComponent stores the new data of the component in the archetype. func (cs *Storage) PushComponent(component component.IComponentType, archetypeIndex ArchetypeIndex) { + if len(cs.storages) <= int(archetypeIndex) { + cs.ensureCapacity(archetypeIndex) + } if v := cs.storages[archetypeIndex]; v == nil { cs.storages[archetypeIndex] = []unsafe.Pointer{} } @@ -44,6 +47,10 @@ func (cs *Storage) SetComponent(archetypeIndex ArchetypeIndex, componentIndex Co // MoveComponent moves the pointer to data of the component in the archetype. func (cs *Storage) MoveComponent(source ArchetypeIndex, index ComponentIndex, dst ArchetypeIndex) { + if len(cs.storages) <= int(dst) { + cs.ensureCapacity(dst) + } + src_slice := cs.storages[source] dst_slice := cs.storages[dst] @@ -74,3 +81,9 @@ func (cs *Storage) Contains(archetypeIndex ArchetypeIndex, componentIndex Compon } return cs.storages[archetypeIndex][componentIndex] != nil } + +func (cs *Storage) ensureCapacity(archetypeIndex ArchetypeIndex) { + newStorages := make([][]unsafe.Pointer, len(cs.storages)*2) + copy(newStorages, cs.storages) + cs.storages = newStorages +} diff --git a/world_test.go b/world_test.go index 73e5f98..8e0a4d7 100644 --- a/world_test.go +++ b/world_test.go @@ -193,6 +193,25 @@ func TestDeleteEntity(t *testing.T) { } } +func TestArchetypeStorageExpands(t *testing.T) { + world := donburi.NewWorld() + dummy := donburi.NewTag() + entry := world.Entry(world.Create(dummy)) + const N = 256 + for i := 0; i < N; i++ { + tag := donburi.NewTag() + entry.AddComponent(tag) + } + q := donburi.NewQuery(filter.Contains(dummy)) + e, ok := q.First(world) + if !ok { + t.Fatalf("Entity should be found") + } + if len(e.Archetype().Layout().Components()) != N+1 { + t.Fatalf("Archetype should have 301 components") + } +} + func TestRemoveAndCreateEntity(t *testing.T) { world := donburi.NewWorld()