Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implements GetComponents #128

Merged
merged 1 commit into from
Mar 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading