wolfadex / elm-ecs / Ecs.System


type alias System world =
world -> world

A function for updating a world

update : Ecs.Component.Spec comp world -> (Ecs.Component comp -> Ecs.Component comp) -> world -> world

Update whole Ecs.Component

map : (comp -> comp) -> Ecs.Component.Spec comp world -> world -> world

Single component mapping, similar to List.map - only for Ecs.Component.Component inside world

gravitySystem : Ecs.System.System world
gravitySystem =
    Logic.System.map (Vec2.add gravity) accelerationSpec

map2 : (( a, a -> System (Acc2 a b) ) -> ( b, b -> System (Acc2 a b) ) -> System (Acc2 a b)) -> Ecs.Component.Spec a world -> Ecs.Component.Spec b world -> world -> world

Map over all entities that have both components.

Example:

moveSystem : Ecs.System.System World
moveSystem =
    Logic.System.map2
        (\( velocity, _ ) ( position, setPosition ) ->
            setPosition (Vec2.add velocity position)
        )
        velocitySpec
        positionSpec

map3 : (( a, a -> System (Acc3 a b c) ) -> ( b, b -> System (Acc3 a b c) ) -> ( c, c -> System (Acc3 a b c) ) -> System (Acc3 a b c)) -> Ecs.Component.Spec a world -> Ecs.Component.Spec b world -> Ecs.Component.Spec c world -> world -> world

Same as map2 only with 3 components

map4 : (( a, a -> System (Acc4 a b c d) ) -> ( b, b -> System (Acc4 a b c d) ) -> ( c, c -> System (Acc4 a b c d) ) -> ( d, d -> System (Acc4 a b c d) ) -> System (Acc4 a b c d)) -> Ecs.Component.Spec a world -> Ecs.Component.Spec b world -> Ecs.Component.Spec c world -> Ecs.Component.Spec d world -> world -> world

Same as map2 only with 4 components

map5 : (( a, a -> System (Acc5 a b c d e) ) -> ( b, b -> System (Acc5 a b c d e) ) -> ( c, c -> System (Acc5 a b c d e) ) -> ( d, d -> System (Acc5 a b c d e) ) -> ( e, e -> System (Acc5 a b c d e) ) -> System (Acc5 a b c d e)) -> Ecs.Component.Spec a world -> Ecs.Component.Spec b world -> Ecs.Component.Spec c world -> Ecs.Component.Spec d world -> Ecs.Component.Spec e world -> world -> world

Same as map2 only with 5 components

foldl : (comp -> acc -> acc) -> Ecs.Component comp -> acc -> acc

Reduce an Ecs.Component from the left.

Example count how many enemies are left in the world:

enemyComponent : Ecs.Component.Component PlayerType
enemyComponent =
    enemySpec.get world

remainingEnemyCount : Int
remainingEnemyCount =
    Ecs.System.foldl (\_ -> (+) 1) enemyComponent 0

foldl2 : (comp1 -> comp2 -> acc -> acc) -> Ecs.Component comp1 -> Ecs.Component comp2 -> acc -> acc

Map over all entities that have both components and reduce the Components from the left.

foldl3 : (comp1 -> comp2 -> comp3 -> acc -> acc) -> Ecs.Component comp1 -> Ecs.Component comp2 -> Ecs.Component comp3 -> acc -> acc

Same as foldl2 only with 3 components

foldl4 : (comp1 -> comp2 -> comp3 -> comp4 -> acc -> acc) -> Ecs.Component comp1 -> Ecs.Component comp2 -> Ecs.Component comp3 -> Ecs.Component comp4 -> acc -> acc

Same as foldl2 only with 4 components

foldl5 : (comp1 -> comp2 -> comp3 -> comp4 -> comp5 -> acc -> acc) -> Ecs.Component comp1 -> Ecs.Component comp2 -> Ecs.Component comp3 -> Ecs.Component comp4 -> Ecs.Component comp5 -> acc -> acc

Same as foldl2 only with 5 components

indexedFoldl : (Ecs.Internal.Entity -> comp -> acc -> acc) -> Ecs.Component comp -> acc -> acc

Variant of foldl that passes the Entity of the current element to the map function.

indexedFoldl is to foldl as List.indexedMap is to List.map.

indexedFoldl2 : (Ecs.Internal.Entity -> comp1 -> comp2 -> acc -> acc) -> Ecs.Component comp1 -> Ecs.Component comp2 -> acc -> acc

Same as indexedFoldl only with 2 components

indexedFoldl3 : (Ecs.Internal.Entity -> comp1 -> comp2 -> comp3 -> acc -> acc) -> Ecs.Component comp1 -> Ecs.Component comp2 -> Ecs.Component comp3 -> acc -> acc

Same as indexedFoldl2 only with 3 components

indexedFoldl4 : (Ecs.Internal.Entity -> comp1 -> comp2 -> comp3 -> comp4 -> acc -> acc) -> Ecs.Component comp1 -> Ecs.Component comp2 -> Ecs.Component comp3 -> Ecs.Component comp4 -> acc -> acc

Same as indexedFoldl2 only with 4 components

indexedFoldl5 : (Ecs.Internal.Entity -> comp1 -> comp2 -> comp3 -> comp4 -> comp5 -> acc -> acc) -> Ecs.Component comp1 -> Ecs.Component comp2 -> Ecs.Component comp3 -> Ecs.Component comp4 -> Ecs.Component comp5 -> acc -> acc

Same as indexedFoldl2 only with 5 components

Util

applyIf : Basics.Bool -> (a -> a) -> a -> a

A helper function to pipe into systems

update msg world =
    world
        |> system1
        |> applyIf (msg === KeyUp "a") systemMoveLeft
        |> system2

applyMaybe : Maybe a -> (a -> c -> c) -> c -> c

Same as applyIf, but works with Maybe

update msg world =
    world
        |> system1
        |> applyMaybe (decode saveDecoder msg) loadGame
        |> system2

Internal helper types


type alias Acc2 a b =
{ a : Ecs.Component a
, b : Ecs.Component b 
}

Helper for map2


type alias Acc3 a b c =
{ a : Ecs.Component a
, b : Ecs.Component b
, c : Ecs.Component c 
}

Helper for map3


type alias Acc4 a b c d =
{ a : Ecs.Component a
, b : Ecs.Component b
, c : Ecs.Component c
, d : Ecs.Component d 
}

Helper for map4


type alias Acc5 a b c d e =
{ a : Ecs.Component a
, b : Ecs.Component b
, c : Ecs.Component c
, d : Ecs.Component d
, e : Ecs.Component e 
}

Helper for map5