UniqueNxlistT

Scripts

14 years
edited 8 years
Code (jass) Select
1
library UniqueNxListT /* v1.0.0.1
2
************************************************************************************
3
*
4
*	*/ uses /*
5
*
6
*		*/ ErrorMessage /*
7
*		*/ TableField	/*
8
*
9
************************************************************************************
10
*
11
*	module UniqueNxListT
12
*
13
*		Description
14
*		-------------------------
15
*
16
*			Node Properties:
17
*
18
*				Unique
19
*				Allocated
20
*				Not 0
21
*
22
*		Fields
23
*		-------------------------
24
*
25
*			readonly static integer sentinel
26
*
27
*			readonly thistype list
28
*
29
*			readonly thistype first
30
*			readonly thistype last
31
*
32
*			readonly thistype next
33
*			readonly thistype prev
34
*
35
*		Methods
36
*		-------------------------
37
*
38
*			method destroy takes nothing returns nothing
39
*				-	May only destroy lists
40
*
41
*			method push takes thistype node returns nothing
42
*			method enqueue takes thistype node returns nothing
43
*
44
*			method pop takes nothing returns nothing
45
*			method dequeue takes nothing returns nothing
46
*
47
*			method remove takes nothing returns nothing
48
*
49
*			method clear takes nothing returns nothing
50
*				-	Initializes list, use instead of create
51
*
52
*			debug static method calculateMemoryUsage takes nothing returns integer
53
*			debug static method getAllocatedMemoryAsString takes nothing returns string
54
*
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 UniqueNxListT
65
		static if DEBUG_MODE then
66
			//! runtextmacro CREATE_TABLE_FIELD("public", "boolean", "isNode", "boolean")
67
			//! runtextmacro CREATE_TABLE_FIELD("public", "boolean", "isCollection", "boolean")
68
		endif
69
		
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_list
75
		endmethod
76
		
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_next
82
		endmethod
83
		
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_prev
89
		endmethod
90
		
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_first
96
		endmethod
97
		
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_last
103
		endmethod
104
		
105
		static method operator sentinel takes nothing returns integer
106
			return 0
107
		endmethod
108
		
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
			else
124
				set p_first.p_prev = node
125
				set node.p_next = p_first
126
				set p_first = node
127
			endif
128
			
129
			set node.p_prev = 0
130
		endmethod
131
		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
			else
146
				set p_last.p_next = node
147
				set node.p_prev = p_last
148
				set p_last = node
149
			endif
150
			
151
			set node.p_next = 0
152
		endmethod
153
		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
			else
166
				set p_first.p_prev = 0
167
			endif
168
		endmethod
169
		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
			else
182
				set p_last.p_next = 0
183
			endif
184
		endmethod
185
		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
			else
199
				set node.p_prev.p_next = node.p_next
200
			endif
201
			if (0 == node.p_next) then
202
				set p_last = node.p_prev
203
			else
204
				set node.p_next.p_prev = node.p_prev
205
			endif
206
		endmethod
207
		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
				loop
223
					exitwhen node == 0
224
					set node.isNode = false
225
					set node = node.p_next
226
				endloop
227
			endif
228
			
229
			if (p_first == 0) then
230
				return
231
			endif
232
			
233
			set p_first = 0
234
			set p_last = 0
235
		endmethod
236
		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
		endmethod
244
		
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
			endif
250
			//! 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
		endmethod
256
		
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
				loop
264
					exitwhen integer(start) > integer(end)
265
					if (integer(start) + 500 > integer(end)) then
266
						return count + checkRegion(start, end)
267
					else
268
						set count = count + checkRegion(start, start + 500)
269
						set start = start + 501
270
					endif
271
				endloop
272
				
273
				return count
274
			endmethod
275
			
276
			private static method checkRegion takes thistype start, thistype end returns integer
277
				local integer count = 0
278
			
279
				loop
280
					exitwhen integer(start) > integer(end)
281
					if (start.isNode) then
282
						set count = count + 1
283
					endif
284
					if (start.isCollection) then
285
						set count = count + 1
286
					endif
287
					set start = start + 1
288
				endloop
289
				
290
				return count
291
			endmethod
292
			
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
				loop
299
					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
					else
304
						set memory = memory + checkRegion2(start, start + 500)
305
						set start = start + 501
306
					endif
307
				endloop
308
				
309
				return memory
310
			endmethod
311
			
312
			private static method checkRegion2 takes thistype start, thistype end returns string
313
				local string memory = null
314
			
315
				loop
316
					exitwhen integer(start) > integer(end)
317
					if (start.isNode) then
318
						if (memory == null) then
319
							set memory = I2S(start)
320
						else
321
							set memory = memory + ", " + I2S(start) + "N"
322
						endif
323
					endif
324
					if (start.isCollection) then
325
						if (memory == null) then
326
							set memory = I2S(start)
327
						else
328
							set memory = memory + ", " + I2S(start) + "C"
329
						endif
330
					endif
331
					set start = start + 1
332
				endloop
333
				
334
				return memory
335
			endmethod
336
		endif
337
	endmodule
338
endlibrary