diff --git a/assert/assert.go b/assert/assert.go index 8505eaf..8c14a87 100755 --- a/assert/assert.go +++ b/assert/assert.go @@ -1,12 +1,15 @@ package assert import ( + "fmt" + "github.com/bloeys/nmage/consts" "github.com/bloeys/nmage/logging" ) -func T(check bool, msg string) { +func T(check bool, msg string, args ...any) { + if consts.Debug && !check { - logging.ErrLog.Panicln("Assert failed:", msg) + logging.ErrLog.Panicln("Assert failed:", fmt.Sprintf(msg, args...)) } } diff --git a/entity/base_comp.go b/entity/base_comp.go new file mode 100755 index 0000000..8ca1d4b --- /dev/null +++ b/entity/base_comp.go @@ -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() { +} diff --git a/entity/comp.go b/entity/comp.go index 12576ca..633f0c4 100755 --- a/entity/comp.go +++ b/entity/comp.go @@ -1,27 +1,37 @@ package entity +import "github.com/bloeys/nmage/assert" + type Comp interface { // This ensures that implementors of the Comp interface // always embed BaseComp base() 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) + 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) { @@ -37,16 +47,16 @@ func GetComp[T Comp](e *Entity) (out T) { 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++ { comp, ok := e.Comps[i].(T) if ok { - out = append(out, comp) + comp.Destroy() + e.Comps = append(e.Comps[:i], e.Comps[i+1:]...) + return } } - - return out } diff --git a/entity/entity.go b/entity/entity.go index f4cc35e..451c81e 100755 --- a/entity/entity.go +++ b/entity/entity.go @@ -13,29 +13,31 @@ const ( IndexBitMask = 0x00_00_FFFF_FFFF_FFFF ) +type EntityHandle uint64 + type Entity struct { // Byte 1: Generation; Byte 2: Flags; Bytes 3-8: Index - ID uint64 + ID EntityHandle Comps []Comp } -func GetGeneration(id uint64) byte { +func GetGeneration(id EntityHandle) byte { return byte(id >> GenerationShiftBits) } -func GetFlags(id uint64) EntityFlag { +func GetFlags(id EntityHandle) EntityFlag { return EntityFlag(id >> FlagsShiftBits) } -func GetIndex(id uint64) uint64 { - return id & IndexBitMask +func GetIndex(id EntityHandle) uint64 { + return uint64(id & IndexBitMask) } func (e *Entity) HasFlag(ef EntityFlag) bool { return GetFlags(e.ID)&ef > 0 } -func NewEntityId(generation byte, flags EntityFlag, index uint64) uint64 { - return index | (uint64(generation) << GenerationShiftBits) | (uint64(flags) << FlagsShiftBits) +func NewEntityId(generation byte, flags EntityFlag, index uint64) EntityHandle { + return EntityHandle(index | (uint64(generation) << GenerationShiftBits) | (uint64(flags) << FlagsShiftBits)) } diff --git a/entity/registry.go b/entity/registry.go index fd6ae3b..efb358a 100755 --- a/entity/registry.go +++ b/entity/registry.go @@ -61,7 +61,7 @@ func (r *Registry) NewEntity() *Entity { return entityToUse } -func (r *Registry) GetEntity(id uint64) *Entity { +func (r *Registry) GetEntity(id EntityHandle) *Entity { index := GetIndex(id) gen := GetGeneration(id) @@ -76,13 +76,17 @@ func (r *Registry) GetEntity(id uint64) *Entity { return e } -func (r *Registry) FreeEntity(id uint64) { +func (r *Registry) FreeEntity(id EntityHandle) { e := r.GetEntity(id) if e == nil { return } + for i := 0; i < len(e.Comps); i++ { + e.Comps[i].Destroy() + } + r.EntityCount-- eIndex := GetIndex(e.ID) diff --git a/main.go b/main.go index 835598a..aaa36f4 100755 --- a/main.go +++ b/main.go @@ -103,9 +103,6 @@ func Test() { trComp = entity.GetComp[*TransformComp](e1) 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", lvl.Registry.NewEntity()) fmt.Printf("Entity: %+v\n", lvl.Registry.NewEntity())