ecs

package module
v0.0.0-...-95e3a34 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 18, 2023 License: MIT Imports: 8 Imported by: 0

README

Go Reference Build

This is an ecs library I wrote for doing game development in Go. I'm actively using it and its pretty stable, but I do find bugs every once in a while. I might vary the APIs in the future if native iterators are added.

Overview

Conceptually you can imagine an ECS as one big table, where an Id column associates an Entity Id with various other component columns. Kind of like this:

Id Position Rotation Size
0 {1, 1} 3.14 11
1 {2, 2} 6.28 22

We use an archetype-based storage mechanism. Which simply means we have a specific table for a specific component layout. This means that if you add or remove components it can be somewhat expensive, because we have to copy the entire entity to the new table.

Basic Usage

Import the library: import "github.com/unitoftime/ecs"

Create Components like you normally would:

type Position struct {
    X, Y float64
}

type Rotation float64

Create a World to store all of your data

world := ecs.NewWorld()

Create an entity and add components to it

id := world.NewId()
ecs.Write(world, id,
    ecs.C(Position{1, 1}),
    ecs.C(Rotation(3.14)),
    // Note: Try to reduce the number of write calls by packing as many components as you can in
)

// Side-Note: I'm trying to get rid of the `ecs.C(...)` boxing, but I couldn't figure out how when
//            I first wrote the ECS. I'll try to get back to fixing that because ideally you
//            shouldn't have to worry about it. For now though, you have to box your components
//            to the `ecs.Component` interface type before passing them in, so `ecs.C(...)`
//            does that for you.

Create a View, by calling QueryN:

query := ecs.Query2[Position, Rotation](world)

Iterate on the query. You basically pass in a lambda, and internally the library calls it for every entity in the world which has all of the components specified. Notably your lambda takes pointer values which represent a pointer to the internally stored component. So modifying these pointers will modify the entity's data.

query.MapId(func(id ecs.Id, pos *Position, rot *Rotation) {
    pos.X += 1
    pos.Y += 1

    rot += 0.01
})

There are several map functions you can use, each with varying numbers of parameters. I support up to Map12. They all look like this:

ecs.MapN(world, func(id ecs.Id, a *ComponentA, /*... */, n *ComponentN) {
    // Do your work
})

Advanced queries

You can also filter your queries for more advanced usage:

// Returns a view of Position and Velocity, but only if the entity also has the `Rotation` component.
query := ecs.Query2[Position, Velocity](world, ecs.With(Rotation))

// Returns a view of Position and Velocity, but if velocity is missing on the entity, will just return nil during the `MapId(...)`. You must do nil checks for all components included in the `Optional()`!
query := ecs.Query2[Position, Velocity](world, ecs.Optional(Velocity))

Commands

Commands will eventually replace ecs.Write(...) once I figure out how their usage will work. Commands essentially buffer some work on the ECS so that the work can be executed later on. You can use them in loop safe ways by calling Execute() after your loop has completed. Right now they work like this:

cmd := ecs.NewCommand(world)
WriteCmd(cmd, id, Position{1,1,1})
WriteCmd(cmd, id, Velocity{1,1,1})
cmd.Execute()

Still In Progress

Videos

Hopefully, eventually I can have some automated test-bench that runs and measures performance, but for now you'll just have to refer to my second video and hopefully trust me. Of course, you can run the benchmark in the bench folder to measure how long frames take on your computer.

  1. How it works: https://youtu.be/71RSWVyOMEY
  2. Simulation Performance: https://youtu.be/i2gWDOgg50k

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Delete

func Delete(world *World, id Id) bool

Deletes the entire entity specified by the id This can be called inside maps and loops, it will delete the entity immediately. Returns true if the entity exists and was actually deleted, else returns false

func Optional

func Optional(comps ...any) optional

Creates a filter to make the query still iterate even if a specific component is missing, in which case you'll get nil if the component isn't there when accessed

func Read

func Read[T any](world *World, id Id) (T, bool)

Reads a specific component of the entity specified at id. Returns true if the entity was found and had that component, else returns false. Deprecated: This API is tentative, I'm trying to improve the QueryN construct so that it can capture this usecase.

func ReadFromEntity

func ReadFromEntity[T any](ent *Entity) (T, bool)

Reads a specific component from the entity, returns false if the component doesn't exist

func ReadPtr

func ReadPtr[T any](world *World, id Id) *T

Reads a pointer to the component of the entity at the specified id. Returns true if the entity was found and had that component, else returns false. This pointer is short lived and can become invalid if any other entity changes in the world Deprecated: This API is tentative, I'm trying to improve the QueryN construct so that it can capture this usecase.

func With

func With(comps ...any) with

Creates a filter to ensure that entities have the specified components

func Write

func Write(world *World, id Id, comp ...Component)

Writes components to the entity specified at id. This API can potentially break if you call it inside of a loop. Specifically, if you cause the archetype of the entity to change by writing a new component, then the loop may act in mysterious ways. Deprecated: This API is tentative, I might replace it with something similar to bevy commands to alleviate the above concern

func WriteCmd

func WriteCmd[A any](c *Command, id Id, comp A)

TODO - maybe rename as just Write? Adds a write command

Types

type Box

type Box[T any] struct {
	Comp T
	// contains filtered or unexported fields
}

This type is used to box a component with all of its type info so that it implements the component interface. I would like to get rid of this and simplify the APIs

func C

func C[T any](comp T) Box[T]

Createst the boxed component type

func (Box[T]) Get

func (c Box[T]) Get() T

type Command

type Command struct {
	// contains filtered or unexported fields
}

Represents a list of commands that need to be executed on the world

func NewCommand

func NewCommand(world *World) *Command

Create a new command to be executed

func (*Command) Execute

func (c *Command) Execute()

Execute the command

type Component

type Component interface {
	// contains filtered or unexported methods
}

type Entity

type Entity struct {
	// contains filtered or unexported fields
}

An Entity is essentially a map of components that is held external to a world. Useful for pulling full entities in and out of the world. Deprecated: This type and its corresponding methods are tentative and might be replaced by something else.

func NewEntity

func NewEntity(components ...Component) *Entity

Creates a new entity with the specified components

func ReadEntity

func ReadEntity(world *World, id Id) *Entity

Reads the entire entity out of the world and into an *Entity object. Returns nil if the entity doesn't exist

func (*Entity) Add

func (e *Entity) Add(components ...Component)

Adds a component to an entity

func (*Entity) Clear

func (e *Entity) Clear()

Clears the map, but retains the space

func (*Entity) Comps

func (e *Entity) Comps() []Component

Returns a list of the components held by the entity

func (*Entity) Delete

func (e *Entity) Delete(c Component)

Deletes a component on this entity

func (*Entity) Merge

func (e *Entity) Merge(e2 *Entity)

Merges e2 on top of e (meaning that we will overwrite e with values from e2)

func (*Entity) Write

func (ent *Entity) Write(world *World, id Id)

Writes the entire entity to the world

type Filter

type Filter interface {
	Filter([]componentId) []componentId
}

TODO - Filter types: Optional - Lets you view even if component is missing (func will return nil) With - Lets you add additional components that must be present Without - Lets you add additional components that must not be present

type Id

type Id uint32

This is the identifier for entities in the world

const (
	InvalidEntity Id = 0 // Represents the default entity Id, which is invalid

	MaxEntity Id = math.MaxUint32
)

func (*Id) DecodeCod

func (t *Id) DecodeCod(bs []byte) (int, error)

func (Id) EncodeCod

func (t Id) EncodeCod(bs []byte) []byte

type RawEntity

type RawEntity struct {
	// contains filtered or unexported fields
}

A RawEntity is like an Entity, but every component is actually a pointer to the underlying component. I mostly use this to build inspector UIs that can directly modify an entity Deprecated: This type and its corresponding methods are tentative and might be replaced by something else.

func NewRawEntity

func NewRawEntity(components ...any) *RawEntity

Creates a new entity with the specified components

func ReadRawEntity

func ReadRawEntity(world *World, id Id) *RawEntity

Reads the entire entity out of the world and into an *RawEntity object. Returns nil if the entity doesn't exist. RawEntity is lik

func (*RawEntity) Add

func (e *RawEntity) Add(components ...any)

