justgook / elm-game-logic / Logic.System

System: main logic driver, that is used to stepping on each game-loop and update World


type alias System world =
world -> world

update : Logic.Component.Spec comp world -> (Logic.Component.Set comp -> Logic.Component.Set comp) -> world -> world

Update whole Component.Set

step : (comp -> comp) -> Logic.Component.Spec comp world -> world -> world

Single component mapping, Same asList.map - only for Component.Set inside World

gravitySystem =
    Logic.System.step (Vec2.add gravity) accelerationSpec

step2 : (( a, a -> System (Acc2 a b) ) -> ( b, b -> System (Acc2 a b) ) -> System (Acc2 a b)) -> Logic.Component.Spec a world -> Logic.Component.Spec b world -> world -> world

Step over all entities that have both components.

Example:

system =
    Logic.System.step2
        (\( v, _ ) ( p, setP ) -> setP (Vec2.add v p))
        velocitySpec
        positionSpec

step3 : (( 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)) -> Logic.Component.Spec a world -> Logic.Component.Spec b world -> Logic.Component.Spec c world -> world -> world

Same as step2 only with 3 components

step4 : (( 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)) -> Logic.Component.Spec a world -> Logic.Component.Spec b world -> Logic.Component.Spec c world -> Logic.Component.Spec d world -> world -> world

Same as step2 only with 4 components

step5 : (( 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)) -> Logic.Component.Spec a world -> Logic.Component.Spec b world -> Logic.Component.Spec c world -> Logic.Component.Spec d world -> Logic.Component.Spec e world -> world -> world

Same as step2 only with 5 components

foldl : (comp1 -> acc -> acc) -> Logic.Component.Set comp1 -> acc -> acc

Reduce a Component.Set from the left.

Example count how much enemies left in the world:

enemySet =
    enemySpec.get world

count =
    foldl (\_ -> (+) 1) enemySet 0

foldl2 : (comp1 -> comp2 -> acc -> acc) -> Logic.Component.Set comp1 -> Logic.Component.Set comp2 -> acc -> acc

Step over all entities that have both components and reduce an Component.Sets from the left.

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

Same as foldl2 only with 3 components

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

Same as foldl2 only with 4 components

foldl5 : (comp1 -> comp2 -> comp3 -> comp4 -> acc -> acc) -> Logic.Component.Set comp1 -> Logic.Component.Set comp2 -> Logic.Component.Set comp3 -> Logic.Component.Set comp4 -> acc -> acc

Same as foldl2 only with 5 components

indexedFoldl : (Logic.Entity.EntityID -> comp1 -> acc -> acc) -> Logic.Component.Set comp1 -> acc -> acc

Variant of foldl that passes the index of the current element to the step function.

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

indexedFoldl2 : (Logic.Entity.EntityID -> comp1 -> comp2 -> acc -> acc) -> Logic.Component.Set comp1 -> Logic.Component.Set comp2 -> acc -> acc

indexedFoldl3 : (Logic.Entity.EntityID -> comp1 -> comp2 -> comp3 -> acc -> acc) -> Logic.Component.Set comp1 -> Logic.Component.Set comp2 -> Logic.Component.Set comp3 -> acc -> acc

Same as indexedFoldl2 only with 3 components

indexedFoldl4 : (Logic.Entity.EntityID -> comp1 -> comp2 -> comp3 -> comp4 -> acc -> acc) -> Logic.Component.Set comp1 -> Logic.Component.Set comp2 -> Logic.Component.Set comp3 -> Logic.Component.Set comp4 -> acc -> acc

Same as indexedFoldl2 only with 4 components

indexedFoldl5 : (Logic.Entity.EntityID -> comp1 -> comp2 -> comp3 -> comp4 -> comp5 -> acc -> acc) -> Logic.Component.Set comp1 -> Logic.Component.Set comp2 -> Logic.Component.Set comp3 -> Logic.Component.Set comp4 -> Logic.Component.Set comp5 -> acc -> acc

Same as indexedFoldl2 only with 5 components

Util

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

Just nice 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