DieselMeister / Terminal.Gui.Elmish

An elmish wrapper around Miguel de Icaza's 'Gui.cs' https://github.com/migueldeicaza/gui.cs including a fable like view DSL.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Using AddTimeout in Subscription

AlexanderLindsay opened this issue · comments

Description

I am trying to add a subscription to a program to use the AddTimeout method on the MainLoop of Terminal.Gui Application. However, it only runs once when I am expecting it to rerun since I am returning true in the AddTimeout callback. I have a feeling that I just don't understand how the dispatch works, or maybe how it interacts with the Application.MainLoop.

Repro steps

    Program.mkProgram init update view
    |> Program.withSubscription (fun m ->  
        let sub dispatch = 
            Application
                .MainLoop
                .AddTimeout(
                    System.TimeSpan(0, 0, 1), 
                    (fun _ -> 
                        dispatch Tick
                        true
                    )
                )
                |> ignore
        Cmd.ofSub sub
    )
    |> Program.run

Expected behavior

I expected the Tick msg to be dispatched every second

Actual behavior

The Tick msg is dispatched only once

Known workarounds

none

Related information

  • Windows 10
  • master
  • dotnet --version: 2.2.401

Full Sample Program

open Terminal.Gui
open Terminal.Gui.Elmish

type Model =
    { Count : int }

type Msg =
    | Tick
    | Inc
    | Dec

let init() = { Count = 1 }, Cmd.none

let update (msg : Msg) (model : Model) =
    match msg with
    | Tick -> { model with Count = model.Count + 1 }, Cmd.none
    | Inc -> { model with Count = model.Count + 1 }, Cmd.none
    | Dec -> { model with Count = model.Count - 1 }, Cmd.none

let view (model : Model) (dispatch : Msg -> unit) =
    page [ 
        window [ 
            Styles [ 
                Pos(AbsPos 0, AbsPos 1)
                Dim(Fill, Fill)
            ]
            Title "Terminal/Console Elmish" 
        ] [
           button [
               Styles [
                   Pos (AbsPos 1, AbsPos 1)
               ]
               Text "Counter Up"
               OnClicked (fun () -> dispatch Inc)                    
           ] 

           label [
               Styles [
                   Pos (AbsPos 1, AbsPos 2)
               ]
               Text <| sprintf "%d" model.Count 
           ]

           button [
               Styles [
                   Pos (AbsPos 1, AbsPos 3)
               ]
               Text "Counter Down"
               OnClicked (fun () -> dispatch Dec)                    
           ] 
        ] 
    ]

[<EntryPoint>]
let main argv =

    Program.mkProgram init update view
    |> Program.withSubscription (fun m ->  
        let sub dispatch = 
            Application
                .MainLoop
                .AddTimeout(
                    System.TimeSpan(0, 0, 1), 
                    (fun _ -> 
                        dispatch Tick
                        true
                    )
                )
                |> ignore
        Cmd.ofSub sub
    )
    |> Program.run
    0 // return an integer exit code

I think I found a workaround at least:

let wait dispatch =
    Application.MainLoop.AddTimeout(
        System.TimeSpan(0, 0, 1),
        (fun _ -> 
            dispatch Tick
            false
        )
    ) |> ignore

let init() = { Count = 1 }, Cmd.ofSub wait

let update (msg : Msg) (model : Model) =
    match msg with
    | Tick -> { model with Count = model.Count + 1 }, Cmd.ofSub wait
    | Inc -> { model with Count = model.Count + 1 }, Cmd.none
    | Dec -> { model with Count = model.Count - 1 }, Cmd.none

I will look into it. Thank you :)

Hi. So i fixed that issue and commit the fix into the master branch. I have to add some additional bugfixes, bacause the subscription, especially the kind of sending messages in intervals, cause some issues.

I added a subscription into the demo application.

Awesome, thanks!

I will take a look at the sample and try it out.

Hi. So I published a new nuget version.

https://www.nuget.org/packages/Terminal.Gui.Elmish/0.1.4

feel free to report further issues. :)