Adds a component to an entity

func (*RawEntity) Clear

func (e *RawEntity) Clear()

Clears the map, but retains the space

func (*RawEntity) Comps

func (e *RawEntity) Comps() []any

Returns a list of the components held by the entity

func (*RawEntity) Delete

func (e *RawEntity) Delete(c Component)

Deletes a component on this entity

func (*RawEntity) Merge

func (e *RawEntity) Merge(e2 *RawEntity)

Merges e2 on top of e (meaning that we will overwrite e with values from e2)

type Scheduler

type Scheduler struct {
	// contains filtered or unexported fields
}

Scheduler is a place to put your systems and have them run. There are two types of systems: Fixed time systems and dynamic time systems 1. Fixed time systems will execute on a fixed time step 2. Dynamic time systems will execute as quickly as they possibly can The scheduler may change in the future, but right now how it works is simple: Input: Execute input systems (Dynamic time systems) Physics: Execute physics systems (Fixed time systems) Render: Execute render systems (Dynamic time systems)

func NewScheduler

func NewScheduler() *Scheduler

Creates a scheduler

func (*Scheduler) AppendInput

func (s *Scheduler) AppendInput(systems ...System)

Adds a system to the list of input systems

func (*Scheduler) AppendPhysics

func (s *Scheduler) AppendPhysics(systems ...System)

Adds a system to the list of physics systems

func (*Scheduler) AppendRender

func (s *Scheduler) AppendRender(systems ...System)

Adds a system to the list of render systems

func (*Scheduler) GetRenderInterp

func (s *Scheduler) GetRenderInterp() float64

Returns an interpolation value which represents how close we are to the next fixed time step execution. Can be useful for interpolating dynamic time systems to the fixed time systems. I might rename this

func (*Scheduler) PauseRender

func (s *Scheduler) PauseRender(value bool)

Pauses the set of render systems (ie they will be skipped). Deprecated: This API is tentatitive

func (*Scheduler) Run

func (s *Scheduler) Run()

Note: Would be nice to sleep or something to prevent spinning while we wait for work to do Could also separate the render loop from the physics loop (requires some thread safety in ECS)

func (*Scheduler) SetFixedTimeStep

func (s *Scheduler) SetFixedTimeStep(t time.Duration)

Sets the amount of time required before the fixed time systems will execute

func (*Scheduler) SetMaxPhysicsLoopCount

func (s *Scheduler) SetMaxPhysicsLoopCount(count int)

Sets the accumulator maximum point so that if the accumulator gets way to big, we will reset it and continue on, dropping all physics ticks that would have been executed. This is useful in a runtime like WASM where the browser may not let us run as frequently as we may need (for example, when the tab is hidden or minimized). Note: This must be set before you call scheduler.Run() Note: The default value is 0, which will force every physics tick to run. I highly recommend setting this to something if you plan to build for WASM!

func (*Scheduler) SetQuit

func (s *Scheduler) SetQuit(value bool)

Tells the scheduler to exit. Scheduler will finish executing its remaining tick before closing.

func (*Scheduler) Syslog

func (s *Scheduler) Syslog() []SystemLog

Returns the front syslog so the user can analyze it. Note: This is only valid for the current frame, you should call this every frame if you use it!

func (*Scheduler) SyslogFixed

func (s *Scheduler) SyslogFixed() []SystemLog

Returns the front syslog for fixed-dt systems only. Note: This is only valid for the current frame, you should call this every frame if you use it!

type System

type System struct {
	Name string
	Func func(dt time.Duration)
}

Represents an individual system

func NewSystem

func NewSystem(lambda func(dt time.Duration)) System

Create a new system. The system name will be automatically created based on the function name that calls this function

func (*System) Run

func (s *System) Run(dt time.Duration) time.Duration

Executes the system once, returning the time taken. This is mostly used by the scheduler, but you can use it too.

type SystemLog

type SystemLog struct {
	Name string
	Time time.Duration
}

A log of a system and the time it took to execute

func (*SystemLog) String

func (s *SystemLog) String() string

type View1

type View1[A any] struct {
	// contains filtered or unexported fields
}

