Add Init,Update,Destroy to Comp+HasComp,DestroyComp funcs

This commit is contained in:
bloeys
2022-12-06 06:07:49 +04:00
parent 84cd8c28c8
commit b025afe1b4
6 changed files with 73 additions and 30 deletions

View File

@ -1,12 +1,15 @@
package assert package assert
import ( import (
"fmt"
"github.com/bloeys/nmage/consts" "github.com/bloeys/nmage/consts"
"github.com/bloeys/nmage/logging" "github.com/bloeys/nmage/logging"
) )
func T(check bool, msg string) { func T(check bool, msg string, args ...any) {
if consts.Debug && !check { if consts.Debug && !check {
logging.ErrLog.Panicln("Assert failed:", msg) logging.ErrLog.Panicln("Assert failed:", fmt.Sprintf(msg, args...))
} }
} }

27
entity/base_comp.go Executable file
View File

@ -0,0 +1,27 @@
package entity
import "github.com/bloeys/nmage/assert"
var _ Comp = &BaseComp{}
type BaseComp struct {
Entity *Entity
}
func (b *BaseComp) base() {
}
func (b *BaseComp) Init(parent *Entity) {
assert.T(parent != nil, "Component was initialized with a nil parent. That is not allowed.")
b.Entity = parent
}
func (b *BaseComp) Name() string {
return "Base Component"
}
func (b *BaseComp) Update() {
}
func (b *BaseComp) Destroy() {
}

View File

@ -1,27 +1,37 @@
package entity package entity
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() base()
Name() string Name() string
Init(parent *Entity)
Update()
Destroy()
} }
var _ Comp = &BaseComp{} func AddComp[T Comp](e *Entity, c T) {
type BaseComp struct { assert.T(!HasComp[T](e), "Entity with id %v already has component with name %s", e.ID, c.Name())
}
func (b *BaseComp) base() {
}
func (b *BaseComp) Name() string {
return "Base Component"
}
func AddComp(e *Entity, c Comp) {
e.Comps = append(e.Comps, c) e.Comps = append(e.Comps, c)
c.Init(e)
}
func HasComp[T Comp](e *Entity) bool {
for i := 0; i < len(e.Comps); i++ {
_, ok := e.Comps[i].(T)
if ok {
return true
}
}
return false
} }
func GetComp[T Comp](e *Entity) (out T) { func GetComp[T Comp](e *Entity) (out T) {
@ -37,16 +47,16 @@ func GetComp[T Comp](e *Entity) (out T) {
return out return out
} }
func GetAllCompOfType[T Comp](e *Entity) (out []T) { // DestroyComp calls Destroy on the component and then removes it from the entities component list
func DestroyComp[T Comp](e *Entity) {
out = []T{}
for i := 0; i < len(e.Comps); i++ { for i := 0; i < len(e.Comps); i++ {
comp, ok := e.Comps[i].(T) comp, ok := e.Comps[i].(T)
if ok { if ok {
out = append(out, comp) comp.Destroy()
e.Comps = append(e.Comps[:i], e.Comps[i+1:]...)
return
} }
} }
return out
} }

View File

@ -13,29 +13,31 @@ const (
IndexBitMask = 0x00_00_FFFF_FFFF_FFFF IndexBitMask = 0x00_00_FFFF_FFFF_FFFF
) )
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 uint64 ID EntityHandle
Comps []Comp Comps []Comp
} }
func GetGeneration(id uint64) byte { func GetGeneration(id EntityHandle) byte {
return byte(id >> GenerationShiftBits) return byte(id >> GenerationShiftBits)
} }
func GetFlags(id uint64) EntityFlag { func GetFlags(id EntityHandle) EntityFlag {
return EntityFlag(id >> FlagsShiftBits) return EntityFlag(id >> FlagsShiftBits)
} }
func GetIndex(id uint64) uint64 { func GetIndex(id EntityHandle) uint64 {
return id & IndexBitMask return uint64(id & IndexBitMask)
} }
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 NewEntityId(generation byte, flags EntityFlag, index uint64) uint64 { func NewEntityId(generation byte, flags EntityFlag, index uint64) EntityHandle {
return index | (uint64(generation) << GenerationShiftBits) | (uint64(flags) << FlagsShiftBits) return EntityHandle(index | (uint64(generation) << GenerationShiftBits) | (uint64(flags) << FlagsShiftBits))
} }

View File

@ -61,7 +61,7 @@ func (r *Registry) NewEntity() *Entity {
return entityToUse return entityToUse
} }
func (r *Registry) GetEntity(id uint64) *Entity { func (r *Registry) GetEntity(id EntityHandle) *Entity {
index := GetIndex(id) index := GetIndex(id)
gen := GetGeneration(id) gen := GetGeneration(id)
@ -76,13 +76,17 @@ func (r *Registry) GetEntity(id uint64) *Entity {
return e return e
} }
func (r *Registry) FreeEntity(id uint64) { func (r *Registry) FreeEntity(id EntityHandle) {
e := r.GetEntity(id) e := r.GetEntity(id)
if e == nil { if e == nil {
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)

View File

@ -103,9 +103,6 @@ func Test() {
trComp = entity.GetComp[*TransformComp](e1) trComp = entity.GetComp[*TransformComp](e1)
fmt.Println("Got comp 2:", trComp) fmt.Println("Got comp 2:", trComp)
trComps := entity.GetAllCompOfType[*TransformComp](e1)
fmt.Printf("Got comp 3: %+v, %+v\n", trComps[0], trComps[1])
fmt.Printf("Entity: %+v\n", e1) fmt.Printf("Entity: %+v\n", e1)
fmt.Printf("Entity: %+v\n", lvl.Registry.NewEntity()) fmt.Printf("Entity: %+v\n", lvl.Registry.NewEntity())
fmt.Printf("Entity: %+v\n", lvl.Registry.NewEntity()) fmt.Printf("Entity: %+v\n", lvl.Registry.NewEntity())