diff --git a/component.go b/component.go index e62ebec..dba417a 100644 --- a/component.go +++ b/component.go @@ -571,7 +571,7 @@ func addComponentsToArchetype1[A ComponentInterface](world *World, entityRecord world.setArchetype(entityRecord, archetype) } } - storageA.add(archetype.Id, component) + storageA.addTyped(archetype.Id, component) return nil } @@ -596,8 +596,8 @@ func addComponentsToArchetype2[A, B ComponentInterface](world *World, entityReco } } - storageA.add(archetype.Id, componentA) - storageB.add(archetype.Id, componentB) + storageA.addTyped(archetype.Id, componentA) + storageB.addTyped(archetype.Id, componentB) return nil } @@ -623,9 +623,9 @@ func addComponentsToArchetype3[A, B, C ComponentInterface](world *World, entityR } } - storageA.add(archetype.Id, componentA) - storageB.add(archetype.Id, componentB) - storageC.add(archetype.Id, componentC) + storageA.addTyped(archetype.Id, componentA) + storageB.addTyped(archetype.Id, componentB) + storageC.addTyped(archetype.Id, componentC) return nil } @@ -652,10 +652,10 @@ func addComponentsToArchetype4[A, B, C, D ComponentInterface](world *World, enti } } - storageA.add(archetype.Id, componentA) - storageB.add(archetype.Id, componentB) - storageC.add(archetype.Id, componentC) - storageD.add(archetype.Id, componentD) + storageA.addTyped(archetype.Id, componentA) + storageB.addTyped(archetype.Id, componentB) + storageC.addTyped(archetype.Id, componentC) + storageD.addTyped(archetype.Id, componentD) return nil } @@ -683,11 +683,11 @@ func addComponentsToArchetype5[A, B, C, D, E ComponentInterface](world *World, e } } - storageA.add(archetype.Id, componentA) - storageB.add(archetype.Id, componentB) - storageC.add(archetype.Id, componentC) - storageD.add(archetype.Id, componentD) - storageE.add(archetype.Id, componentE) + storageA.addTyped(archetype.Id, componentA) + storageB.addTyped(archetype.Id, componentB) + storageC.addTyped(archetype.Id, componentC) + storageD.addTyped(archetype.Id, componentD) + storageE.addTyped(archetype.Id, componentE) return nil } @@ -716,12 +716,12 @@ func addComponentsToArchetype6[A, B, C, D, E, F ComponentInterface](world *World } } - storageA.add(archetype.Id, componentA) - storageB.add(archetype.Id, componentB) - storageC.add(archetype.Id, componentC) - storageD.add(archetype.Id, componentD) - storageE.add(archetype.Id, componentE) - storageF.add(archetype.Id, componentF) + storageA.addTyped(archetype.Id, componentA) + storageB.addTyped(archetype.Id, componentB) + storageC.addTyped(archetype.Id, componentC) + storageD.addTyped(archetype.Id, componentD) + storageE.addTyped(archetype.Id, componentE) + storageF.addTyped(archetype.Id, componentF) return nil } @@ -751,13 +751,13 @@ func addComponentsToArchetype7[A, B, C, D, E, F, G ComponentInterface](world *Wo } } - storageA.add(archetype.Id, componentA) - storageB.add(archetype.Id, componentB) - storageC.add(archetype.Id, componentC) - storageD.add(archetype.Id, componentD) - storageE.add(archetype.Id, componentE) - storageF.add(archetype.Id, componentF) - storageG.add(archetype.Id, componentG) + storageA.addTyped(archetype.Id, componentA) + storageB.addTyped(archetype.Id, componentB) + storageC.addTyped(archetype.Id, componentC) + storageD.addTyped(archetype.Id, componentD) + storageE.addTyped(archetype.Id, componentE) + storageF.addTyped(archetype.Id, componentF) + storageG.addTyped(archetype.Id, componentG) return nil } @@ -788,14 +788,14 @@ func addComponentsToArchetype8[A, B, C, D, E, F, G, H ComponentInterface](world } } - storageA.add(archetype.Id, componentA) - storageB.add(archetype.Id, componentB) - storageC.add(archetype.Id, componentC) - storageD.add(archetype.Id, componentD) - storageE.add(archetype.Id, componentE) - storageF.add(archetype.Id, componentF) - storageG.add(archetype.Id, componentG) - storageH.add(archetype.Id, componentH) + storageA.addTyped(archetype.Id, componentA) + storageB.addTyped(archetype.Id, componentB) + storageC.addTyped(archetype.Id, componentC) + storageD.addTyped(archetype.Id, componentD) + storageE.addTyped(archetype.Id, componentE) + storageF.addTyped(archetype.Id, componentF) + storageG.addTyped(archetype.Id, componentG) + storageH.addTyped(archetype.Id, componentH) return nil } diff --git a/storage.go b/storage.go index c324427..467d9f8 100644 --- a/storage.go +++ b/storage.go @@ -80,18 +80,21 @@ func (c *ComponentsStorage[T]) size(archetypeId archetypeId) int { } func (c *ComponentsStorage[T]) add(archetypeId archetypeId, component ComponentInterface) int { - // this function could be simplified using: - // c.size(archetypeId) - 1 - // but to reduce the usage of mapaccess we compute the size ourselves instead of calling c.size + return c.addTyped(archetypeId, component.(T)) +} - c.archetypesComponentsEntities[archetypeId] = append(c.archetypesComponentsEntities[archetypeId], component.(T)) +// addTyped appends a component without boxing it into ComponentInterface. +// The generic add/copy paths hold a concrete *ComponentsStorage[T], so they can +// call this directly and avoid one heap allocation per component added. +func (c *ComponentsStorage[T]) addTyped(archetypeId archetypeId, component T) int { + // We compute the size ourselves instead of calling c.size to reduce mapaccess. + c.archetypesComponentsEntities[archetypeId] = append(c.archetypesComponentsEntities[archetypeId], component) return len(c.archetypesComponentsEntities[archetypeId]) - 1 - } func (c *ComponentsStorage[T]) copy(oldArchetypeId archetypeId, archetypeId archetypeId, recordKey int) int { - return c.add(archetypeId, c.archetypesComponentsEntities[oldArchetypeId][recordKey]) + return c.addTyped(archetypeId, c.archetypesComponentsEntities[oldArchetypeId][recordKey]) } func (c *ComponentsStorage[T]) set(archetypeId archetypeId, key int, component ComponentInterface) {