Skip to content

Instantly share code, notes, and snippets.

@object
Last active October 18, 2024 09:12
Show Gist options
  • Select an option

  • Save object/e7b6253b08babda208f2f04e954f1e80 to your computer and use it in GitHub Desktop.

Select an option

Save object/e7b6253b08babda208f2f04e954f1e80 to your computer and use it in GitHub Desktop.
Fable workshop (2024). Step 6. Update.fs
module Update
open System
open Elmish
open Fable.SimpleHttp
open Model
open Messages
let tryParseWith (tryParseFunc: string -> bool * _) = tryParseFunc >> function
| true, v -> Some v
| false, _ -> None
let loadEvents (state : Model) =
async {
let filename = match state.EventSet with | EventSet.Small -> "SingleProgram.txt" | EventSet.Large -> "MultiplePrograms.txt"
let! response =
Http.request (sprintf "http://localhost:5000/api/files/%s" filename)
|> Http.method GET
|> Http.send
if response.statusCode <> 200 then failwith (sprintf "Error %d" response.statusCode)
return response.responseText
}
let delayMessage msg (delay : int) state =
let delayedMsg (dispatch : Msg -> unit) : unit =
let delayedDispatch = async {
do! Async.Sleep delay
dispatch msg
}
Async.StartImmediate delayedDispatch
state, Cmd.ofEffect delayedMsg
let init () =
Model.Empty, Cmd.none
let update msg state =
match msg with
| EventSetChanged eventSet ->
let eventSet = if eventSet = EventSet.Small.ToString() then EventSet.Small else EventSet.Large
{ state with EventSet = eventSet; Error = "" }, Cmd.none
| PlaybackDelayChanged delay ->
{ state with PlaybackDelay = Int32.Parse delay }, Cmd.none
| StartPlayback ->
let eventIndex =
if state.EventIndex < 0 || state.EventIndex >= state.Events.Length then 0
else state.EventIndex
{ state with EventIndex = eventIndex; IsPlaying = true }, Cmd.OfAsync.either loadEvents state EventsLoaded EventsError
| PausePlayback ->
{ state with IsPlaying = false }, Cmd.none
| StopPlayback ->
{ state with EventIndex = -1; IsPlaying = false }, Cmd.none
| NextEvent ->
if state.IsPlaying then
if state.EventIndex < state.Events.Length then
{ state with EventIndex = state.EventIndex + 1 }, Cmd.ofMsg (Delayed (NextEvent, state.PlaybackDelay))
else
{ state with IsPlaying = false }, Cmd.none
else
state, Cmd.none
| EventsLoaded events ->
{ state with Events = events.Split([|'\r'; '\n'|], StringSplitOptions.RemoveEmptyEntries) }, Cmd.ofMsg (Delayed (NextEvent, state.PlaybackDelay))
| EventsError exn ->
{ state with Error = exn.ToString() }, Cmd.none
| Delayed (msg, delay) -> delayMessage msg delay state
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment