diff --git a/entity/entity.go b/entity/entity.go index a628323..28fb0f5 100755 --- a/entity/entity.go +++ b/entity/entity.go @@ -3,9 +3,8 @@ package entity type EntityFlag byte const ( - EntityFlag_Unknown EntityFlag = 0 - EntityFlag_Dead EntityFlag = 1 << (iota - 1) - EntityFlag_Alive + EntityFlag_None EntityFlag = 0 + EntityFlag_Alive EntityFlag = 1 << (iota - 1) ) const ( @@ -25,8 +24,8 @@ func GetGeneration(id uint64) byte { return byte(id >> GenerationShiftBits) } -func GetFlags(id uint64) byte { - return byte(id >> FlagsShiftBits) +func GetFlags(id uint64) EntityFlag { + return EntityFlag(id >> FlagsShiftBits) } func GetIndex(id uint64) uint64 { @@ -34,10 +33,10 @@ func GetIndex(id uint64) uint64 { } func (e *Entity) HasFlag(ef EntityFlag) bool { - return GetFlags(e.ID)&byte(ef) > 0 + return GetFlags(e.ID)&ef > 0 } -func NewEntityId(generation, flags byte, index uint64) uint64 { +func NewEntityId(generation byte, flags EntityFlag, index uint64) uint64 { return index | (uint64(generation) << GenerationShiftBits) | (uint64(flags) << FlagsShiftBits) } diff --git a/entity/registry.go b/entity/registry.go index a0dcaca..fd6ae3b 100755 --- a/entity/registry.go +++ b/entity/registry.go @@ -4,6 +4,12 @@ import ( "github.com/bloeys/nmage/assert" ) +var ( + // The number of slots required to be in the free list before the free list + // is used for creating new entries + FreeListUsageThreshold uint32 = 20 +) + type freeListitem struct { EntityIndex uint64 nextFree *freeListitem @@ -12,7 +18,9 @@ type freeListitem struct { type Registry struct { EntityCount uint64 Entities []Entity - FreeList *freeListitem + + FreeList *freeListitem + FreeListSize uint32 } func (r *Registry) NewEntity() *Entity { @@ -22,17 +30,18 @@ func (r *Registry) NewEntity() *Entity { entityToUseIndex := uint64(0) var entityToUse *Entity = nil - if r.FreeList != nil { + if r.FreeList != nil && r.FreeListSize > FreeListUsageThreshold { entityToUseIndex = r.FreeList.EntityIndex entityToUse = &r.Entities[entityToUseIndex] r.FreeList = r.FreeList.nextFree + r.FreeListSize-- } else { for i := 0; i < len(r.Entities); i++ { e := &r.Entities[i] - if GetFlags(e.ID) != byte(EntityFlag_Unknown) && !e.HasFlag(EntityFlag_Dead) { + if e.HasFlag(EntityFlag_Alive) { continue } @@ -47,7 +56,7 @@ func (r *Registry) NewEntity() *Entity { } r.EntityCount++ - entityToUse.ID = NewEntityId(GetGeneration(entityToUse.ID)+1, byte(EntityFlag_Alive), entityToUseIndex) + entityToUse.ID = NewEntityId(GetGeneration(entityToUse.ID)+1, EntityFlag_Alive, entityToUseIndex) assert.T(entityToUse.ID != 0, "Entity ID must not be zero") return entityToUse } @@ -78,12 +87,13 @@ func (r *Registry) FreeEntity(id uint64) { eIndex := GetIndex(e.ID) e.Comps = []Comp{} - e.ID = NewEntityId(GetGeneration(e.ID), byte(EntityFlag_Dead), eIndex) + e.ID = NewEntityId(GetGeneration(e.ID), EntityFlag_None, eIndex) r.FreeList = &freeListitem{ EntityIndex: eIndex, nextFree: r.FreeList, } + r.FreeListSize++ } func NewRegistry(size uint32) *Registry {