Learning Elm Part 8

The Elm Architecture

The Elm Architecture

modelviewupdate.svg

Model

  • The Model is a user defined data structure
type alias Model = { ... }
  • It’s purpose is to contain the state of the app, which is whatever you may decide

Msg

  • The Msg is another user defined data structure
type Msg = ...
  • Its purpose is to encode events such as the current time, mouse clicks, key presses, etc

View

  • The view method is a function called by the main program
view :: Model -> Html
  • It’s purpose is to render html code that will be displayed in your browser, given the current state of your app (i.e., the Model)

Update

  • The update method is a function called by the main program
update :: Msg -> Model -> Model
  • It’s automatically envoked whenever an event occurs, takes the current state of the program (i.e. the Model) and returns a new state

Main App

Elm supports a number of different main apps, but we will only focus on gameApp

main =
    gameApp Tick
        { model = init
        , update = update
        , view = view
        }

GameApp Msg Type

  • The gameApp is hard-coded to work with the following Msg type
type Msg = Tick Float GetKeyState
  • The gameApp method will automatically call the update method on each frame change providing
    • The current time as a Float
    • The current key states using the GetKeyState data structure

GameApp Update

  • An example model for a gameApp will generally include a time attribute
    type alias Model = { time :: Float
                       ...
                       }
  • One function of the update method would then be to set the given time
    update msg model =
        case msg of
            Tick t getKey -> { model | time = t }

GameApp View

  • The view method of a gameApp specifically renders a Collage
view model = collage 192 128 (myShapes model)
  • A Collage takes a list of shapes
myShapes model = [ circle 5
                 |> filled red
                 |> scale (10 * sin model.time)
                 ]

Key Press Events

  • The GetKeyState attribute given by gameApp provides a function
type alias GetKeyState = ( Keys -> KeyState, (Float,Float), (Float,Float))
  • The first attribute in the tuple is a function from Keys to KeyState
type Keys
    = Key String
    | Backspace
    | Tab
    | Enter
    | Shift
    | Ctrl
    | Alt
    | Caps
    | LeftArrow
    | UpArrow
    | RightArrow
    | DownArrow
    | Delete
    | Space
type KeyState
    = JustDown
    | Down
    | JustUp
    | Up

Using GetKeyState

We can use the GetKeyState function to update the model

type alias Model = { time : Float, size : Float }

update msg model =
    case msg of
      Tick t (getKey,_,_) ->
        case (getKey (Key "a"),getKey (Key "b")) of
          (Down,_) -> { model | size = model.size + 1 }
          (_,Down) -> { model | size = model.size - 1 }
          _ -> model

Built-in Shape Notifications

  • GraphicsSVG provides notification methods that can be directly attached to Shapes
type Msg = Tick Float GetKeyState
         | Tap

myShapes model =
  [circle 5 |> filled red
             |> scale model.size
             |> notifyTap Tap ]
  • We then need to handle Tap in the update method
update msg model = case msg of
    Tap -> {model | size = 20 }
    Tick t (getKey,_,_) -> ...