Repository: mlange-42/arche
Pull request #257 (2023-05-02 10:23:48)

Configurable capacity increment for relation archetypes

coveralls: ## Pull Request Test Coverage Report for [Build 4860156999](https://coveralls.io/builds/59520018)

* **14** of **14**   **(100.0%)**  changed or added relevant lines in **2** files are covered.
* No unchanged relevant lines lost coverage.
* Overall coverage remained the same at **100.0%**

---



|  Totals | [![Coverage Status](https://coveralls.io/builds/59520018/badge)](https://coveralls.io/builds/59520018) |
| :-- | --: |
| Change from base [Build 4859967421](https://coveralls.io/builds/59518963): |  0.0% |
| Covered Lines: | 3418 |
| Relevant Lines: | 3418 |

---
##### 💛  - [Coveralls](https://coveralls.io)


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 738bc7a..dee37f1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,7 @@
 * Support an unlimited number of cached filters, instead of 128 (#245)
 * `WorldStats` contains the number of cached filters (#247)
 * Archetypes with entity relations are removed on `World.Reset` (#247)
+* Capacity increment can be configured separately for relation archetypes (#257)
 
 ### Performance
 
diff --git a/ecs/config.go b/ecs/config.go
index a4a9426..5587990 100644
--- a/ecs/config.go
+++ b/ecs/config.go
@@ -5,12 +5,16 @@ type Config struct {
 	// Capacity increment for archetypes and the entity index.
 	// The default value is 128.
 	CapacityIncrement int
+	// Capacity increment for archetypes with a relation component.
+	// The default value is CapacityIncrement.
+	RelationCapacityIncrement int
 }
 
 // NewConfig creates a new default [World] configuration.
 func NewConfig() Config {
 	return Config{
-		CapacityIncrement: 128,
+		CapacityIncrement:         128,
+		RelationCapacityIncrement: 0,
 	}
 }
 
@@ -20,3 +24,10 @@ func (c Config) WithCapacityIncrement(inc int) Config {
 	c.CapacityIncrement = inc
 	return c
 }
+
+// WithRelationCapacityIncrement return a new Config with RelationCapacityIncrement set.
+// Use with method chaining.
+func (c Config) WithRelationCapacityIncrement(inc int) Config {
+	c.RelationCapacityIncrement = inc
+	return c
+}
diff --git a/ecs/world.go b/ecs/world.go
index eff314f..1cc2873 100644
--- a/ecs/world.go
+++ b/ecs/world.go
@@ -95,6 +95,9 @@ func fromConfig(conf Config) World {
 	if conf.CapacityIncrement < 1 {
 		panic("invalid CapacityIncrement in config, must be > 0")
 	}
+	if conf.RelationCapacityIncrement < 1 {
+		conf.RelationCapacityIncrement = conf.CapacityIncrement
+	}
 	entities := make([]entityIndex, 1, conf.CapacityIncrement)
 	entities[0] = entityIndex{arch: nil, index: 0}
 	w := World{
@@ -1053,7 +1056,12 @@ func (w *World) findArchetypeSlow(mask Mask) (*archetypeNode, bool) {
 
 // Creates a node in the archetype graph.
 func (w *World) createArchetypeNode(mask Mask, relation int8) *archetypeNode {
-	w.graph.Add(newArchetypeNode(mask, relation, w.config.CapacityIncrement))
+	capInc := w.config.CapacityIncrement
+	if relation >= 0 {
+		capInc = w.config.RelationCapacityIncrement
+	}
+
+	w.graph.Add(newArchetypeNode(mask, relation, capInc))
 	node := w.graph.Get(w.graph.Len() - 1)
 	w.relationNodes = append(w.relationNodes, node)
 	return node


Test patch:
diff --git a/ecs/config_test.go b/ecs/config_test.go
index d9f1f07..1ece5d0 100644
--- a/ecs/config_test.go
+++ b/ecs/config_test.go
@@ -11,11 +11,20 @@ func TestConfig(t *testing.T) {
 	c := ecs.NewConfig()
 	c = c.WithCapacityIncrement(16)
 	assert.Equal(t, 16, c.CapacityIncrement)
+	assert.Equal(t, 0, c.RelationCapacityIncrement)
+
+	c = c.WithRelationCapacityIncrement(8)
+	assert.Equal(t, 8, c.RelationCapacityIncrement)
+
 	_ = ecs.NewWorld(c)
 }
 
 func ExampleConfig() {
-	config := ecs.NewConfig().WithCapacityIncrement(1024)
+	config :=
+		ecs.NewConfig().
+			WithCapacityIncrement(1024).       // Optionally set capacity increment
+			WithRelationCapacityIncrement(128) // Optionally set capacity increment for relations
+
 	world := ecs.NewWorld(config)
 
 	world.NewEntity()
diff --git a/ecs/world_test.go b/ecs/world_test.go
index 42a8181..4bb87c5 100644
--- a/ecs/world_test.go
+++ b/ecs/world_test.go
@@ -15,6 +15,18 @@ func TestWorldConfig(t *testing.T) {
 
 	assert.Panics(t, func() { _ = NewWorld(Config{}) })
 	assert.Panics(t, func() { _ = NewWorld(Config{}, Config{}) })
+
+	world := NewWorld(
+		NewConfig().WithCapacityIncrement(32).WithRelationCapacityIncrement(8),
+	)
+
+	relID := ComponentID[testRelationA](&world)
+
+	world.NewEntity()
+	world.NewEntity(relID)
+
+	assert.Equal(t, uint32(32), world.graph.Get(0).capacityIncrement)
+	assert.Equal(t, uint32(8), world.graph.Get(1).capacityIncrement)
 }
 
 func TestWorldEntites(t *testing.T) {