-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathCallBackEventQueue.cs
153 lines (146 loc) · 4.32 KB
/
CallBackEventQueue.cs
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Jint.Ex
{
internal class CallBackEventQueue : IEnumerable<CallBackEvent>
{
private static readonly Object obj = new Object();
private List<CallBackEvent> _queue = new List<CallBackEvent>();
System.Collections.IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
public IEnumerator<CallBackEvent> GetEnumerator()
{
return ((IEnumerable<CallBackEvent>) _queue).GetEnumerator();
}
public int Count {
get { return this._queue.Count; }
}
public CallBackEventQueue Clone()
{
lock (obj)
{
var q = new CallBackEventQueue();
foreach (var e in _queue)
_queue.Add(e);
return q;
}
}
public void RemoveDisabledEvents()
{
lock (obj)
{
var goOn = true;
while (goOn)
{
goOn = false;
foreach (var e in this._queue)
{
if (e.Disabled)
{
this._queue.Remove(e);
goOn = true;
break;
}
}
}
}
}
public CallBackEventQueue GetEventsWithNoDelay()
{
lock (obj)
{
var q = new CallBackEventQueue();
foreach (var e in _queue)
if (e.Delay == 0 && e.Enabled)
q.EnqueueNotSafe(e);
return q;
}
}
public CallBackEventQueue CloneEventWithDelay()
{
lock (obj)
{
var q = new CallBackEventQueue();
foreach (var e in _queue)
if (e.Delay > 0 && e.Enabled)
q.EnqueueNotSafe(e);
return q;
}
}
public void Clear()
{
// No need to lock because this method is only called by
// the event loop
this._queue.Clear();
}
public void RequestScriptExecution(string source)
{
lock (obj)
{
this._queue.Insert(0, new CallBackEvent(source));
}
}
public void EndqueueCallBackExecution(Func<Jint.Native.JsValue, Jint.Native.JsValue[], Jint.Native.JsValue> function, double delay, CallBackType type)
{
lock (obj)
{
this._queue.Add(new CallBackEvent(function, delay, type));
}
}
public CallBackEvent Enqueue(CallBackEvent c)
{
lock (obj)
{
this._queue.Add(c);
}
return c;
}
internal void EnqueueNotSafe(CallBackEvent c)
{
this._queue.Add(c);
}
public CallBackEvent Dequeue()
{
lock (obj)
{
var c = this._queue[0];
this._queue.RemoveAt(0);
return c;
}
}
public CallBackEvent Peek()
{
lock (obj)
{
return this._queue[0];
}
}
public void ClearCallBackEvent(int id)
{
lock (obj)
{
var c = this._queue.FirstOrDefault(e => e.Id == id);
if (c == null)
throw new ArgumentException(string.Format("Cannot find timeout or interval id {0}", id));
else
c.Disable();
}
}
public void RemoveTopBecauseProcessed(CallBackEvent c, bool mainQueue)
{
lock (obj)
{
var cc = this._queue.Find(e => e == c);
if (cc != null)
this._queue.Remove(cc);
if (mainQueue)
if (c.Type == CallBackType.Interval) // for Interval we re add the event at then end of the queue
this.Enqueue(c);
}
}
}
}