diff --git a/CHANGELOG.md b/CHANGELOG.md index ff713585..5e73d5ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## [[unpublished]](https://github.com/mlange-42/arche/compare/v0.11.0...main) +## [[v0.12.0]](https://github.com/mlange-42/arche/compare/v0.11.0...v0.12.0) ### Features @@ -12,6 +12,10 @@ * Re-arrange struct fields to save memory in a few places (#413) +### Bugfixes + +* Fix crash caused by extending layouts of an inactive archetype (#416, reported in #415) + ### First-time contributors * [delaneyj](https://github.com/delaneyj) diff --git a/ecs/archetype_node.go b/ecs/archetype_node.go index 2d340faf..6fc75c1a 100644 --- a/ecs/archetype_node.go +++ b/ecs/archetype_node.go @@ -136,6 +136,10 @@ func (a *archNode) CreateArchetype(layouts uint8, target Entity) *archetype { } func (a *archNode) ExtendArchetypeLayouts(count uint8) { + if !a.IsActive { + return + } + if !a.HasRelation { a.archetype.ExtendLayouts(count) return diff --git a/ecs/types_test.go b/ecs/types_test.go index 02939151..53268fa7 100644 --- a/ecs/types_test.go +++ b/ecs/types_test.go @@ -60,6 +60,7 @@ type testStruct13 struct{ val int32 } type testStruct14 struct{ val int32 } type testStruct15 struct{ val int32 } type testStruct16 struct{ val int32 } +type testStruct17 struct{ val int32 } type withSlice struct { Slice []int diff --git a/ecs/world_test.go b/ecs/world_test.go index f1787c86..6a51e573 100644 --- a/ecs/world_test.go +++ b/ecs/world_test.go @@ -1712,6 +1712,7 @@ func Test1000Archetypes(t *testing.T) { _ = testStruct14{1} _ = testStruct15{1} _ = testStruct16{1} + _ = testStruct17{1} w := NewWorld() @@ -1878,6 +1879,34 @@ func TestWorldExtendLayouts(t *testing.T) { } } +func TestWorldExtendLayouts2(t *testing.T) { + w := NewWorld() + + id1 := ComponentID[testStruct0](&w) + id2 := ComponentID[testStruct1](&w) + _ = ComponentID[testStruct2](&w) + _ = ComponentID[testStruct3](&w) + _ = ComponentID[testStruct4](&w) + _ = ComponentID[testStruct5](&w) + _ = ComponentID[testStruct6](&w) + _ = ComponentID[testStruct7](&w) + _ = ComponentID[testStruct8](&w) + _ = ComponentID[testStruct9](&w) + _ = ComponentID[testStruct10](&w) + _ = ComponentID[testStruct11](&w) + _ = ComponentID[testStruct12](&w) + _ = ComponentID[testStruct13](&w) + _ = ComponentID[testStruct14](&w) + + _ = w.NewEntity(id1, id2) + + _ = ComponentID[testStruct15](&w) + _ = ComponentID[testStruct16](&w) + id17 := ComponentID[testStruct17](&w) + + _ = w.NewEntity(id17) +} + func TestWorldPointerStressTest(t *testing.T) { w := NewWorld()