Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
AsynchronousChannelMergeEnumerator.cs
Go to the documentation of this file.
2
4{
5 private readonly AsynchronousChannel<T>[] _channels;
6
8
9 private readonly bool[] _done;
10
11 private int _channelIndex;
12
13 private T _currentElement;
14
15 public override T Current
16 {
17 get
18 {
19 if (_channelIndex == -1 || _channelIndex == _channels.Length)
20 {
22 }
23 return _currentElement;
24 }
25 }
26
28 : base(taskGroupState)
29 {
30 _channels = channels;
31 _channelIndex = -1;
32 _done = new bool[_channels.Length];
33 _consumerEvent = consumerEvent;
34 }
35
36 public override bool MoveNext()
37 {
38 int num = _channelIndex;
39 if (num == -1)
40 {
41 num = (_channelIndex = 0);
42 }
43 if (num == _channels.Length)
44 {
45 return false;
46 }
47 if (!_done[num] && _channels[num].TryDequeue(ref _currentElement))
48 {
49 _channelIndex = (num + 1) % _channels.Length;
50 return true;
51 }
52 return MoveNextSlowPath();
53 }
54
55 private bool MoveNextSlowPath()
56 {
57 int num = 0;
58 int num2 = _channelIndex;
59 int channelIndex;
60 while ((channelIndex = _channelIndex) != _channels.Length)
61 {
62 AsynchronousChannel<T> asynchronousChannel = _channels[channelIndex];
63 bool flag = _done[channelIndex];
64 if (!flag && asynchronousChannel.TryDequeue(ref _currentElement))
65 {
66 _channelIndex = (channelIndex + 1) % _channels.Length;
67 return true;
68 }
69 if (!flag && asynchronousChannel.IsDone)
70 {
71 if (!asynchronousChannel.IsChunkBufferEmpty)
72 {
73 bool flag2 = asynchronousChannel.TryDequeue(ref _currentElement);
74 return true;
75 }
76 _done[channelIndex] = true;
77 flag = true;
78 asynchronousChannel.Dispose();
79 }
80 if (flag && ++num == _channels.Length)
81 {
82 channelIndex = (_channelIndex = _channels.Length);
83 break;
84 }
85 channelIndex = (_channelIndex = (channelIndex + 1) % _channels.Length);
86 if (channelIndex != num2)
87 {
88 continue;
89 }
90 try
91 {
92 num = 0;
93 for (int i = 0; i < _channels.Length; i++)
94 {
95 bool isDone = false;
96 if (!_done[i] && _channels[i].TryDequeue(ref _currentElement, ref isDone))
97 {
98 return true;
99 }
100 if (isDone)
101 {
102 if (!_done[i])
103 {
104 _done[i] = true;
105 }
106 if (++num == _channels.Length)
107 {
108 channelIndex = (_channelIndex = _channels.Length);
109 break;
110 }
111 }
112 }
113 if (channelIndex == _channels.Length)
114 {
115 break;
116 }
118 channelIndex = (_channelIndex = _consumerEvent.Value);
120 num2 = channelIndex;
121 num = 0;
122 continue;
123 }
124 finally
125 {
126 for (int j = 0; j < _channels.Length; j++)
127 {
128 if (!_done[j])
129 {
130 _channels[j].DoneWithDequeueWait();
131 }
132 }
133 }
134 }
135 _taskGroupState.QueryEnd(userInitiatedDispose: false);
136 return false;
137 }
138
139 public override void Dispose()
140 {
141 if (_consumerEvent != null)
142 {
143 base.Dispose();
145 _consumerEvent = null;
146 }
147 }
148}
AsynchronousChannelMergeEnumerator(QueryTaskGroupState taskGroupState, AsynchronousChannel< T >[] channels, IntValueEvent consumerEvent)
bool TryDequeue([MaybeNullWhen(false)][AllowNull] ref T item)
void QueryEnd(bool userInitiatedDispose)
static string PLINQ_CommonEnumerator_Current_NotStarted
Definition SR.cs:24
Definition SR.cs:7