-
Notifications
You must be signed in to change notification settings - Fork 3
Systems
A System is used to perform operations on a world's entities. It essentially is a shortcut for iterating over views (but it proves very useful in order to write concise, readable code).
Generally speaking, a system describes a computation that is performed each time the world's update
method is called.
A simple System
simply uses the delta time and world's reference to perform its computation.
A special kind of System is the IteratingSystem
: it is a wrapper of a view that allows to perform some computation over all its entities.
To create a System
you can simply use its apply
method specifying its update
behaviour:
val system = System((deltaTime, world) => ???)
val printSystem = System((_, _) => println("Hello, world!"))
// This system will print "Hello, world!" each time the world in which it is inserted
// is updated
An IteratingSystem
is a wrapper of a View
; it defines some methods:
-
shouldRun
: it is checked every time the system should be executed, if it returns false the system is not executed -
before
: a function that is executed once before updating the entities over which the system iterates -
update
: defines how to update a single entity, will be automatically applied to all the system's entities -
after
: a function that is executed once after updating the entities over which the system iterates
To create an IteratingSystem
you can use a handy builder syntax:
import dev.atedeg.ecscala.given
val system = System[Position &: Velocity &: CNil]
.withPrecondition { () => ??? }
.withBefore { (deltaTime, world, view) => ??? }
.withAfter { (deltaTime, world, view) => ??? }
.withUpdate { (entity, components, deltaTime) => ??? }
Some things to note:
- We must annotate the type of the components over which the system will iterate (
System[Position &: Velocity &: CNil]
iterates over all entities with aPosition
and aVelocity
components) - The call to
withPrecondition
,withBefore
andwithAfter
are all optional and can be made in any order - The call to
withUpdate
is needed to actually create the system and specifies how it will update each entity -
withUpdate
can also be called with the lambda(entity, components, deltaTime, world, view) => ???
-
components
in the lambda parameters is theCList
of components specified in the system type at the beginning (i.e. here it is aCList Position &: Velocity &: CNil
)
Is a wrapper of an ExcludingView
, building it is very similar to building an IteratingSystem
, to specify the components' types to
exclude you can simply write:
import dev.atedeg.ecscala.given
val system = System[Position &: Velocity &: CNil].excluding[Mass &: CNil]
.withPrecondition { () => ??? }
.withBefore { (deltaTime, world, view) => ??? }
.withAfter { (deltaTime, world, view) => ??? }
.withUpdate { (entity, components, deltaTime) => ??? }
To add a system to a world you can write:
object Example with ECScalaDSL {
val world = World()
val mySystem = System[Position &: CNil].withUpdate(???)
world hasA system(mySystem)
}
To remove a system from a world you can write:
object Example with ECScalaDSL {
val world = World()
val mySystem = System[Position &: CNil].withUpdate(???)
world hasA system(mySystem)
remove mySystem from world
}