-
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 updatedAn 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 aPositionand aVelocitycomponents) - The call to
withPrecondition,withBeforeandwithAfterare all optional and can be made in any order - The call to
withUpdateis needed to actually create the system and specifies how it will update each entity -
withUpdatecan also be called with the lambda(entity, components, deltaTime, world, view) => ??? -
componentsin the lambda parameters is theCListof 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
}