Sometimes arrived will return an old state. This is illustrated in this ellie. Code reproduced below for reference.
Basically the program is randomly incrementing an Int every 50 - 150 ms, and updating the Timeline Int with veryQuickly which is 100 ms. When these timings overlap, the arrived value occasionally reverts to the initial state for some reason. In the example, you'll see this as the third column occasionally zeroing out.
I haven't explored all the permutations of timings, but you can vary delayMillis and fuzz in the code below to experiment.
module Sandbox.AnimatorTest exposing (..)
import Animator exposing (Animator, Timeline, arrived, current, go, toSubscription, veryQuickly, watchingWith)
import Browser exposing (Document, element)
import Delay exposing (TimeUnit(..), after)
import Dict exposing (Dict, fromList)
import Html exposing (Html, div, text)
import Html.Attributes exposing (style)
import Random exposing (Seed, float, initialSeed, step)
import String exposing (fromInt)
import Time exposing (Posix)
type alias AnimatedModel =
{ real : Int
, timeline : Timeline Int
, seed : Seed
}
type AnimationMsg
= Tick Posix
| IncrementSomething
main : Program () AnimatedModel AnimationMsg
main =
element
{ init = init
, update = update
, view = view
, subscriptions = subscriptions
}
delayMillis =
100
fuzz =
50
limit =
8
init : () -> ( AnimatedModel, Cmd AnimationMsg )
init () =
( { real = 0
, timeline = Animator.init 0
, seed = initialSeed 1
}
, after delayMillis Millisecond IncrementSomething
)
update : AnimationMsg -> AnimatedModel -> ( AnimatedModel, Cmd AnimationMsg )
update msg model =
case msg of
Tick posix ->
( Animator.update posix animator model, Cmd.none )
IncrementSomething ->
let
newModel =
model.real + 1
( fuzzedDelay, newSeed ) =
step (float (delayMillis - fuzz) (delayMillis + fuzz)) model.seed
maybeKeepGoing =
if continue newModel then
after fuzzedDelay Millisecond IncrementSomething
else
Cmd.none
in
( { model
| real = newModel
, timeline = go veryQuickly newModel model.timeline
, seed = newSeed
}
, maybeKeepGoing
)
continue i =
i <= limit
view : AnimatedModel -> Html AnimationMsg
view model =
div
[ style "display" "flex"
, style "flex-direction" "row"
]
[ viewImpl "real" model.real
, viewImpl "current" <| current model.timeline
, viewImpl "arrived" <| arrived model.timeline
]
viewImpl : String -> Int -> Html msg
viewImpl label i =
div [ style "margin" "10px" ]
[ div [] [ text label ]
, div [] [ text <| fromInt i ]
]
animator : Animator AnimatedModel
animator =
let
updateTimeline nt m =
{ m | timeline = nt }
in
Animator.animator
|> watchingWith .timeline
updateTimeline
continue
subscriptions : AnimatedModel -> Sub AnimationMsg
subscriptions model =
toSubscription Tick model animator
I'm experiencing this issue as well, where my Timeline eventually reaches "Nothing", which is correctly returned by "current", but "arrived" still shows the previous "Just X".
Sometimes
arrived
will return an old state. This is illustrated in this ellie. Code reproduced below for reference.Basically the program is randomly incrementing an
Int
every 50 - 150 ms, and updating theTimeline Int
withveryQuickly
which is 100 ms. When these timings overlap, thearrived
value occasionally reverts to the initial state for some reason. In the example, you'll see this as the third column occasionally zeroing out.I haven't explored all the permutations of timings, but you can vary
delayMillis
andfuzz
in the code below to experiment.