From 66d93b3e06ce278ee282f75018754bc9927e2698 Mon Sep 17 00:00:00 2001 From: mlange-42 Date: Sun, 28 Apr 2024 20:49:41 +0200 Subject: [PATCH 1/2] Fix: Do not extend layouts of inactive archetypes --- CHANGELOG.md | 6 +++++- ecs/archetype_node.go | 2 +- ecs/types_test.go | 1 + ecs/world_test.go | 29 +++++++++++++++++++++++++++++ 4 files changed, 36 insertions(+), 2 deletions(-) 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..d33345ea 100644 --- a/ecs/archetype_node.go +++ b/ecs/archetype_node.go @@ -136,7 +136,7 @@ func (a *archNode) CreateArchetype(layouts uint8, target Entity) *archetype { } func (a *archNode) ExtendArchetypeLayouts(count uint8) { - if !a.HasRelation { + if a.IsActive && !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() From 4685db2374b629f22a9dfc32f4e14284cd40a060 Mon Sep 17 00:00:00 2001 From: mlange-42 Date: Mon, 29 Apr 2024 10:17:53 +0200 Subject: [PATCH 2/2] fix early return, also for relation nodes --- ecs/archetype_node.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ecs/archetype_node.go b/ecs/archetype_node.go index d33345ea..6fc75c1a 100644 --- a/ecs/archetype_node.go +++ b/ecs/archetype_node.go @@ -136,7 +136,11 @@ func (a *archNode) CreateArchetype(layouts uint8, target Entity) *archetype { } func (a *archNode) ExtendArchetypeLayouts(count uint8) { - if a.IsActive && !a.HasRelation { + if !a.IsActive { + return + } + + if !a.HasRelation { a.archetype.ExtendLayouts(count) return }