14 years
edited 8 years
1 library NxListT /* v1.0.0.1
2 ************************************************************************************3 *4 * */ uses /*
5 *6 * */ ErrorMessage /*
7 * */ TableField /*
8 *9 ************************************************************************************10 *11 * module NxListT12 *13 * Description14 * -------------------------15 *16 * NA17 *18 * Fields19 * -------------------------20 *21 * readonly static integer sentinel22 *23 * readonly thistype list24 *25 * readonly thistype first26 * readonly thistype last27 *28 * readonly thistype next29 * readonly thistype prev30 *31 * Methods32 * -------------------------33 *34 * method destroy takes nothing returns nothing35 * - May only destroy lists36 *37 * method push takes nothing returns thistype38 * method enqueue takes nothing returns thistype39 *40 * method pop takes nothing returns nothing41 * method dequeue takes nothing returns nothing42 *43 * method remove takes nothing returns nothing44 *45 * method clear takes nothing returns nothing46 * - Initializes list, use instead of create47 *48 * debug static method calculateMemoryUsage takes nothing returns integer49 * debug static method getAllocatedMemoryAsString takes nothing returns string50 *51 ************************************************************************************/52 private keyword isNode
53 private keyword isCollection
54 private keyword p_list
55 private keyword p_next
56 private keyword p_prev
57 private keyword p_first
58 private keyword p_last
59
60 module NxListT61 private static thistype nodeCount = 0
62
63 static if DEBUG_MODE then
64 //! runtextmacro CREATE_TABLE_FIELD("public", "boolean", "isNode", "boolean")65 //! runtextmacro CREATE_TABLE_FIELD("public", "boolean", "isCollection", "boolean")66 endif67
68 //! runtextmacro CREATE_TABLE_FIELD("public", "integer", "p_list", "thistype")69 method operator list takes nothing returns thistype
70 debug call ThrowError(this == 0, "NxList", "list", "thistype", this, "Attempted To Read Null Node.")
71 debug call ThrowError(not isNode, "NxList", "list", "thistype", this, "Attempted To Read Invalid Node.")
72 return p_list73 endmethod74
75 //! runtextmacro CREATE_TABLE_FIELD("public", "integer", "p_next", "thistype")76 method operator next takes nothing returns thistype
77 debug call ThrowError(this == 0, "NxList", "next", "thistype", this, "Attempted To Go Out Of Bounds.")
78 debug call ThrowError(not isNode, "NxList", "next", "thistype", this, "Attempted To Read Invalid Node.")
79 return p_next80 endmethod81
82 //! runtextmacro CREATE_TABLE_FIELD("public", "integer", "p_prev", "thistype")83 method operator prev takes nothing returns thistype
84 debug call ThrowError(this == 0, "NxList", "prev", "thistype", this, "Attempted To Go Out Of Bounds.")
85 debug call ThrowError(not isNode, "NxList", "prev", "thistype", this, "Attempted To Read Invalid Node.")
86 return p_prev87 endmethod88
89 //! runtextmacro CREATE_TABLE_FIELD("public", "integer", "p_first", "thistype") 90 method operator first takes nothing returns thistype
91 debug call ThrowError(this == 0, "NxList", "first", "thistype", this, "Attempted To Read Null List.")
92 debug call ThrowError(not isCollection, "NxList", "first", "thistype", this, "Attempted To Read Invalid List.")
93 return p_first94 endmethod95
96 //! runtextmacro CREATE_TABLE_FIELD("public", "integer", "p_last", "thistype")97 method operator last takes nothing returns thistype
98 debug call ThrowError(this == 0, "NxList", "last", "thistype", this, "Attempted To Read Null List.")
99 debug call ThrowError(not isCollection, "NxList", "last", "thistype", this, "Attempted To Read Invalid List.")
100 return p_last101 endmethod102
103 static method operator sentinel takes nothing returns integer
104 return 0
105 endmethod106
107 private static method allocateNode takes nothing returns thistype
108 local thistype this = thistype(0).p_next
109
110 if (0 == this) then
111 set this = nodeCount + 1
112 set nodeCount = this
113 else114 set thistype(0).p_next = p_next
115 endif116
117 return this
118 endmethod119
120 method push takes nothing returns thistype
121 local thistype node = allocateNode()
122
123 debug call ThrowError(this == 0, "NxList", "push", "thistype", this, "Attempted To Push On To Null List.")
124 debug call ThrowError(not isCollection, "NxList", "push", "thistype", this, "Attempted To Push On To Invalid List.")
125
126 debug set node.isNode = true
127
128 set node.p_list = this
129
130 if (p_first == 0) then
131 set p_first = node
132 set p_last = node
133 set node.p_next = 0
134 else135 set p_first.p_prev = node
136 set node.p_next = p_first
137 set p_first = node
138 endif139
140 set node.p_prev = 0
141
142 return node143 endmethod144 method enqueue takes nothing returns thistype
145 local thistype node = allocateNode()
146
147 debug call ThrowError(this == 0, "NxList", "enqueue", "thistype", this, "Attempted To Enqueue On To Null List.")
148 debug call ThrowError(not isCollection, "NxList", "enqueue", "thistype", this, "Attempted To Enqueue On To Invalid List.")
149
150 debug set node.isNode = true
151
152 set node.p_list = this
153
154 if (p_first == 0) then
155 set p_first = node
156 set p_last = node
157 set node.p_prev = 0
158 else159 set p_last.p_next = node
160 set node.p_prev = p_last
161 set p_last = node
162 endif163
164 set node.p_next = 0
165
166 return node167 endmethod168 method pop takes nothing returns nothing
169 local thistype node = p_first
170
171 debug call ThrowError(this == 0, "NxList", "pop", "thistype", this, "Attempted To Pop Null List.")
172 debug call ThrowError(not isCollection, "NxList", "pop", "thistype", this, "Attempted To Pop Invalid List.")
173 debug call ThrowError(node == 0, "NxList", "pop", "thistype", this, "Attempted To Pop Empty List.")
174
175 debug set node.isNode = false
176
177 set p_first.p_list = 0
178
179 set p_first = p_first.p_next
180 if (p_first == 0) then
181 set p_last = 0
182 else183 set p_first.p_prev = 0
184 endif185
186 set node.p_next = thistype(0).p_next
187 set thistype(0).p_next = node
188 endmethod189 method dequeue takes nothing returns nothing
190 local thistype node = p_last
191
192 debug call ThrowError(this == 0, "NxList", "dequeue", "thistype", this, "Attempted To Dequeue Null List.")
193 debug call ThrowError(not isCollection, "NxList", "dequeue", "thistype", this, "Attempted To Dequeue Invalid List.")
194 debug call ThrowError(node == 0, "NxList", "dequeue", "thistype", this, "Attempted To Dequeue Empty List.")
195
196 debug set node.isNode = false
197
198 set p_last.p_list = 0
199
200 set p_last = p_last.p_prev
201 if (p_last == 0) then
202 set p_first = 0
203 else204 set p_last.p_next = 0
205 endif206
207 set node.p_next = thistype(0).p_next
208 set thistype(0).p_next = node
209 endmethod210 method remove takes nothing returns nothing
211 local thistype node = this
212 set this = node.p_list
213
214 debug call ThrowError(node == 0, "NxList", "remove", "thistype", this, "Attempted To Remove Null Node.")
215 debug call ThrowError(not node.isNode, "NxList", "remove", "thistype", this, "Attempted To Remove Invalid Node (" + I2S(node) + ").")
216
217 debug set node.isNode = false
218
219 set node.p_list = 0
220
221 if (0 == node.p_prev) then
222 set p_first = node.p_next
223 else224 set node.p_prev.p_next = node.p_next
225 endif226 if (0 == node.p_next) then
227 set p_last = node.p_prev
228 else229 set node.p_next.p_prev = node.p_prev
230 endif231
232 set node.p_next = thistype(0).p_next
233 set thistype(0).p_next = node
234 endmethod235 method clear takes nothing returns nothing
236 debug local thistype node = p_first
237
238 debug call ThrowError(this == 0, "NxList", "clear", "thistype", this, "Attempted To Clear Null List.")
239
240 debug if (not isCollection) then
241 debug set isCollection = true
242
243 debug set p_first = 0
244 debug set p_last = 0
245
246 debug return
247 debug endif
248
249 static if DEBUG_MODE then
250 loop251 exitwhen node == 0
252 set node.isNode = false
253 set node = node.p_next
254 endloop255 endif256
257 if (p_first == 0) then
258 return259 endif260
261 set p_last.p_next = thistype(0).p_next
262 set thistype(0).p_next = p_first
263
264 set p_first = 0
265 set p_last = 0
266 endmethod267 method destroy takes nothing returns nothing
268 debug call ThrowError(this == 0, "NxList", "destroy", "thistype", this, "Attempted To Destroy Null List.")
269 debug call ThrowError(not isCollection, "NxList", "destroy", "thistype", this, "Attempted To Destroy Invalid List.")
270
271 call clear()
272
273 debug set isCollection = false
274 endmethod275
276 private static method onInit takes nothing returns nothing
277 static if DEBUG_MODE then
278 //! runtextmacro INITIALIZE_TABLE_FIELD("isNode")279 //! runtextmacro INITIALIZE_TABLE_FIELD("isCollection")280 endif281 //! runtextmacro INITIALIZE_TABLE_FIELD("p_list")282 //! runtextmacro INITIALIZE_TABLE_FIELD("p_next")283 //! runtextmacro INITIALIZE_TABLE_FIELD("p_prev")284 //! runtextmacro INITIALIZE_TABLE_FIELD("p_first")285 //! runtextmacro INITIALIZE_TABLE_FIELD("p_last")286 endmethod287
288 static if DEBUG_MODE then
289 static method calculateMemoryUsage takes nothing returns integer
290 local thistype start = 1
291 local thistype end = 8191
292 local integer count = 0
293
294 loop295 exitwhen integer(start) > integer(end)
296 if (integer(start) + 500 > integer(end)) then
297 return count + checkRegion(start, end)
298 else299 set count = count + checkRegion(start, start + 500)
300 set start = start + 501
301 endif302 endloop303
304 return count305 endmethod306
307 private static method checkRegion takes thistype start, thistype end returns integer
308 local integer count = 0
309
310 loop311 exitwhen integer(start) > integer(end)
312 if (start.isNode) then
313 set count = count + 1
314 endif315 if (start.isCollection) then
316 set count = count + 1
317 endif318 set start = start + 1
319 endloop320
321 return count322 endmethod323
324 static method getAllocatedMemoryAsString takes nothing returns string
325 local thistype start = 1
326 local thistype end = 8191
327 local string memory = null
328
329 loop330 exitwhen integer(start) > integer(end)
331 if (integer(start) + 500 > integer(end)) then
332 set memory = memory + checkRegion2(start, end)
333 set start = end + 1
334 else335 set memory = memory + checkRegion2(start, start + 500)
336 set start = start + 501
337 endif338 endloop339
340 return memory341 endmethod342
343 private static method checkRegion2 takes thistype start, thistype end returns string
344 local string memory = null
345
346 loop347 exitwhen integer(start) > integer(end)
348 if (start.isNode) then
349 if (memory == null) then
350 set memory = I2S(start)
351 else352 set memory = memory + ", " + I2S(start) + "N"
353 endif354 endif355 if (start.isCollection) then
356 if (memory == null) then
357 set memory = I2S(start)
358 else359 set memory = memory + ", " + I2S(start) + "C"
360 endif361 endif362 set start = start + 1
363 endloop364
365 return memory366 endmethod367 endif368 endmodule369 endlibrary