Hardt-Coded / 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.
The Unlicense
224 stars 13 forks source link

Using AddTimeout in Subscription #7

Closed AlexanderLindsay closed 5 years ago

AlexanderLindsay commented 5 years ago

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

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
AlexanderLindsay commented 5 years ago

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
Hardt-Coded commented 5 years ago

I will look into it. Thank you :)

Hardt-Coded commented 5 years ago

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.

AlexanderLindsay commented 5 years ago

Awesome, thanks!

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

Hardt-Coded commented 5 years ago

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. :)