Represents a view of data in a specific world. Provides access to the components specified in the generic block

func Query1

func Query1[A any](world *World, filters ...Filter) *View1[A]

Creates a View for the specified world with the specified component filters.

func (*View1[A]) MapId

func (v *View1[A]) MapId(lambda func(id Id, a *A))

Maps the lambda function across every entity which matched the specified filters.

func (*View1[A]) MapSlices deprecated

func (v *View1[A]) MapSlices(lambda func(id []Id, a []A))

Deprecated: This API is a tentative alternative way to map

func (*View1[A]) Read

func (v *View1[A]) Read(id Id) *A

Reads a pointer to the underlying component at the specified id. Read will return even if the specified id doesn't match the filter list Read will return the value if it exists, else returns nil. If you execute any ecs.Write(...) or ecs.Delete(...) this pointer may become invalid.

type View10

type View10[A, B, C, D, E, F, G, H, I, J any] struct {
	// contains filtered or unexported fields
}

Represents a view of data in a specific world. Provides access to the components specified in the generic block

func Query10

func Query10[A, B, C, D, E, F, G, H, I, J any](world *World, filters ...Filter) *View10[A, B, C, D, E, F, G, H, I, J]

Creates a View for the specified world with the specified component filters.

func (*View10[A, B, C, D, E, F, G, H, I, J]) MapId

func (v *View10[A, B, C, D, E, F, G, H, I, J]) MapId(lambda func(id Id, a *A, b *B, c *C, d *D, e *E, f *F, g *G, h *H, i *I, j *J))

Maps the lambda function across every entity which matched the specified filters.

func (*View10[A, B, C, D, E, F, G, H, I, J]) MapSlices deprecated

func (v *View10[A, B, C, D, E, F, G, H, I, J]) MapSlices(lambda func(id []Id, a []A, b []B, c []C, d []D, e []E, f []F, g []G, h []H, i []I, j []J))

Deprecated: This API is a tentative alternative way to map

func (*View10[A, B, C, D, E, F, G, H, I, J]) Read

func (v *View10[A, B, C, D, E, F, G, H, I, J]) Read(id Id) (*A, *B, *C, *D, *E, *F, *G, *H, *I, *J)

Reads a pointer to the underlying component at the specified id. Read will return even if the specified id doesn't match the filter list Read will return the value if it exists, else returns nil. If you execute any ecs.Write(...) or ecs.Delete(...) this pointer may become invalid.

type View11

type View11[A, B, C, D, E, F, G, H, I, J, K any] struct {
	// contains filtered or unexported fields
}

Represents a view of data in a specific world. Provides access to the components specified in the generic block

func Query11

func Query11[A, B, C, D, E, F, G, H, I, J, K any](world *World, filters ...Filter) *View11[A, B, C, D, E, F, G, H, I, J, K]

Creates a View for the specified world with the specified component filters.

func (*View11[A, B, C, D, E, F, G, H, I, J, K]) MapId

func (v *View11[A, B, C, D, E, F, G, H, I, J, K]) MapId(lambda func(id Id, a *A, b *B, c *C, d *D, e *E, f *F, g *G, h *H, i *I, j *J, k *K))

Maps the lambda function across every entity which matched the specified filters.

func (*View11[A, B, C, D, E, F, G, H, I, J, K]) MapSlices deprecated

func (v *View11[A, B, C, D, E, F, G, H, I, J, K]) MapSlices(lambda func(id []Id, a []A, b []B, c []C, d []D, e []E, f []F, g []G, h []H, i []I, j []J, k []K))

Deprecated: This API is a tentative alternative way to map

func (*View11[A, B, C, D, E, F, G, H, I, J, K]) Read

func (v *View11[A, B, C, D, E, F, G, H, I, J, K]) Read(id Id) (*A, *B, *C, *D, *E, *F, *G, *H, *I, *J, *K)

Reads a pointer to the underlying component at the specified id. Read will return even if the specified id doesn't match the filter list Read will return the value if it exists, else returns nil. If you execute any ecs.Write(...) or ecs.Delete(...) this pointer may become invalid.

type View12

type View12[A, B, C, D, E, F, G, H, I, J, K, L any] struct {
	// contains filtered or unexported fields
}

