I'm hoping someone might be able to help me out here with Signals and Effects.
I'm looking into Signals/Effects and have been studying the-elm-architecture, particularly example 8.
In this example (as I understand it), if you click on the shape(s) :
- a signal message is sent to the address along with the action
- the
SPIN
action is fired on update - if he shape isn't currently animating, Tick is also called.
I'm trying to replicate the exact same flow (using similar code) but instead of clicking on a button and using the HTML package, I want to just send a signal using the spacebar.
In my code, the spacebar sends a Signal off to the Punch
action. Just like example 8, I want to then also call Tick
and update the debounceState
in my model.
You'll see in my comments that I can reach my Punch
action, but I don't seem to ever get to Tick
.
I have looked at this question, but because I'm using a Keyboard Signal and not the elm StartApp, I don't think it applies.
If someone could explain why I'm not able to reach Tick
in my example, I'd super appreciate it.
module Main (..) where
import Graphics.Element exposing (..)
import Time exposing (Time, second)
import Effects exposing (Effects)
import Keyboard
type alias DebounceState =
Maybe
{ prevClockTime : Time
, elapsedTime : Time
}
type alias Model =
{ punching : Bool
, count : Int
, randomString: String
, debounceState : DebounceState
}
duration = second
-- MODEL
initialModel : ( Model, Effects Action )
initialModel =
( { punching = False
, count = 0
, randomString = ""
, debounceState = Nothing
}
, Effects.none
)
model : Signal ( Model, Effects Action )
model =
Signal.foldp update initialModel (punch Keyboard.space)
-- ACTIONS
type Action
= NoOp
| Punch Bool
| Tick Time
-- UPDATE
update : Action -> ( Model, Effects Action ) -> ( Model, Effects Action )
update action ( model, fx ) =
case action of
NoOp ->
( model, Effects.none )
Punch isPunching ->
case model.debounceState of
Nothing ->
( { model |
punching = isPunching
, count = model.count + 1 }, Effects.tick Tick )
Just _ ->
( { model |
punching = isPunching
, count = model.count + 2 }, Effects.none )
-- I don't seem to reach `Tick` at all
-- You'll notice that I try to apply a value to `randomString` in the
-- conditional to indicate where I end up
Tick clockTime ->
let
newElapsedTime =
case model.debounceState of
Nothing ->
0
Just {elapsedTime, prevClockTime} ->
elapsedTime + (clockTime - prevClockTime)
in
if newElapsedTime > duration then
( {model | randomString = "foo"} , Effects.none )
else
( {model | randomString = "bar"} , Effects.tick Tick )
-- SIGNAL
punch : Signal Bool -> Signal Action
punch input =
Signal.map Punch input
-- VIEW
view : ( Model, Effects Action ) -> Element
view model =
show model
main : Signal Element
main =
Signal.map view model
Paste that straight into Try Elm.