0 people like it.

scheduler

  1: 
  2: 
  3: 
  4: 
  5: 
  6: 
  7: 
  8: 
  9: 
 10: 
 11: 
 12: 
 13: 
 14: 
 15: 
 16: 
 17: 
 18: 
 19: 
 20: 
 21: 
 22: 
 23: 
 24: 
 25: 
 26: 
 27: 
 28: 
 29: 
 30: 
 31: 
 32: 
 33: 
 34: 
 35: 
 36: 
 37: 
 38: 
 39: 
 40: 
 41: 
 42: 
 43: 
 44: 
 45: 
 46: 
 47: 
 48: 
 49: 
 50: 
 51: 
 52: 
 53: 
 54: 
 55: 
 56: 
 57: 
 58: 
 59: 
 60: 
 61: 
 62: 
 63: 
 64: 
 65: 
 66: 
 67: 
 68: 
 69: 
 70: 
 71: 
 72: 
 73: 
 74: 
 75: 
 76: 
 77: 
 78: 
 79: 
 80: 
 81: 
 82: 
 83: 
 84: 
 85: 
 86: 
 87: 
 88: 
 89: 
 90: 
 91: 
 92: 
 93: 
 94: 
 95: 
 96: 
 97: 
 98: 
 99: 
100: 
101: 
102: 
103: 
104: 
105: 
106: 
107: 
108: 
109: 
110: 
111: 
112: 
113: 
114: 
115: 
116: 
117: 
118: 
119: 
120: 
121: 
122: 
123: 
124: 
125: 
126: 
127: 
128: 
129: 
130: 
131: 
132: 
133: 
134: 
135: 
[<RequireQualifiedAccess>]
module Task
open System
open System.Collections.Generic

type private unsigned = uint64

