anchor.diff:  ﻿module Kismet
   
   open System
  +open System.Collections.Generic
   open Hopac
   open Hopac.Alt
   open Hopac.Alt.Infixes
   open Hopac.Job
   open Hopac.Job.Infixes
  -open Hopac.Timer.Global
  +open Hopac.Extensions
   
   // Inspired by http://upload.wikimedia.org/wikipedia/en/e/e6/Kismet_Roboblitz.PNG
  +
  +module GameTime =
  +  type Ticks = int64
  +  let mutable internal currentTime : Ticks = 0L
  +
  +  let internal timerReqCh : Ch<Ticks * IVar<unit>> = Ch.Now.create ()
  +
  +  let atTime (atTime: Ticks) : Alt<unit> =
  +    Alt.guard << Job.delay <| fun () ->
  +    let replyI = IVar.Now.create ()
  +    Ch.send timerReqCh (atTime, replyI) >>%
  +    IVar.Alt.read replyI
  +
  +  let timeOut (afterTicks: Ticks) : Alt<unit> =
  +    assert (0L <= afterTicks)
  +    Alt.delay <| fun () ->
  +    atTime (currentTime + afterTicks)
  +
  +  let internal requests = Dictionary<Ticks, ResizeArray<IVar<unit>>> ()
  +
  +  let internal timeReqServer =
  +    Ch.take timerReqCh >>= fun (atTime, replyI) ->
  +    if currentTime <= atTime then
  +      IVar.fill replyI ()
  +    else
  +      let replyIs =
  +        match requests.TryGetValue atTime with
  +         | (true, replyIs) -> replyIs
  +         | _ ->
  +           let replyIs = ResizeArray<_>()
  +           requests.Add (atTime, replyIs)
  +           replyIs
  +      replyIs.Add replyI
  +      Job.unit
  +
  +  let tick = Job.delay <| fun () ->
  +    currentTime <- currentTime + 1L
  +    match requests.TryGetValue currentTime with
  +     | (true, replyIs) ->
  +       requests.Remove currentTime |> ignore
  +       replyIs
  +       |> Seq.iterJob (fun replyI -> IVar.fill replyI ())
  +     | _ ->
  +       Job.unit
   
   let CompareBool comparand input onTrue onFalse =
     pick input >>= fun x ->
  
positive.code: 
  let Delay duration start stop finished aborted =
    pick start >>= fun x ->
    select [stop                >=> fun y -> aborted y
            timeOut (!duration) >=> fun () -> finished x]
  
  let Set value target input output =
    pick input >>= fun x ->
  
negative.code:                   (Ch.give ch_2)
                    (fun _ -> Job.unit)
        |> Job.forever |> Job.server
    do! Delay (ref 314L)
              (Ch.Alt.take ch_2)
              (Alt.never ())
              (Ch.give ch_3)
  