Separate components from entity

This commit is contained in:
bloeys
2023-10-06 03:52:43 +04:00
parent 6f646540f9
commit c1d5033eb0
5 changed files with 22 additions and 26 deletions

View File

@ -8,7 +8,7 @@ type BaseComp struct {
Entity *Entity Entity *Entity
} }
func (b *BaseComp) base() { func (b *BaseComp) baseComp() {
} }
func (b *BaseComp) Init(parent *Entity) { func (b *BaseComp) Init(parent *Entity) {

View File

@ -5,7 +5,7 @@ import "github.com/bloeys/nmage/assert"
type Comp interface { type Comp interface {
// This ensures that implementors of the Comp interface // This ensures that implementors of the Comp interface
// always embed BaseComp // always embed BaseComp
base() baseComp()
Name() string Name() string
Init(parent *Entity) Init(parent *Entity)
@ -13,15 +13,23 @@ type Comp interface {
Destroy() Destroy()
} }
func AddComp[T Comp](e *Entity, c T) { func NewCompContainer() CompContainer {
return CompContainer{Comps: []Comp{}}
}
assert.T(!HasComp[T](e), "Entity with id '%v' already has component of type '%T'", e.ID, c) type CompContainer struct {
Comps []Comp
}
e.Comps = append(e.Comps, c) func AddComp[T Comp](e *Entity, cc *CompContainer, c T) {
assert.T(!HasComp[T](cc), "Entity with id '%v' already has component of type '%T'", e.ID, c)
cc.Comps = append(cc.Comps, c)
c.Init(e) c.Init(e)
} }
func HasComp[T Comp](e *Entity) bool { func HasComp[T Comp](e *CompContainer) bool {
for i := 0; i < len(e.Comps); i++ { for i := 0; i < len(e.Comps); i++ {
@ -34,7 +42,7 @@ func HasComp[T Comp](e *Entity) bool {
return false return false
} }
func GetComp[T Comp](e *Entity) (out T) { func GetComp[T Comp](e *CompContainer) (out T) {
for i := 0; i < len(e.Comps); i++ { for i := 0; i < len(e.Comps); i++ {
@ -48,7 +56,7 @@ func GetComp[T Comp](e *Entity) (out T) {
} }
// DestroyComp calls Destroy on the component and then removes it from the entities component list // DestroyComp calls Destroy on the component and then removes it from the entities component list
func DestroyComp[T Comp](e *Entity) { func DestroyComp[T Comp](e *CompContainer) {
for i := 0; i < len(e.Comps); i++ { for i := 0; i < len(e.Comps); i++ {

View File

@ -16,22 +16,14 @@ const (
type EntityHandle uint64 type EntityHandle uint64
type Entity struct { type Entity struct {
// Byte 1: Generation; Byte 2: Flags; Bytes 3-8: Index // Byte 1: Generation; Byte 2: Flags; Bytes 3-8: Index
ID EntityHandle ID EntityHandle
Comps []Comp
} }
func (e *Entity) HasFlag(ef EntityFlag) bool { func (e *Entity) HasFlag(ef EntityFlag) bool {
return GetFlags(e.ID)&ef > 0 return GetFlags(e.ID)&ef > 0
} }
func (e *Entity) UpdateAllComps() {
for i := 0; i < len(e.Comps); i++ {
e.Comps[i].Update()
}
}
func GetGeneration(id EntityHandle) byte { func GetGeneration(id EntityHandle) byte {
return byte(id >> GenerationShiftBits) return byte(id >> GenerationShiftBits)
} }

View File

@ -76,7 +76,7 @@ func (r *Registry) GetEntity(id EntityHandle) *Entity {
return e return e
} }
// FreeEntity calls Destroy on all the entities components, resets the component list, resets the entity flags, then ads this entity to the free list // FreeEntity resets the entity flags then adds this entity to the free list
func (r *Registry) FreeEntity(id EntityHandle) { func (r *Registry) FreeEntity(id EntityHandle) {
e := r.GetEntity(id) e := r.GetEntity(id)
@ -84,14 +84,9 @@ func (r *Registry) FreeEntity(id EntityHandle) {
return return
} }
for i := 0; i < len(e.Comps); i++ {
e.Comps[i].Destroy()
}
r.EntityCount-- r.EntityCount--
eIndex := GetIndex(e.ID) eIndex := GetIndex(e.ID)
e.Comps = []Comp{}
e.ID = NewEntityId(GetGeneration(e.ID), EntityFlag_None, eIndex) e.ID = NewEntityId(GetGeneration(e.ID), EntityFlag_None, eIndex)
r.FreeList = &freeListitem{ r.FreeList = &freeListitem{

View File

@ -89,16 +89,17 @@ func Test() {
lvl := level.NewLevel("test level", 1000) lvl := level.NewLevel("test level", 1000)
e1 := lvl.Registry.NewEntity() e1 := lvl.Registry.NewEntity()
e1CompContainer := entity.NewCompContainer()
trComp := entity.GetComp[*TransformComp](e1) trComp := entity.GetComp[*TransformComp](&e1CompContainer)
fmt.Println("Get comp before adding any:", trComp) fmt.Println("Get comp before adding any:", trComp)
entity.AddComp(e1, &TransformComp{ entity.AddComp(e1, &e1CompContainer, &TransformComp{
Pos: gglm.NewVec3(0, 0, 0), Pos: gglm.NewVec3(0, 0, 0),
Rot: gglm.NewQuatEulerXYZ(0, 0, 0), Rot: gglm.NewQuatEulerXYZ(0, 0, 0),
Scale: gglm.NewVec3(0, 0, 0), Scale: gglm.NewVec3(0, 0, 0),
}) })
trComp = entity.GetComp[*TransformComp](e1) trComp = entity.GetComp[*TransformComp](&e1CompContainer)
fmt.Println("Get transform comp:", trComp) fmt.Println("Get transform comp:", trComp)
fmt.Printf("Entity: %+v\n", e1) fmt.Printf("Entity: %+v\n", e1)