type 'a M =
    | Delay of (unit -> 'a M)
    | Sleeping of unsigned * (unit -> 'a M)
    | Tick of (unit -> 'a M)
    | Interruptible of (unit -> 'a M)
    | Done of 'a

type 'a Entity(e, m, id) =
    member val Entity : 'a = e with get
    member val State : _ M = m with get, set
    member val Id : unsigned = id with get

type private TaskComparer<'a>() =
    interface IComparer<'a Entity> with
        member o.Compare(x, y) =
            let c1, o1, c2, o2 = x.Id, x.State, y.Id, y.State
            let cmp = Comparer.Default.Compare
            match o1, o2 with
            (* always last *)
            | Interruptible _, Interruptible _ -> cmp(c1, c2)
            | Interruptible _, _ -> 1
            | _, Interruptible _ -> -1
            (* never contained in the task list *)
            | Done _, _ -> failwith "can't happen"
            | _, Done _ -> failwith "can't happen"
            | Delay _, Delay _ -> cmp(c1, c2)
            | Delay _, _ -> -1
            | _, Delay _ -> 1
            | Tick _, Tick _ -> cmp(c1, c2)
            | Tick _, _ -> -1
            | _, Tick _ -> 1
            | Sleeping (t1, _), Sleeping (t2, _) -> let ret = cmp(t1, t2)
                                                    if ret = 0 then cmp(c1, c2)
                                                    else ret

type TaskBuilder<'TEntity>() =
    (* builder helpers *)
    let rec bind (k : 'a -> 'b M) (v : 'a M) : 'b M =
        match v with
        | Delay d -> d () |> bind k
        | Sleeping(t, f) -> Sleeping(t, fun () -> f () |> bind k)
        | Tick f -> Tick(fun () -> f () |> bind k)
        | Interruptible f -> Interruptible(fun () -> f () |> bind k)
        | Done r -> k r
    let delay (k : unit -> 'a M) : 'a M =
        Delay k
    let ret (r : 'a) : 'a M =
        Done r
    let rec whileLoop (cond : unit -> bool) (expr : 'a M) : unit M =
        if cond ()
        then expr |> bind (fun _ -> whileLoop cond expr)
        else Done ()
    let forLoop (lst : 'a seq) (body : 'a -> 'b M) =
        let iter = lst.GetEnumerator ()
        Delay(fun () -> iter.Current |> body) |> whileLoop (fun () -> iter.MoveNext ())
    (* scheduling helpers *)
    let mutable offset = 0UL
    let mutable last = Int32.MinValue
    let tasks = SortedSet(TaskComparer())
    let ticks () =
        let ticks = Environment.TickCount
        if ticks < last
        then offset <- offset + (uint64 UInt32.MaxValue)
        last <- ticks
        offset + (uint64 ticks)
    let peek ticks (task : _ M) =
        match task with
        | Done _ -> failwith "can't happen"
        | Delay _ -> true
        | Sleeping(t, _) -> t < ticks
        | Tick _ -> true
        | Interruptible _ -> false
    let eval (task : 'a M) : 'a M =
        match task with
        | Delay f -> f ()
        | Done v -> task
        | Interruptible f -> f ()
        | Sleeping(t, f) -> f ()
        | Tick f -> f ()
    let mutable counter = 0UL
    let makeId () = let ret = counter
                    counter <- counter + 1UL
                    ret
    (* builder implementation *)
    member o.Bind(v, k) = bind k v
    member o.Return(r) = ret r
    member o.Delay k = delay k
    member o.While(cond, expr) = whileLoop cond expr
    member o.Zero () = Done ()
    member o.For(lst, body) = forLoop lst body
    member o.Combine(first, second) = bind (fun () -> second) first
    (* scheduling implementation *)
    member o.add (entity : 'TEntity) (expr : _ M) =
        let entity = Entity(entity, expr, makeId ())
        tasks.Add(entity) |> ignore
        entity
    member o.interrupt (entity : 'TEntity Entity) =
        match entity.State with
            | Interruptible m -> tasks.Remove(entity) |> ignore
                                 entity.State <- m ()
                                 tasks.Add(entity) |> ignore
                                 true
            | _ -> false
    member o.sleep dt =
        if dt < 0 then failwith "delta time can't be less than 0"
        let t = (uint64 dt) + ticks ()
        Sleeping(t, fun () -> Done ())
    member o.tick () =
        let ticks = ticks ()
        if tasks.Count > 0 then
            let nextTick = ResizeArray()
            while tasks.Count > 0 && peek ticks tasks.Min.State do
                let entity = tasks.Min
                let task = entity.State
                tasks.Remove(entity) |> ignore
                let m = eval task
                match m with
                | Tick _ -> entity.State <- m
                            nextTick.Add(entity) |> ignore
                | Done _ -> ()
                | _ -> entity.State <- m
                       tasks.Add(entity) |> ignore
            nextTick |> Seq.iter (fun m -> tasks.Add(m) |> ignore)
    //member o.test () = Tick(fun () -> Done 42)

let task : unit TaskBuilder = TaskBuilder()

Console.ReadLine () |> ignore
Multiple items
type RequireQualifiedAccessAttribute =
  inherit Attribute
  new : unit -> RequireQualifiedAccessAttribute

Full name: Microsoft.FSharp.Core.RequireQualifiedAccessAttribute

--------------------
new : unit -> RequireQualifiedAccessAttribute
module Task
namespace System
namespace System.Collections
namespace System.Collections.Generic
type private unsigned = uint64

Full name: Task.unsigned
Multiple items
val uint64 : value:'T -> uint64 (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.uint64

--------------------
type uint64 = UInt64

Full name: Microsoft.FSharp.Core.uint64
type 'a M =
  | Delay of (unit -> 'a M)
  | Sleeping of unsigned * (unit -> 'a M)
  | Tick of (unit -> 'a M)
  | Interruptible of (unit -> 'a M)
  | Done of 'a

Full name: Task.M<_>
union case M.Delay: (unit -> 'a M) -> 'a M
type unit = Unit

Full name: Microsoft.FSharp.Core.unit
union case M.Sleeping: unsigned * (unit -> 'a M) -> 'a M
union case M.Tick: (unit -> 'a M) -> 'a M
union case M.Interruptible: (unit -> 'a M) -> 'a M
union case M.Done: 'a -> 'a M
Multiple items
type 'a Entity =
  new : e:'a * m:obj M * id:unsigned -> 'a Entity
  member Entity : 'a
  member Id : unsigned
  member State : obj M
  member State : obj M with set

Full name: Task.Entity<_>

--------------------
new : e:'a * m:obj M * id:unsigned -> 'a Entity
val e : 'a
val m : obj M
val id : unsigned
val set : elements:seq<'T> -> Set<'T> (requires comparison)

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.set
Multiple items
type private TaskComparer<'a> =
  interface IComparer<'a Entity>
  new : unit -> TaskComparer<'a>

Full name: Task.TaskComparer<_>

--------------------
private new : unit -> TaskComparer<'a>
type IComparer<'T> =
  member Compare : x:'T * y:'T -> int

Full name: System.Collections.Generic.IComparer<_>
val o : TaskComparer<'a>
override private TaskComparer.Compare : x:'a Entity * y:'a Entity -> int

Full name: Task.TaskComparer`1.Compare
val x : 'a Entity
val y : 'a Entity
val c1 : unsigned
val o1 : obj M
val c2 : unsigned
val o2 : obj M
property Entity.Id: unsigned
property Entity.State: obj M
val cmp : (unsigned * unsigned -> int)
type Comparer<'T> =
  member Compare : x:'T * y:'T -> int
  static member Default : Comparer<'T>

Full name: System.Collections.Generic.Comparer<_>
property Comparer.Default: Comparer<'T>
Comparer.Compare(x: 'T, y: 'T) : int
val failwith : message:string -> 'T

Full name: Microsoft.FSharp.Core.Operators.failwith
val t1 : unsigned
val t2 : unsigned
val ret : int
Multiple items
type TaskBuilder<'TEntity> =
  new : unit -> TaskBuilder<'TEntity>
  member Bind : v:'a M * k:('a -> 'b M) -> 'b M
  member Combine : first:unit M * second:'a M -> 'a M
  member Delay : k:(unit -> 'a M) -> 'a M
  member For : lst:seq<'a> * body:('a -> 'b M) -> unit M
  member Return : r:'a -> 'a M
  member While : cond:(unit -> bool) * expr:'a M -> unit M
  member Zero : unit -> unit M
  member add : entity:'TEntity -> expr:obj M -> 'TEntity Entity
  member interrupt : entity:'TEntity Entity -> bool
  ...

Full name: Task.TaskBuilder<_>

--------------------
new : unit -> TaskBuilder<'TEntity>
val bind : (('a -> 'b M) -> 'a M -> 'b M)
val k : ('a -> 'b M)
val v : 'a M
val d : (unit -> 'a M)
val t : unsigned
val f : (unit -> 'a M)
val r : 'a
val delay : ((unit -> 'a M) -> 'a M)
val k : (unit -> 'a M)
val ret : ('a -> 'a M)
val whileLoop : ((unit -> bool) -> 'a M -> unit M)
val cond : (unit -> bool)
type bool = Boolean

Full name: Microsoft.FSharp.Core.bool
val expr : 'a M
val forLoop : (seq<'a> -> ('a -> 'b M) -> unit M)
val lst : seq<'a>
Multiple items
val seq : sequence:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Core.Operators.seq

--------------------
type seq<'T> = IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>
val body : ('a -> 'b M)
val iter : IEnumerator<'a>
IEnumerable.GetEnumerator() : IEnumerator<'a>
property IEnumerator.Current: 'a
Collections.IEnumerator.MoveNext() : bool
val mutable offset : uint64
val mutable last : int
type Int32 =
  struct
    member CompareTo : value:obj -> int + 1 overload
    member Equals : obj:obj -> bool + 1 overload
    member GetHashCode : unit -> int
    member GetTypeCode : unit -> TypeCode
    member ToString : unit -> string + 3 overloads
    static val MaxValue : int
    static val MinValue : int
    static member Parse : s:string -> int + 3 overloads
    static member TryParse : s:string * result:int -> bool + 1 overload
  end

Full name: System.Int32
field int.MinValue = -2147483648
val tasks : SortedSet<'TEntity Entity>
Multiple items
type SortedSet<'T> =
  new : unit -> SortedSet<'T> + 3 overloads
  member Add : item:'T -> bool
  member Clear : unit -> unit
  member Comparer : IComparer<'T>
  member Contains : item:'T -> bool
  member CopyTo : array:'T[] -> unit + 2 overloads
  member Count : int
  member ExceptWith : other:IEnumerable<'T> -> unit
  member GetEnumerator : unit -> Enumerator<'T>
  member GetViewBetween : lowerValue:'T * upperValue:'T -> SortedSet<'T>
  ...
  nested type Enumerator

Full name: System.Collections.Generic.SortedSet<_>

--------------------
SortedSet() : unit
SortedSet(comparer: IComparer<'T>) : unit
SortedSet(collection: IEnumerable<'T>) : unit
SortedSet(collection: IEnumerable<'T>, comparer: IComparer<'T>) : unit
val ticks : (unit -> uint64)
val ticks : int
type Environment =
  static member CommandLine : string
  static member CurrentDirectory : string with get, set
  static member Exit : exitCode:int -> unit
  static member ExitCode : int with get, set
  static member ExpandEnvironmentVariables : name:string -> string
  static member FailFast : message:string -> unit + 1 overload
  static member GetCommandLineArgs : unit -> string[]
  static member GetEnvironmentVariable : variable:string -> string + 1 overload
  static member GetEnvironmentVariables : unit -> IDictionary + 1 overload
  static member GetFolderPath : folder:SpecialFolder -> string + 1 overload
  ...
  nested type SpecialFolder
  nested type SpecialFolderOption

Full name: System.Environment
property Environment.TickCount: int
type UInt32 =
  struct
    member CompareTo : value:obj -> int + 1 overload
    member Equals : obj:obj -> bool + 1 overload
    member GetHashCode : unit -> int
    member GetTypeCode : unit -> TypeCode
    member ToString : unit -> string + 3 overloads
    static val MaxValue : uint32
    static val MinValue : uint32
    static member Parse : s:string -> uint32 + 3 overloads
    static member TryParse : s:string * result:uint32 -> bool + 1 overload
  end

Full name: System.UInt32
field uint32.MaxValue = 4294967295u
val peek : (unsigned -> 'b M -> bool)
val ticks : unsigned
val task : 'b M
val eval : ('a M -> 'a M)
val task : 'a M
val v : 'a
val mutable counter : uint64
val makeId : (unit -> uint64)
val ret : uint64
val o : TaskBuilder<'TEntity>
member TaskBuilder.Bind : v:'a M * k:('a -> 'b M) -> 'b M

Full name: Task.TaskBuilder`1.Bind
member TaskBuilder.Return : r:'a -> 'a M

Full name: Task.TaskBuilder`1.Return
member TaskBuilder.Delay : k:(unit -> 'a M) -> 'a M

Full name: Task.TaskBuilder`1.Delay
member TaskBuilder.While : cond:(unit -> bool) * expr:'a M -> unit M

Full name: Task.TaskBuilder`1.While
member TaskBuilder.Zero : unit -> unit M

Full name: Task.TaskBuilder`1.Zero
member TaskBuilder.For : lst:seq<'a> * body:('a -> 'b M) -> unit M

Full name: Task.TaskBuilder`1.For
member TaskBuilder.Combine : first:unit M * second:'a M -> 'a M

Full name: Task.TaskBuilder`1.Combine
val first : unit M
val second : 'a M
member TaskBuilder.add : entity:'TEntity -> expr:obj M -> 'TEntity Entity

Full name: Task.TaskBuilder`1.add
val entity : 'TEntity
val expr : obj M
val entity : 'TEntity Entity
SortedSet.Add(item: 'TEntity Entity) : bool
val ignore : value:'T -> unit

Full name: Microsoft.FSharp.Core.Operators.ignore
member TaskBuilder.interrupt : entity:'TEntity Entity -> bool

Full name: Task.TaskBuilder`1.interrupt
val m : (unit -> obj M)
SortedSet.Remove(item: 'TEntity Entity) : bool
member TaskBuilder.sleep : dt:int -> unit M

Full name: Task.TaskBuilder`1.sleep
val dt : int
val t : uint64
member TaskBuilder.tick : unit -> unit

Full name: Task.TaskBuilder`1.tick
val ticks : uint64
property SortedSet.Count: int
val nextTick : List<'TEntity Entity>
type ResizeArray<'T> = List<'T>

Full name: Microsoft.FSharp.Collections.ResizeArray<_>
property SortedSet.Min: 'TEntity Entity
val task : obj M
List.Add(item: 'TEntity Entity) : unit
module Seq

from Microsoft.FSharp.Collections
val iter : action:('T -> unit) -> source:seq<'T> -> unit

Full name: Microsoft.FSharp.Collections.Seq.iter
val m : 'TEntity Entity
val task : TaskBuilder<unit>

Full name: Task.task
type Console =
  static member BackgroundColor : ConsoleColor with get, set
  static member Beep : unit -> unit + 1 overload
  static member BufferHeight : int with get, set
  static member BufferWidth : int with get, set
  static member CapsLock : bool
  static member Clear : unit -> unit
  static member CursorLeft : int with get, set
  static member CursorSize : int with get, set
  static member CursorTop : int with get, set
  static member CursorVisible : bool with get, set
  ...

Full name: System.Console
Console.ReadLine() : string
Raw view Test code New version

More information

Link:http://fssnip.net/9k
Posted:14 years ago
Author:
Tags: