Skip to content

Commit

Permalink
Implements GetComponents (#128)
Browse files Browse the repository at this point in the history
  • Loading branch information
gin authored Mar 23, 2024
1 parent a8d962e commit 34c2e5d
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 0 deletions.
5 changes: 5 additions & 0 deletions component.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ type ComponentType[T any] struct {
query *Query
}

// Typ returns the reflect.Type of the ComponentType.
func (c *ComponentType[T]) Typ() reflect.Type {
return c.typ
}

// Get returns component data from the entry.
func (c *ComponentType[T]) Get(entry *Entry) *T {
return (*T)(entry.Component(c))
Expand Down
2 changes: 2 additions & 0 deletions component/component.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package component

import (
"reflect"
"unsafe"
)

Expand All @@ -11,5 +12,6 @@ type (
type IComponentType interface {
Id() ComponentTypeId
New() unsafe.Pointer
Typ() reflect.Type
Name() string
}
18 changes: 18 additions & 0 deletions entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package donburi
import (
"bytes"
"fmt"
"reflect"
"unsafe"

"github.com/yohamta/donburi/component"
Expand All @@ -23,6 +24,23 @@ func Get[T any](e *Entry, ctype component.IComponentType) *T {
return (*T)(e.Component(ctype))
}

// GetComponents uses reflection to convert the unsafe.Pointers of an entry into its component data instances.
// Note that this is likely to be slow and should not be used in hot paths or if not necessary.
func GetComponents(e *Entry) []any {
archetypeIdx := e.loc.Archetype
s := e.World.StorageAccessor().Archetypes[archetypeIdx]
cs := s.ComponentTypes()
var instances []any
for _, ctyp := range cs {
instancePtr := e.Component(ctyp)
componentType := ctyp.Typ()
val := reflect.NewAt(componentType, instancePtr)
valInstance := reflect.Indirect(val).Interface()
instances = append(instances, valInstance)
}
return instances
}

// Add adds the component to the entry.
func Add[T any](e *Entry, ctype component.IComponentType, component *T) {
e.AddComponent(ctype, unsafe.Pointer(component))
Expand Down
5 changes: 5 additions & 0 deletions internal/storage/archetype.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ func (archetype *Archetype) Entities() []Entity {
return archetype.entities
}

// ComponentTypes returns a slice of all component types in the archetype.
func (archetype *Archetype) ComponentTypes() []component.IComponentType {
return archetype.Layout().componentTypes
}

// SwapRemove removes an entity from the archetype and returns it.
func (archetype *Archetype) SwapRemove(entity_index int) Entity {
removed := archetype.entities[entity_index]
Expand Down

0 comments on commit 34c2e5d

Please sign in to comment.