Documentation
¶
Index ¶
- func AddComp(w *World, e Entity, c Component)
- func DelComp(w *World, e Entity, c Component)
- func DelEntity(w *World, e Entity)
- func GetComp[C any](w *World, e Entity, c Component) (data *C)
- func HasComp(w *World, e Entity, c Component) bool
- func SetComp[C any](w *World, e Entity, c Component, data C)
- func Type(w *World, e Entity, nameComp Component) string
- type Archetype
- type ArchetypeEdge
- type CachedQuery
- type Component
- type ComponentMeta
- type Entity
- type EntityRecord
- type Filter
- type IDManager
- type Storage
- type Table
- type Types
- type World
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DelComp ¶
DelComp removes the Component of an Entity. If the Entity doesn't have the Component, nothing will happen.
func GetComp ¶
GetComp gets the data of a Component of an Entity. If the Entity doesn't have the Component, nil will be returned.
Types ¶
type ArchetypeEdge ¶
type ArchetypeEdge struct {
// contains filtered or unexported fields
}
type CachedQuery ¶
type CachedQuery struct {
// contains filtered or unexported fields
}
CachedQuery is cached filter
func (*CachedQuery) Free ¶
func (q *CachedQuery) Free(w *World)
func (*CachedQuery) Run ¶
func (q *CachedQuery) Run(h func(entities []Entity, data []any))
type Component ¶
type Component Entity
A Component is a type of which instances can be added and removed to entities. Each component can be added only once to an entity.
--flecs.dev
func NewComponent ¶
NewComponent creates a new Component in the World. The data type associated with the Component will be bind when the first data is set.
type ComponentMeta ¶
type Entity ¶
type Entity uint64
An Entity is a unique thing in the world, and is represented by a 64-bit id. Entities can be created and deleted. If an entity is deleted, it is no longer considered "alive".
A world can contain up to 4 billion alive entities. Entity identifiers contain a few bits that make it possible to check whether an entity is alive or not.
--flecs.dev
Example (Basic) ¶
type ( Position struct{ x, y float64 } Walking struct{} ) w := ecs.NewWorld() name := ecs.NewComponent(w) ecs.SetComp(w, ecs.Entity(name), name, "Name") position := ecs.NewComponent(w) ecs.SetComp(w, ecs.Entity(position), name, "Position") walking := ecs.NewComponent(w) ecs.SetComp(w, ecs.Entity(walking), name, "Walking") // Create an entity with name Bob bob := ecs.NewEntity(w) ecs.SetComp(w, bob, name, "Bob") // The set operation finds or creates a component, and sets it. ecs.SetComp(w, bob, position, Position{10, 20}) // The add operation adds a component without setting a value. This is // useful for tags, or when adding a component with its default value. ecs.SetComp(w, bob, walking, Walking{}) // Get the value for the Position component pos := ecs.GetComp[Position](w, bob, position) fmt.Printf("{%f, %f}\n", pos.x, pos.y) // Overwrite the value of the Position component ecs.SetComp(w, bob, position, Position{20, 30}) // Create another named entity alice := ecs.NewEntity(w) ecs.SetComp(w, alice, name, "Alice") ecs.SetComp(w, alice, position, Position{10, 20}) ecs.SetComp(w, alice, walking, Walking{}) // Print all the Components the entity has. This will output: // Position, Walking, (Identifier,Name) fmt.Printf("[%s]\n", ecs.Type(w, alice, name)) // Iterate all entities with Position ecs.QueryAll(position).Run(w, func(entities []ecs.Entity, data []any) { p := *data[0].(*[]Position) for i, e := range entities { entityName := ecs.GetComp[string](w, e, name) fmt.Printf("%s: {%f, %f}\n", *entityName, p[i].x, p[i].y) } }) // DelComp tag ecs.DelComp(w, alice, walking)
Output: {10.000000, 20.000000} [Name, Position, Walking] Bob: {20.000000, 30.000000} Alice: {10.000000, 20.000000}
type EntityRecord ¶
type Filter ¶
func QueryAll ¶
Example ¶
w := ecs.NewWorld() // Create 10 entities. var entities [10]ecs.Entity for i := range entities { entities[i] = ecs.NewEntity(w) } // Create 2 Components. c1 := ecs.NewComponent(w) c2 := ecs.NewComponent(w) // Add Components to entities. for i, e := range entities[:5] { ecs.SetComp(w, e, c1, i) } for i, e := range entities[3:7] { ecs.SetComp(w, e, c2, i+3) } // Current layout: // // entity:[0 1 2 3 4 5 6 7 8 9] // c1: [0 1 2 3 4 ] // c2: [ 3 4 5 6 ] // c1&c2: [ 3 4 ] // CachedQuery all entities which have both c1 and c2. ecs.QueryAll(c1, c2).Run(w, func(entities []ecs.Entity, data []any) { // The type of the data's element is `Table[T]`, // which can be converted to `[]T` only after type assertion. fmt.Println(*data[0].(*[]int)) })
Output: [3 4]
Example (Iter) ¶
w := ecs.NewWorld() // Create 10 entities. var entities [10]ecs.Entity for i := range entities { entities[i] = ecs.NewEntity(w) } // Create 2 Components. c1 := ecs.NewComponent(w) c2 := ecs.NewComponent(w) // Add Components to entities. for i, e := range entities[:5] { ecs.SetComp(w, e, c1, i) } for i, e := range entities[3:7] { ecs.SetComp(w, e, c2, i+3) } // Current layout: // // entity:[0 1 2 3 4 5 6 7 8 9] // c1: [0 1 2 3 4 ] // c2: [ 3 4 5 6 ] // c1&c2: [ 3 4 ] // CachedQuery all entities which have both c1 and c2. for entity, components := range ecs.QueryAll(c1, c2).Iter(w) { // The type of the data's element is `Table[T]`, // which can be converted to `[]T` only after type assertion. fmt.Println(entity, components) }
Output: 3 [3 3] 4 [4 4]
func QueryAny ¶
Example ¶
w := ecs.NewWorld() // Create 10 entities. var entities [10]ecs.Entity for i := range entities { entities[i] = ecs.NewEntity(w) } // Create 2 Components. c1 := ecs.NewComponent(w) c2 := ecs.NewComponent(w) // Add Components to entities. for i, e := range entities[:5] { ecs.SetComp(w, e, c1, int32(i)) } for i, e := range entities[3:7] { ecs.SetComp(w, e, c2, int64(i+3)) } // Current layout: // // entity:[0 1 2 3 4 5 6 7 8 9] // c1: [0 1 2 3 4 ] // c2: [ 3 4 5 6 ] // c1&c2: [ 3 4 ] // CachedQuery all entities which have c1 or c2. var results []string ecs.QueryAny(c1, c2).Run(w, func(entities []ecs.Entity, data []any) { // The type of the data's element is `Table[T]`, // which can be converted to `[]T` only after type assertion. var sb strings.Builder fmt.Fprintf(&sb, "%v:", entities) if data[0] != nil { fmt.Fprintf(&sb, " c1: [%v]", *data[0].(*[]int32)) } if data[1] != nil { fmt.Fprintf(&sb, " c2: [%v]", *data[1].(*[]int64)) } results = append(results, sb.String()) }) sort.Strings(results) fmt.Print(strings.Join(results, "\n"))
Output: [0 1 2]: c1: [[0 1 2]] [3 4]: c1: [[3 4]] c2: [[3 4]] [5 6]: c2: [[5 6]]
Example (Cache_iter) ¶
w := ecs.NewWorld() // Create 10 entities. var entities [10]ecs.Entity for i := range entities { entities[i] = ecs.NewEntity(w) } // Create 2 Components. c1 := ecs.NewComponent(w) c2 := ecs.NewComponent(w) // Cache query query := ecs.QueryAny(c1, c2).Cache(w) // Add Components to entities. for i, e := range entities[:5] { ecs.SetComp(w, e, c1, int32(i)) } for i, e := range entities[3:7] { ecs.SetComp(w, e, c2, int64(i+3)) } // Current layout: // // entity:[0 1 2 3 4 5 6 7 8 9] // c1: [0 1 2 3 4 ] // c2: [ 3 4 5 6 ] // c1&c2: [ 3 4 ] // CachedQuery all entities which have c1 or c2. var results []string for entity, data := range query.Iter { // The type of the data's element is `Table[T]`, // which can be converted to `[]T` only after type assertion. results = append(results, fmt.Sprintf("e%v: [c1: %v c2: %v]", entity, data[0], data[1])) } sort.Strings(results) fmt.Print(strings.Join(results, "\n"))
Output: e0: [c1: 0 c2: <nil>] e1: [c1: 1 c2: <nil>] e2: [c1: 2 c2: <nil>] e3: [c1: 3 c2: 3] e4: [c1: 4 c2: 4] e5: [c1: <nil> c2: 5] e6: [c1: <nil> c2: 6]
Example (Iter) ¶
w := ecs.NewWorld() // Create 10 entities. var entities [10]ecs.Entity for i := range entities { entities[i] = ecs.NewEntity(w) } // Create 2 Components. c1 := ecs.NewComponent(w) c2 := ecs.NewComponent(w) // Add Components to entities. for i, e := range entities[:5] { ecs.SetComp(w, e, c1, int32(i)) } for i, e := range entities[3:7] { ecs.SetComp(w, e, c2, int64(i+3)) } // Current layout: // // entity:[0 1 2 3 4 5 6 7 8 9] // c1: [0 1 2 3 4 ] // c2: [ 3 4 5 6 ] // c1&c2: [ 3 4 ] // CachedQuery all entities which have c1 or c2. var results []string for entity, data := range ecs.QueryAny(c1, c2).Iter(w) { // The type of the data's element is `Table[T]`, // which can be converted to `[]T` only after type assertion. results = append(results, fmt.Sprintf("e%v: [c1: %v c2: %v]", entity, data[0], data[1])) } sort.Strings(results) fmt.Print(strings.Join(results, "\n"))
Output: e0: [c1: 0 c2: <nil>] e1: [c1: 1 c2: <nil>] e2: [c1: 2 c2: <nil>] e3: [c1: 3 c2: 3] e4: [c1: 4 c2: 4] e5: [c1: <nil> c2: 5] e6: [c1: <nil> c2: 6]
func (Filter) Cache ¶
func (f Filter) Cache(w *World) (q *CachedQuery)
type IDManager ¶
The IDManager is an internal structure which is used to generate/recycle entity IDs.
type Types ¶
type Types []ComponentMeta
Types is list of Components. It's sorted and able to be hashed. Allowing us to find the archetype by the hash of its type.
type World ¶
type World struct { IDManager // The default archetype for newly created entities, which contains no Components. Zero *Archetype // All entities in the World, including Components. // Records their archetype's pointer and the index of the Comps belonging to the entity. Entities map[Entity]*EntityRecord // All archetypes in the World. // The key of the map is the hash of the archetype's Types. // And the value is the archetype's pointer. Archetypes map[uint64]*Archetype // This field stores maps for each component. // Each map contains a list of archetypes that have the component. // And the component's corresponding Storage index in the archetype. // // We can check if an archetype has a component by looking up the map. // // For any Component c and archetype a: // col, ok := Components[c][a] // If ok == true, then archetype a has component c, otherwise it doesn't. // And if col == -1, archetype a has component c but doesn't contain any data, // otherwise the col is the index of the component's Storage in the archetype. Components map[Component]map[*Archetype]int // For high performance, we cache the queries. // But these caches will get outdated when new archetypes are created. // We register all queries created here, and update them when new archetypes are created. Queries Table[*CachedQuery] // contains filtered or unexported fields }
The World is the container for all ECS data. It stores the entities and their Components, does queries and runs systems.
--flecs.dev