Represents a view of data in a specific world. Provides access to the components specified in the generic block

func Query12

func Query12[A, B, C, D, E, F, G, H, I, J, K, L any](world *World, filters ...Filter) *View12[A, B, C, D, E, F, G, H, I, J, K, L]

Creates a View for the specified world with the specified component filters.

func (*View12[A, B, C, D, E, F, G, H, I, J, K, L]) MapId

func (v *View12[A, B, C, D, E, F, G, H, I, J, K, L]) MapId(lambda func(id Id, a *A, b *B, c *C, d *D, e *E, f *F, g *G, h *H, i *I, j *J, k *K, l *L))

Maps the lambda function across every entity which matched the specified filters.

func (*View12[A, B, C, D, E, F, G, H, I, J, K, L]) MapSlices deprecated

func (v *View12[A, B, C, D, E, F, G, H, I, J, K, L]) MapSlices(lambda func(id []Id, a []A, b []B, c []C, d []D, e []E, f []F, g []G, h []H, i []I, j []J, k []K, l []L))

Deprecated: This API is a tentative alternative way to map

func (*View12[A, B, C, D, E, F, G, H, I, J, K, L]) Read

func (v *View12[A, B, C, D, E, F, G, H, I, J, K, L]) Read(id Id) (*A, *B, *C, *D, *E, *F, *G, *H, *I, *J, *K, *L)

Reads a pointer to the underlying component at the specified id. Read will return even if the specified id doesn't match the filter list Read will return the value if it exists, else returns nil. If you execute any ecs.Write(...) or ecs.Delete(...) this pointer may become invalid.

type View2

type View2[A, B any] struct {
	// contains filtered or unexported fields
}

Represents a view of data in a specific world. Provides access to the components specified in the generic block

func Query2

func Query2[A, B any](world *World, filters ...Filter) *View2[A, B]

Creates a View for the specified world with the specified component filters.

func (*View2[A, B]) MapId

func (v *View2[A, B]) MapId(lambda func(id Id, a *A, b *B))

Maps the lambda function across every entity which matched the specified filters.

func (*View2[A, B]) MapSlices deprecated

func (v *View2[A, B]) MapSlices(lambda func(id []Id, a []A, b []B))

Deprecated: This API is a tentative alternative way to map

func (*View2[A, B]) Read

func (v *View2[A, B]) Read(id Id) (*A, *B)

Reads a pointer to the underlying component at the specified id. Read will return even if the specified id doesn't match the filter list Read will return the value if it exists, else returns nil. If you execute any ecs.Write(...) or ecs.Delete(...) this pointer may become invalid.

type View3

type View3[A, B, C any] struct {
	// contains filtered or unexported fields
}

Represents a view of data in a specific world. Provides access to the components specified in the generic block

func Query3

func Query3[A, B, C any](world *World, filters ...Filter) *View3[A, B, C]

Creates a View for the specified world with the specified component filters.

func (*View3[A, B, C]) MapId

func (v *View3[A, B, C]) MapId(lambda func(id Id, a *A, b *B, c *C))

Maps the lambda function across every entity which matched the specified filters.

func (*View3[A, B, C]) MapSlices deprecated

func (v *View3[A, B, C]) MapSlices(lambda func(id []Id, a []A, b []B, c []C))

Deprecated: This API is a tentative alternative way to map

func (*View3[A, B, C]) Read

func (v *View3[A, B, C]) Read(id Id) (*A, *B, *C)

Reads a pointer to the underlying component at the specified id. Read will return even if the specified id doesn't match the filter list Read will return the value if it exists, else returns nil. If you execute any ecs.Write(...) or ecs.Delete(...) this pointer may become invalid.

type View4

type View4[A, B, C, D any] struct {
	// contains filtered or unexported fields
}

Represents a view of data in a specific world. Provides access to the components specified in the generic block

func Query4

func Query4[A, B, C, D any](world *World, filters ...Filter) *View4[A, B, C, D]

Creates a View for the specified world with the specified component filters.

func (*View4[A, B, C, D]) MapId

func (v *View4[A, B, C, D]) MapId(lambda func(id Id, a *A, b *B, c *C, d *D))

