Advertisement
Guest User

Untitled

a guest
Feb 4th, 2019
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 3.90 KB | None | 0 0
  1. open System
  2. open Hopac
  3. open Hopac.Infixes
  4.  
  5.  
  6. let rec until (cancel: Alt<'c>) (s: 's) (j: Alt<'c> -> 's -> Alt<'s>) =
  7.    (cancel ^-> fun x -> x, s)
  8.    <|>
  9.    (j cancel s ^=> fun s -> until cancel s j)
  10.  
  11. let printDelay msg =
  12.    Job.delay <| fun _ ->
  13.        printfn "before timeout"
  14.        timeOutMillis 200
  15.    >>- fun _ -> printfn "after, msg: %d" msg; msg + 1
  16.  
  17. type Timer = { incomingTasks: Ch<DateTime * Alt<unit> * IVar<Alt<unit>>> }
  18.  
  19. module Timer =
  20.    type Task = {
  21.        wakeTime:   DateTime
  22.        cancel:     Alt<unit>
  23.        fire:       IVar<unit>
  24.    }
  25.  
  26.    let takeFirst tasks =
  27.        match tasks with
  28.        | [] -> None, []
  29.        | xs -> xs |> List.head |> Some, xs |> List.tail
  30.  
  31.    let create () = { incomingTasks = Ch () }
  32.  
  33.    let loop timer cancel =
  34.        fun (currentTask, nextTasks) ->
  35.            Alt.choose (seq {
  36.                yield cancel ^=>. Job.abort ()
  37.                match currentTask with
  38.                | Some task ->
  39.                    yield task.cancel ^-> (fun _ -> nextTasks |> takeFirst)
  40.                    let waitTime = task.wakeTime - DateTime.Now
  41.                    yield
  42.                        (if TimeSpan.Compare (waitTime, TimeSpan.Zero) <= 0 then
  43.                            Alt.always ()
  44.                        else
  45.                            (timeOut waitTime))
  46.                        ^=>. (task.fire *<= () >>- (fun _ -> printfn "fired!!!") >>-. (nextTasks |> takeFirst))
  47.                | None -> ()
  48.  
  49.                yield Ch.take timer.incomingTasks ^=> (fun (wakeTime, cancel, res) ->
  50.                    let fire = IVar ()
  51.                    let newTask = { wakeTime = wakeTime; cancel = cancel; fire = fire }
  52.                    res *<= (fire |> IVar.read) >>- fun _ ->
  53.                        currentTask |> Option.fold (fun l x -> x::l) (newTask::nextTasks)
  54.                        |> List.sortBy (fun task -> task.wakeTime)
  55.                        |> takeFirst)
  56.            })
  57.  
  58.    //let start timer =
  59.    //    loop timer |> Job.iterate (None, [])
  60.  
  61.    let submit wakeTime cancel timer =
  62.        let res = IVar ()
  63.        timer.incomingTasks *<+ (wakeTime, cancel, res)
  64.        >>=. res >>=* id
  65.  
  66.    let submitNack wakeTime timer =
  67.        Alt.withNackFun (fun nack -> timer |> submit wakeTime nack)
  68.  
  69.  
  70. [<EntryPoint>]
  71. let main argv =
  72.  
  73.    // let cancel = IVar<string> ()
  74.    // // let x = printDelay |> until cancel 10 |> startIgnore
  75.    // let promiseJob = printDelay |> until cancel 0 |> Promise.start >>= Promise.read >>- (fun r -> Console.WriteLine (r)) |> startIgnore
  76.    // // let r = promiseJob |> startIgnore
  77.    // Console.ReadLine () |> ignore
  78.    // cancel *<= "asdf" |> run
  79.    // Console.ReadLine () |> ignore
  80.  
  81.    printfn "Start: %A" (DateTime.Now.ToLongTimeString ())
  82.    let timerStop = IVar<unit> ()
  83.    let timer = Timer.create ()
  84.    let a = timer |> Timer.loop
  85.    let b = until timerStop (None, [])
  86.    a |> b |> startIgnore
  87.    let now = DateTime.Now
  88.    let wakeTime1 = now + (TimeSpan.FromSeconds 0.5)
  89.    let wakeTime2 = now + (TimeSpan.FromSeconds 1.2)
  90.    let wakeTime3 = now + (TimeSpan.FromSeconds 1.5)
  91.    let stopTime = now + (TimeSpan.FromSeconds 1.0)
  92.    (timer |> Timer.submitNack wakeTime1) ^-> (fun _ -> printfn "EVENT1 %A" (DateTime.Now.ToLongTimeString ()); 1)
  93.    <|> (timeOutMillis 1500 ^-> fun _ -> printfn "Timeout %A" (DateTime.Now.ToLongTimeString ()); 2)
  94.    |> startIgnore
  95.    (timer |> Timer.submitNack wakeTime2) ^-> (fun _ -> printfn "EVENT2 %A" (DateTime.Now.ToLongTimeString ()); 1)
  96.    |> startIgnore
  97.    (timer |> Timer.submitNack wakeTime3) ^-> (fun _ -> printfn "EVENT3 %A" (DateTime.Now.ToLongTimeString ()); 1)
  98.    |> startIgnore
  99.    
  100.    (timer |> Timer.submitNack stopTime) ^=> fun _ -> printfn "timer stop %A" (DateTime.Now.ToLongTimeString ()); timerStop *<= ()
  101.    |> startIgnore
  102.  
  103.    Console.ReadLine () |> ignore
  104.  
  105.  
  106.    0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement