14 years
edited 8 years
1 library UniqueNxListT /* v1.0.0.1
2 ************************************************************************************3 *4 * */ uses /*
5 *6 * */ ErrorMessage /*
7 * */ TableField /*
8 *9 ************************************************************************************10 *11 * module UniqueNxListT12 *13 * Description14 * -------------------------15 *16 * Node Properties:17 *18 * Unique19 * Allocated20 * Not 021 *22 * Fields23 * -------------------------24 *25 * readonly static integer sentinel26 *27 * readonly thistype list28 *29 * readonly thistype first30 * readonly thistype last31 *32 * readonly thistype next33 * readonly thistype prev34 *35 * Methods36 * -------------------------37 *38 * method destroy takes nothing returns nothing39 * - May only destroy lists40 *41 * method push takes thistype node returns nothing42 * method enqueue takes thistype node returns nothing43 *44 * method pop takes nothing returns nothing45 * method dequeue takes nothing returns nothing46 *47 * method remove takes nothing returns nothing48 *49 * method clear takes nothing returns nothing50 * - Initializes list, use instead of create51 *52 * debug static method calculateMemoryUsage takes nothing returns integer53 * debug static method getAllocatedMemoryAsString takes nothing returns string54 *55 ************************************************************************************/56 private keyword isNode
57 private keyword isCollection
58 private keyword p_list
59 private keyword p_next
60 private keyword p_prev
61 private keyword p_first
62 private keyword p_last
63 64 module UniqueNxListT65 static if DEBUG_MODE then
66 //! runtextmacro CREATE_TABLE_FIELD("public", "boolean", "isNode", "boolean")67 //! runtextmacro CREATE_TABLE_FIELD("public", "boolean", "isCollection", "boolean")68 endif69
70 //! runtextmacro CREATE_TABLE_FIELD("public", "integer", "p_list", "thistype")71 method operator list takes nothing returns thistype
72 debug call ThrowError(this == 0, "UniqueNxListT", "list", "thistype", this, "Attempted To Read Null Node.")
73 debug call ThrowError(not isNode, "UniqueNxListT", "list", "thistype", this, "Attempted To Read Invalid Node.")
74 return p_list75 endmethod76
77 //! runtextmacro CREATE_TABLE_FIELD("public", "integer", "p_next", "thistype")78 method operator next takes nothing returns thistype
79 debug call ThrowError(this == 0, "UniqueNxListT", "next", "thistype", this, "Attempted To Go Out Of Bounds.")
80 debug call ThrowError(not isNode, "UniqueNxListT", "next", "thistype", this, "Attempted To Read Invalid Node.")
81 return p_next82 endmethod83
84 //! runtextmacro CREATE_TABLE_FIELD("public", "integer", "p_prev", "thistype")85 method operator prev takes nothing returns thistype
86 debug call ThrowError(this == 0, "UniqueNxListT", "prev", "thistype", this, "Attempted To Go Out Of Bounds.")
87 debug call ThrowError(not isNode, "UniqueNxListT", "prev", "thistype", this, "Attempted To Read Invalid Node.")
88 return p_prev89 endmethod90
91 //! runtextmacro CREATE_TABLE_FIELD("public", "integer", "p_first", "thistype")92 method operator first takes nothing returns thistype
93 debug call ThrowError(this == 0, "UniqueNxListT", "first", "thistype", this, "Attempted To Read Null List.")
94 debug call ThrowError(not isCollection, "UniqueNxListT", "first", "thistype", this, "Attempted To Read Invalid List.")
95 return p_first96 endmethod97
98 //! runtextmacro CREATE_TABLE_FIELD("public", "integer", "p_last", "thistype")99 method operator last takes nothing returns thistype
100 debug call ThrowError(this == 0, "UniqueNxListT", "last", "thistype", this, "Attempted To Read Null List.")
101 debug call ThrowError(not isCollection, "UniqueNxListT", "last", "thistype", this, "Attempted To Read Invalid List.")
102 return p_last103 endmethod104
105 static method operator sentinel takes nothing returns integer
106 return 0
107 endmethod108
109 method push takes thistype node returns nothing
110 debug call ThrowError(this == 0, "UniqueNxListT", "push", "thistype", this, "Attempted To Push (" + I2S(node) + ") On To Null List.")
111 debug call ThrowError(not isCollection, "UniqueNxListT", "push", "thistype", this, "Attempted To Push (" + I2S(node) + ") On To Invalid List.")
112 debug call ThrowError(node == 0, "UniqueNxListT", "push", "thistype", this, "Attempted To Push Null Node.")
113 debug call ThrowError(node.isNode, "UniqueNxListT", "push", "thistype", this, "Attempted To Push Owned Node (" + I2S(node) + ").")
114
115 debug set node.isNode = true
116
117 set node.p_list = this
118
119 if (p_first == 0) then
120 set p_first = node
121 set p_last = node
122 set node.p_next = 0
123 else124 set p_first.p_prev = node
125 set node.p_next = p_first
126 set p_first = node
127 endif128
129 set node.p_prev = 0
130 endmethod131 method enqueue takes thistype node returns nothing
132 debug call ThrowError(this == 0, "UniqueNxListT", "enqueue", "thistype", this, "Attempted To Enqueue (" + I2S(node) + ") On To Null List.")
133 debug call ThrowError(not isCollection, "UniqueNxListT", "enqueue", "thistype", this, "Attempted To Enqueue (" + I2S(node) + ") On To Invalid List.")
134 debug call ThrowError(node == 0, "UniqueNxListT", "enqueue", "thistype", this, "Attempted To Enqueue Null Node.")
135 debug call ThrowError(node.isNode, "UniqueNxListT", "enqueue", "thistype", this, "Attempted To Enqueue Owned Node (" + I2S(node) + ").")
136
137 debug set node.isNode = true
138
139 set node.p_list = this
140
141 if (p_first == 0) then
142 set p_first = node
143 set p_last = node
144 set node.p_prev = 0
145 else146 set p_last.p_next = node
147 set node.p_prev = p_last
148 set p_last = node
149 endif150
151 set node.p_next = 0
152 endmethod153 method pop takes nothing returns nothing
154 debug call ThrowError(this == 0, "UniqueNxListT", "pop", "thistype", this, "Attempted To Pop Null List.")
155 debug call ThrowError(not isCollection, "UniqueNxListT", "pop", "thistype", this, "Attempted To Pop Invalid List.")
156 debug call ThrowError(p_first == 0, "UniqueNxListT", "pop", "thistype", this, "Attempted To Pop Empty List.")
157
158 debug set p_first.isNode = false
159
160 set p_first.p_list = 0
161
162 set p_first = p_first.p_next
163 if (p_first == 0) then
164 set p_last = 0
165 else166 set p_first.p_prev = 0
167 endif168 endmethod169 method dequeue takes nothing returns nothing
170 debug call ThrowError(this == 0, "UniqueNxListT", "dequeue", "thistype", this, "Attempted To Dequeue Null List.")
171 debug call ThrowError(not isCollection, "UniqueNxListT", "dequeue", "thistype", this, "Attempted To Dequeue Invalid List.")
172 debug call ThrowError(p_last == 0, "UniqueNxListT", "dequeue", "thistype", this, "Attempted To Dequeue Empty List.")
173
174 debug set p_last.isNode = false
175
176 set p_last.p_list = 0
177
178 set p_last = p_last.p_prev
179 if (p_last == 0) then
180 set p_first = 0
181 else182 set p_last.p_next = 0
183 endif184 endmethod185 method remove takes nothing returns nothing
186 local thistype node = this
187 set this = node.p_list
188
189 debug call ThrowError(node == 0, "UniqueNxListT", "remove", "thistype", this, "Attempted To Remove Null Node.")
190 debug call ThrowError(not node.isNode, "UniqueNxListT", "remove", "thistype", this, "Attempted To Remove Invalid Node (" + I2S(node) + ").")
191
192 debug set node.isNode = false
193
194 set node.p_list = 0
195
196 if (0 == node.p_prev) then
197 set p_first = node.p_next
198 else199 set node.p_prev.p_next = node.p_next
200 endif201 if (0 == node.p_next) then
202 set p_last = node.p_prev
203 else204 set node.p_next.p_prev = node.p_prev
205 endif206 endmethod207 method clear takes nothing returns nothing
208 debug local thistype node = p_first
209
210 debug call ThrowError(this == 0, "UniqueNxListT", "clear", "thistype", this, "Attempted To Clear Null List.")
211
212 debug if (not isCollection) then
213 debug set isCollection = true
214
215 debug set p_first = 0
216 debug set p_last = 0
217
218 debug return
219 debug endif
220
221 static if DEBUG_MODE then
222 loop223 exitwhen node == 0
224 set node.isNode = false
225 set node = node.p_next
226 endloop227 endif228
229 if (p_first == 0) then
230 return231 endif232
233 set p_first = 0
234 set p_last = 0
235 endmethod236 method destroy takes nothing returns nothing
237 debug call ThrowError(this == 0, "UniqueNxListT", "destroy", "thistype", this, "Attempted To Destroy Null List.")
238 debug call ThrowError(not isCollection, "UniqueNxListT", "destroy", "thistype", this, "Attempted To Destroy Invalid List.")
239
240 call clear()
241
242 debug set isCollection = false
243 endmethod244
245 private static method onInit takes nothing returns nothing
246 static if DEBUG_MODE then
247 //! runtextmacro INITIALIZE_TABLE_FIELD("isNode")248 //! runtextmacro INITIALIZE_TABLE_FIELD("isCollection")249 endif250 //! runtextmacro INITIALIZE_TABLE_FIELD("p_list")251 //! runtextmacro INITIALIZE_TABLE_FIELD("p_next")252 //! runtextmacro INITIALIZE_TABLE_FIELD("p_prev")253 //! runtextmacro INITIALIZE_TABLE_FIELD("p_first")254 //! runtextmacro INITIALIZE_TABLE_FIELD("p_last")255 endmethod256
257 static if DEBUG_MODE then
258 static method calculateMemoryUsage takes nothing returns integer
259 local thistype start = 1
260 local thistype end = 8191
261 local integer count = 0
262
263 loop264 exitwhen integer(start) > integer(end)
265 if (integer(start) + 500 > integer(end)) then
266 return count + checkRegion(start, end)
267 else268 set count = count + checkRegion(start, start + 500)
269 set start = start + 501
270 endif271 endloop272
273 return count274 endmethod275
276 private static method checkRegion takes thistype start, thistype end returns integer
277 local integer count = 0
278
279 loop280 exitwhen integer(start) > integer(end)
281 if (start.isNode) then
282 set count = count + 1
283 endif284 if (start.isCollection) then
285 set count = count + 1
286 endif287 set start = start + 1
288 endloop289
290 return count291 endmethod292
293 static method getAllocatedMemoryAsString takes nothing returns string
294 local thistype start = 1
295 local thistype end = 8191
296 local string memory = null
297
298 loop299 exitwhen integer(start) > integer(end)
300 if (integer(start) + 500 > integer(end)) then
301 set memory = memory + checkRegion2(start, end)
302 set start = end + 1
303 else304 set memory = memory + checkRegion2(start, start + 500)
305 set start = start + 501
306 endif307 endloop308
309 return memory310 endmethod311
312 private static method checkRegion2 takes thistype start, thistype end returns string
313 local string memory = null
314
315 loop316 exitwhen integer(start) > integer(end)
317 if (start.isNode) then
318 if (memory == null) then
319 set memory = I2S(start)
320 else321 set memory = memory + ", " + I2S(start) + "N"
322 endif323 endif324 if (start.isCollection) then
325 if (memory == null) then
326 set memory = I2S(start)
327 else328 set memory = memory + ", " + I2S(start) + "C"
329 endif330 endif331 set start = start + 1
332 endloop333
334 return memory335 endmethod336 endif337 endmodule338 endlibrary