0 people like it.
Like the snippet!
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
More information