NxListT

Scripts

14 years
edited 8 years
Code (jass) Select
1
library NxListT /* v1.0.0.1
2
************************************************************************************
3
*
4
*	*/ uses /*
5
*
6
*		*/ ErrorMessage	/*
7
*		*/ TableField	/*
8
*
9
************************************************************************************
10
*
11
*	module NxListT
12
*
13
*		Description
14
*		-------------------------
15
*
16
*			NA
17
*
18
*		Fields
19
*		-------------------------
20
*
21
*			readonly static integer sentinel
22
*
23
*			readonly thistype list
24
*
25
*			readonly thistype first
26
*			readonly thistype last
27
*
28
*			readonly thistype next
29
*		readonly thistype prev
30
*
31
*		Methods
32
*		-------------------------
33
*
34
*			method destroy takes nothing returns nothing
35
*				-	May only destroy lists
36
*
37
*			method push takes nothing returns thistype
38
*			method enqueue takes nothing returns thistype
39
*
40
*			method pop takes nothing returns nothing
41
*			method dequeue takes nothing returns nothing
42
*
43
*			method remove takes nothing returns nothing
44
*
45
*			method clear takes nothing returns nothing
46
*				-	Initializes list, use instead of create
47
*
48
*			debug static method calculateMemoryUsage takes nothing returns integer
49
*			debug static method getAllocatedMemoryAsString takes nothing returns string
50
*
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 NxListT
61
		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
		endif
67
		
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_list
73
		endmethod
74
		
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_next
80
		endmethod
81
		
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_prev
87
		endmethod
88
		
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_first
94
		endmethod
95
		
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_last
101
		endmethod
102
		
103
		static method operator sentinel takes nothing returns integer
104
			return 0
105
		endmethod
106
		
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
			else
114
				set thistype(0).p_next = p_next
115
			endif
116
			
117
			return this
118
		endmethod
119
		
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
			else
135
				set p_first.p_prev = node
136
				set node.p_next = p_first
137
				set p_first = node
138
			endif
139
			
140
			set node.p_prev = 0
141
			
142
			return node
143
		endmethod
144
		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
			else
159
				set p_last.p_next = node
160
				set node.p_prev = p_last
161
				set p_last = node
162
			endif
163
			
164
			set node.p_next = 0
165
			
166
			return node
167
		endmethod
168
		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
			else
183
				set p_first.p_prev = 0
184
			endif
185
			
186
			set node.p_next = thistype(0).p_next
187
			set thistype(0).p_next = node
188
		endmethod
189
		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
			else
204
				set p_last.p_next = 0
205
			endif
206
			
207
			set node.p_next = thistype(0).p_next
208
			set thistype(0).p_next = node
209
		endmethod
210
		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
			else
224
				set node.p_prev.p_next = node.p_next
225
			endif
226
			if (0 == node.p_next) then
227
				set p_last = node.p_prev
228
			else
229
				set node.p_next.p_prev = node.p_prev
230
			endif
231
			
232
			set node.p_next = thistype(0).p_next
233
			set thistype(0).p_next = node
234
		endmethod
235
		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
				loop
251
					exitwhen node == 0
252
					set node.isNode = false
253
					set node = node.p_next
254
				endloop
255
			endif
256
			
257
			if (p_first == 0) then
258
				return
259
			endif
260
			
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
		endmethod
267
		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
		endmethod
275
		
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
			endif
281
			//! 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
		endmethod
287
		
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
				loop
295
					exitwhen integer(start) > integer(end)
296
					if (integer(start) + 500 > integer(end)) then
297
						return count + checkRegion(start, end)
298
					else
299
						set count = count + checkRegion(start, start + 500)
300
						set start = start + 501
301
					endif
302
				endloop
303
				
304
				return count
305
			endmethod
306
			
307
			private static method checkRegion takes thistype start, thistype end returns integer
308
				local integer count = 0
309
			
310
				loop
311
					exitwhen integer(start) > integer(end)
312
					if (start.isNode) then
313
						set count = count + 1
314
					endif
315
					if (start.isCollection) then
316
						set count = count + 1
317
					endif
318
					set start = start + 1
319
				endloop
320
				
321
				return count
322
			endmethod
323
			
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
				loop
330
					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
					else
335
						set memory = memory + checkRegion2(start, start + 500)
336
						set start = start + 501
337
					endif
338
				endloop
339
				
340
				return memory
341
			endmethod
342
			
343
			private static method checkRegion2 takes thistype start, thistype end returns string
344
				local string memory = null
345
			
346
				loop
347
					exitwhen integer(start) > integer(end)
348
					if (start.isNode) then
349
						if (memory == null) then
350
							set memory = I2S(start)
351
						else
352
							set memory = memory + ", " + I2S(start) + "N"
353
						endif
354
					endif
355
					if (start.isCollection) then
356
						if (memory == null) then
357
							set memory = I2S(start)
358
						else
359
							set memory = memory + ", " + I2S(start) + "C"
360
						endif
361
					endif
362
					set start = start + 1
363
				endloop
364
				
365
				return memory
366
			endmethod
367
		endif
368
	endmodule
369
endlibrary