Maps the lambda function across every entity which matched the specified filters.

func (*View4[A, B, C, D]) MapSlices deprecated

func (v *View4[A, B, C, D]) MapSlices(lambda func(id []Id, a []A, b []B, c []C, d []D))

Deprecated: This API is a tentative alternative way to map

func (*View4[A, B, C, D]) Read

func (v *View4[A, B, C, D]) Read(id Id) (*A, *B, *C, *D)

Reads a pointer to the underlying component at the specified id. Read will return even if the specified id doesn't match the filter list Read will return the value if it exists, else returns nil. If you execute any ecs.Write(...) or ecs.Delete(...) this pointer may become invalid.

type View5

type View5[A, B, C, D, E any] struct {
	// contains filtered or unexported fields
}

Represents a view of data in a specific world. Provides access to the components specified in the generic block

func Query5

func Query5[A, B, C, D, E any](world *World, filters ...Filter) *View5[A, B, C, D, E]

Creates a View for the specified world with the specified component filters.

func (*View5[A, B, C, D, E]) MapId

func (v *View5[A, B, C, D, E]) MapId(lambda func(id Id, a *A, b *B, c *C, d *D, e *E))

Maps the lambda function across every entity which matched the specified filters.

func (*View5[A, B, C, D, E]) MapSlices deprecated

func (v *View5[A, B, C, D, E]) MapSlices(lambda func(id []Id, a []A, b []B, c []C, d []D, e []E))

Deprecated: This API is a tentative alternative way to map

func (*View5[A, B, C, D, E]) Read

func (v *View5[A, B, C, D, E]) Read(id Id) (*A, *B, *C, *D, *E)

Reads a pointer to the underlying component at the specified id. Read will return even if the specified id doesn't match the filter list Read will return the value if it exists, else returns nil. If you execute any ecs.Write(...) or ecs.Delete(...) this pointer may become invalid.

type View6

type View6[A, B, C, D, E, F any] struct {
	// contains filtered or unexported fields
}

Represents a view of data in a specific world. Provides access to the components specified in the generic block

func Query6

func Query6[A, B, C, D, E, F any](world *World, filters ...Filter) *View6[A, B, C, D, E, F]

Creates a View for the specified world with the specified component filters.

func (*View6[A, B, C, D, E, F]) MapId

func (v *View6[A, B, C, D, E, F]) MapId(lambda func(id Id, a *A, b *B, c *C, d *D, e *E, f *F))

Maps the lambda function across every entity which matched the specified filters.

func (*View6[A, B, C, D, E, F]) MapSlices deprecated

func (v *View6[A, B, C, D, E, F]) MapSlices(lambda func(id []Id, a []A, b []B, c []C, d []D, e []E, f []F))

Deprecated: This API is a tentative alternative way to map

func (*View6[A, B, C, D, E, F]) Read

func (v *View6[A, B, C, D, E, F]) Read(id Id) (*A, *B, *C, *D, *E, *F)

Reads a pointer to the underlying component at the specified id. Read will return even if the specified id doesn't match the filter list Read will return the value if it exists, else returns nil. If you execute any ecs.Write(...) or ecs.Delete(...) this pointer may become invalid.

type View7

type View7[A, B, C, D, E, F, G any] struct {
	// contains filtered or unexported fields
}

Represents a view of data in a specific world. Provides access to the components specified in the generic block

func Query7

func Query7[A, B, C, D, E, F, G any](world *World, filters ...Filter) *View7[A, B, C, D, E, F, G]

Creates a View for the specified world with the specified component filters.

func (*View7[A, B, C, D, E, F, G]) MapId

func (v *View7[A, B, C, D, E, F, G]) MapId(lambda func(id Id, a *A, b *B, c *C, d *D, e *E, f *F, g *G))

Maps the lambda function across every entity which matched the specified filters.

func (*View7[A, B, C, D, E, F, G]) MapSlices deprecated

func (v *View7[A, B, C, D, E, F, G]) MapSlices(lambda func(id []Id, a []A, b []B, c []C, d []D, e []E, f []F, g []G))

Deprecated: This API is a tentative alternative way to map

