-
Notifications
You must be signed in to change notification settings - Fork 7
/
base.util.objectqueue.bmx
executable file
·262 lines (206 loc) · 4.91 KB
/
base.util.objectqueue.bmx
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
SuperStrict
'FIFO container
'converted from: BMX-NG/brl.mod/collection.mod/queue.mod
' licence: zlib/libPNG
Type TObjectQueue
Field initialCapacity:Int
Field data:Object[]
Field head:Int
Field tail:Int
Field size:Int
Field full:Int
Method New()
Self.initialCapacity = 16
data = New Object[initialCapacity]
End Method
Rem
Method GetIterator:IIterator<T>()
Return New TQueueIterator<T>(Self)
End Method
endrem
'Gets the number of elements contained in the container.
Method Count:Int()
Return size
End Method
'Returns True if the container is empty, otherwise fFalse.
Method IsEmpty:Int()
Return size = 0
End Method
'Converts the container to an array.
'returns: An array of elements.
Method ToArray:Object[]()
Local arr:Object[size]
Local i:Int
For Local o:Object = EachIn Self
arr[i] = o
i :+ 1
Next
Return arr
End Method
'Removes all elements from the container.
Method Clear()
If size Then
Local index:Int = head
Repeat
data[index] = Null
index :+ 1
If index = data.length Then
index = 0
End If
Until index = tail
size = 0
head = tail
End If
End Method
'Determines whether an element is in the container.
Method Contains:Int(o:Object)
If Not size Then
Return False
End If
Local index:Int = head
Repeat
If o = data[index] Then
Return True
End If
index :+ 1
If index = data.length Then
index = 0
End If
Until index = tail
Return False
End Method
'Removes and returns the element at the beginning of the container
'Similar to the Peek() method, but Peek() does not modify the container.
Method Dequeue:Object()
If Not size Then
Throw "The container is empty"
End If
full = False
Local o:Object = data[head]
head :+ 1
size :- 1
If head = data.length Then
head = 0
End If
Return o
End Method
'Adds an element to the end of the container.
'If Count() already equals the capacity, the capacity of the container
'is increased by automatically reallocating the internal array, and
'the existing elements are copied to the new array before the new
'element is added.
Method Enqueue(o:Object)
If full Then
Resize()
End If
If Not full Then
data[tail] = o
tail :+ 1
size :+ 1
If tail = data.length Then
tail = 0
End If
If tail = head Then
full = True
End If
End If
End Method
'Returns the element at the beginning of the container without
'removing it.
Method Peek:Object()
If Not size Then
Throw "The container is empty"
End If
Return data[head]
End Method
'Can be used to minimize a collection's memory overhead if no new
'elements will be added to the collection.
Method TrimExcess()
Local temp:Object[]
If Not size Then
temp = temp[..initialCapacity]
Else If size < data.length Then
temp = temp[..size]
End If
Local tempIndex:Int
Local dataIndex:Int = head
Repeat
temp[tempIndex] = data[dataIndex]
dataIndex :+ 1
If dataIndex = data.length Then
dataIndex = 0
End If
tempIndex :+ 1
Until dataIndex = tail
head = 0
data = temp
tail = 0
full = size > 0
End Method
'Tries to remove and return the element at the beginning of the
'container.
'returns: True if an element was removed and returned from the
' beginning of the container successfully; otherwise, False.
'When this method returns, if the operation was successful, value
'contains the element removed. If no element was available to be
'removed, the value is unspecified.
Method TryDequeue:Int(value:Object Var)
If Not size Then
Return False
End If
value = Dequeue()
Return True
End Method
'Tries to return an element from the beginning of the container
'without removing it.
'returns: True if an element was returned successfully; otherwise, False.
'When this method returns, value contains an element from the
'beginning of the container or an unspecified value if the operation
'failed.
Method TryPeek:Int(value:Object Var)
If Not size Then
Return False
End If
value = data[head]
Return True
End Method
Method Resize()
Local temp:Object[] = New Object[data.length * 2]
Local tempIndex:Int
Local dataIndex:Int = head
Repeat
temp[tempIndex] = data[dataIndex]
dataIndex :+ 1
If dataIndex = data.length Then
dataIndex = 0
End If
tempIndex :+ 1
Until dataIndex = tail
head = 0
tail = data.length
data = temp
full = False
End Method
Method ObjectEnumerator:TObjectQueueEnumerator()
Local enumerator:TObjectQueueEnumerator = New TObjectQueueEnumerator
enumerator.objectQueue = Self
enumerator.length = Count()
Return enumerator
End Method
End Type
Type TObjectQueueEnumerator
Field index:Int
Field length:Int
Field objectQueue:TObjectQueue
Method HasNext:Int()
Return index < length
End Method
Method NextObject:Object()
Local o:Object
If objectQueue.TryDequeue(o)
index :+ 1
Return o
EndIf
Return Null
End Method
End Type