func (*View7[A, B, C, D, E, F, G]) Read

func (v *View7[A, B, C, D, E, F, G]) Read(id Id) (*A, *B, *C, *D, *E, *F, *G)

Reads a pointer to the underlying component at the specified id. Read will return even if the specified id doesn't match the filter list Read will return the value if it exists, else returns nil. If you execute any ecs.Write(...) or ecs.Delete(...) this pointer may become invalid.

type View8

type View8[A, B, C, D, E, F, G, H any] struct {
	// contains filtered or unexported fields
}

Represents a view of data in a specific world. Provides access to the components specified in the generic block

func Query8

func Query8[A, B, C, D, E, F, G, H any](world *World, filters ...Filter) *View8[A, B, C, D, E, F, G, H]

Creates a View for the specified world with the specified component filters.

func (*View8[A, B, C, D, E, F, G, H]) MapId

func (v *View8[A, B, C, D, E, F, G, H]) MapId(lambda func(id Id, a *A, b *B, c *C, d *D, e *E, f *F, g *G, h *H))

Maps the lambda function across every entity which matched the specified filters.

func (*View8[A, B, C, D, E, F, G, H]) MapSlices deprecated

func (v *View8[A, B, C, D, E, F, G, H]) MapSlices(lambda func(id []Id, a []A, b []B, c []C, d []D, e []E, f []F, g []G, h []H))

Deprecated: This API is a tentative alternative way to map

func (*View8[A, B, C, D, E, F, G, H]) Read

func (v *View8[A, B, C, D, E, F, G, H]) Read(id Id) (*A, *B, *C, *D, *E, *F, *G, *H)

Reads a pointer to the underlying component at the specified id. Read will return even if the specified id doesn't match the filter list Read will return the value if it exists, else returns nil. If you execute any ecs.Write(...) or ecs.Delete(...) this pointer may become invalid.

type View9

type View9[A, B, C, D, E, F, G, H, I any] struct {
	// contains filtered or unexported fields
}

Represents a view of data in a specific world. Provides access to the components specified in the generic block

func Query9

func Query9[A, B, C, D, E, F, G, H, I any](world *World, filters ...Filter) *View9[A, B, C, D, E, F, G, H, I]

Creates a View for the specified world with the specified component filters.

func (*View9[A, B, C, D, E, F, G, H, I]) MapId

func (v *View9[A, B, C, D, E, F, G, H, I]) MapId(lambda func(id Id, a *A, b *B, c *C, d *D, e *E, f *F, g *G, h *H, i *I))

Maps the lambda function across every entity which matched the specified filters.

func (*View9[A, B, C, D, E, F, G, H, I]) MapSlices deprecated

func (v *View9[A, B, C, D, E, F, G, H, I]) MapSlices(lambda func(id []Id, a []A, b []B, c []C, d []D, e []E, f []F, g []G, h []H, i []I))

Deprecated: This API is a tentative alternative way to map

func (*View9[A, B, C, D, E, F, G, H, I]) Read

func (v *View9[A, B, C, D, E, F, G, H, I]) Read(id Id) (*A, *B, *C, *D, *E, *F, *G, *H, *I)

Reads a pointer to the underlying component at the specified id. Read will return even if the specified id doesn't match the filter list Read will return the value if it exists, else returns nil. If you execute any ecs.Write(...) or ecs.Delete(...) this pointer may become invalid.

type World

type World struct {
	// contains filtered or unexported fields
}

World is the main data-holder. You usually pass it to other functions to do things.

func NewWorld

func NewWorld() *World

Creates a new world

func (*World) Exists

func (world *World) Exists(id Id) bool

Returns true if the entity exists in the world else it returns false

func (*World) NewId

func (w *World) NewId() Id

Creates a new Id which can then be used to create an entity

func (*World) SetIdRange

func (w *World) SetIdRange(min, max Id)

Sets an range of Ids that the world will use when creating new Ids. Potentially helpful when you have multiple worlds and don't want their Id space to collide. Deprecated: This API is tentative. It may be better to just have the user create Ids as they see fit

func (*World) Write

func (world *World) Write(id Id, comp ...Component)

Directories

Path Synopsis
internal
gen

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL