14 years
edited 8 years
I was in need of something to make messages in Warcraft III pop out Type-writer style, and that would require a Buffer. And since I had some other things that needed to use a buffer (Like a Unit order queue and an AI-Action/Behavior system), I decided that I needed to make them run off of one Buffer system. Hence, I wrote this.
The reason I called it BufferEx is because Nestharus' Save/Load system uses a library called Buffer which can be found in the Small Code Snippets thread at the Hive Workshop.
Code
Demo
Feel free to comment.
The reason I called it BufferEx is because Nestharus' Save/Load system uses a library called Buffer which can be found in the Small Code Snippets thread at the Hive Workshop.
Code
1 /**********************************2 *3 * BufferEx4 * v1.0.0.15 * By Magtheridon966 *7 * - Data structure resource.8 * This buffer is a FIFO (First in, 9 * First out) data structure. 10 * What you write first is read 11 * first.12 *13 * Optional Requirement:14 * ---------------------15 *16 * - Table by Bribe17 * - https://wc3modding.info/4611/snippet-new-table/18 *19 * API:20 * ----21 *22 * struct BufferEx extends array23 *24 * static method create takes nothing returns thistype25 * - Creates a new buffer.26 *27 * method read takes nothing returns integer28 * method write takes integer i returns nothing29 * - Data IO functions.30 *31 * method operator empty takes nothing returns boolean32 * - Determines whether the buffer is empty or not.33 *34 * method operator count takes nothing returns integer35 * - Determines the amount of data left to read.36 *37 * method clear takes nothing returns nothing38 * method reset takes nothing returns nothing39 * - Clear all data in the buffer.40 *41 * method destroy takes nothing returns nothing42 * - Destroy the buffer.43 *44 **********************************/45 library BufferEx requires optional Table
46 47 globals48 /*49 * An empty buffer will be cleaned if it has more50 * than THRESHOLD slots of unneeded data.51 * This needs to be less than 8192.52 * The smaller, the better.53 * Do not make it too small though.54 * Too Small = 10, 15, etc...55 *56 * We might as well clear the Buffer whenever possible,57 * but that would be incredibly inefficient if a user58 * is going to write, then read, then write, then read59 * every single time. A threshold will minimize the 60 * number of times we are going to clear a Buffer.61 */62 private constant integer THRESHOLD = 32
63 endglobals64
65 struct BufferEx extends array
66 private static integer array rn
67 private static integer ic = 0
68
69 static if LIBRARY_Table then
70 private static Table array data
71 else72 private static hashtable data = InitHashtable()
73 endif74
75 private static integer array readIndex
76 private static integer array writeIndex
77
78 static method create takes nothing returns thistype
79 /*80 * Allocate struct instance.81 */82 local thistype this = rn[0]
83 if this == 0 then
84 set ic = ic + 1
85 set this = ic
86 else87 set rn[0] = rn[this]
88 endif89
90 /*91 * If the table is null, we create92 * it. I'm not destroying any tables.93 * I'm only flushing them when a94 * Buffer is destroyed.95 */96 static if LIBRARY_Table then
97 if data[this] == 0 then
98 set data[this] = Table.create()
99 endif100 endif101
102 return this
103 endmethod104
105 method operator empty takes nothing returns boolean
106 return readIndex[this] == writeIndex[this]
107 endmethod108
109 method operator count takes nothing returns integer
110 return writeIndex[this] - readIndex[this]
111 endmethod112
113 method clear takes nothing returns nothing
114 /*115 * Reset the write index and the read index116 * and clear all the data in the buffer.117 */118 set writeIndex[this] = 0
119 set readIndex[this] = 0
120
121 static if LIBRARY_Table then
122 call data[this].flush()
123 else124 call FlushChildHashtable(data, this)
125 endif126 endmethod127
128 method read takes nothing returns integer
129 local integer value
130
131 /*132 * We will only read from the buffer133 * if it actually has data in it.134 */135 if not this.empty then
136 set readIndex[this] = readIndex[this] + 1
137
138 static if LIBRARY_Table then
139 set value = data[this][readIndex[this]]
140 else141 set value = LoadInteger(data, this, readIndex[this])
142 endif143
144 if this.empty and readIndex[this] >= THRESHOLD then
145 call this.clear()
146 endif147
148 return value149 debug else
150 debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "ATTEMPTED TO READ FROM EMPTY BUFFER.")
151 endif152
153 return 0
154 endmethod155
156 method write takes integer i returns nothing
157 /*158 * We write the data.159 */160 set writeIndex[this] = writeIndex[this] + 1
161
162 static if LIBRARY_Table then
163 set data[this][writeIndex[this]] = i
164 else165 call SaveInteger(data, this, writeIndex[this], i)
166 endif167 endmethod168
169 method reset takes nothing returns nothing
170 call this.clear()
171 endmethod172
173 method destroy takes nothing returns nothing
174 /*175 * Deallocate struct instance.176 */177 set rn[this] = rn[0]
178 set rn[0] = this
179
180 call this.clear()
181 endmethod182 endstruct183
184 endlibrary
Demo
1 struct Test extends array
2 3 static BufferEx myBuffer4
5 private static method printStr takes string s returns nothing
6 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, s)
7 endmethod8
9 private static method wait takes real time returns nothing
10 call TriggerSleepAction(time)
11 endmethod12
13 private static method onInit takes nothing returns nothing
14 local integer index = 0
15 local integer array data
16 local boolean failure = false
17
18 set myBuffer = BufferEx.create()
19
20 set data[0] = 100
21 set data[1] = 242
22 set data[2] = 214
23 set data[3] = 245
24 set data[4] = 935
25 set data[5] = 652
26
27 loop28 call myBuffer.write(data[index])
29 exitwhen index == 5
30 set index = index + 1
31 endloop32
33 set index = 0
34
35 loop36 if myBuffer.read() != data[index] then
37 set failure = true
38 endif39 exitwhen index == 5
40 set index = index + 1
41 endloop42
43 if not failure then
44 call printStr("Buffer Write Test 1 Successful")
45 else46 call printStr("Buffer Write Test 1 Failed")
47 return48 endif49
50 call wait(1)
51
52 call myBuffer.clear()
53 if myBuffer.empty then
54 call printStr("Buffer Clear Test 1 Successful")
55 else56 call printStr("Buffer Clear Test 1 Failed")
57 return58 endif59
60 call wait(1)
61
62 call myBuffer.write(4)
63 call myBuffer.write(5)
64 call myBuffer.write(9)
65 call myBuffer.write(7)
66
67 if myBuffer.read() == 4 then
68 if myBuffer.read() == 5 then
69 if myBuffer.read() == 9 then
70 if myBuffer.read() == 7 then
71 call printStr("Buffer Write Test 2 Successful")
72 else73 call printStr("Buffer Write Test 2 Failed")
74 endif75 else76 call printStr("Buffer Write Test 2 Failed")
77 endif78 else79 call printStr("Buffer Write Test 2 Failed")
80 endif81 else82 call printStr("Buffer Write Test 2 Failed")
83 endif84
85 call wait(1)
86
87 call myBuffer.clear()
88 if myBuffer.empty then
89 call printStr("Buffer Clear Test 2 Successful")
90 else91 call printStr("Buffer Clear Test 2 Failed")
92 endif93
94 call myBuffer.write(1)
95 call myBuffer.write(1)
96 call myBuffer.write(1)
97 call myBuffer.write(1)
98 call myBuffer.write(1)
99 call myBuffer.write(1)
100 call myBuffer.write(1)
101 call myBuffer.write(1)
102 call myBuffer.write(1)
103 call myBuffer.write(1)
104 call myBuffer.write(1)
105 call myBuffer.write(1)
106 call myBuffer.write(1)
107 call myBuffer.write(1)
108 call myBuffer.write(1)
109 call myBuffer.write(1)
110 call myBuffer.write(1)
111 call myBuffer.write(1)
112 call myBuffer.write(1)
113 call myBuffer.write(1)
114 call myBuffer.write(1)
115 call myBuffer.write(1)
116 call myBuffer.write(1)
117 call myBuffer.write(1)
118 call myBuffer.write(1)
119 call myBuffer.write(1)
120 call myBuffer.write(1)
121 call myBuffer.write(1)
122 call myBuffer.write(1)
123 call myBuffer.write(1)
124 call myBuffer.write(1)
125 call myBuffer.write(1)
126 call myBuffer.write(1)
127 call myBuffer.write(1)
128 call myBuffer.write(1)
129 call myBuffer.write(1)
130 call myBuffer.write(1)
131 call myBuffer.write(1)
132 call myBuffer.write(1)
133 call myBuffer.write(1)
134 call myBuffer.write(1)
135 call myBuffer.write(1)
136 call myBuffer.write(1)
137 call myBuffer.write(1)
138 call myBuffer.write(1)
139 call myBuffer.write(1)
140 call myBuffer.write(1)
141 call myBuffer.write(1)
142 call myBuffer.write(1)
143 call myBuffer.write(1)
144 call myBuffer.write(1)
145 call myBuffer.write(1)
146 call myBuffer.write(1)
147 call myBuffer.write(1)
148 call myBuffer.write(1)
149 call myBuffer.write(1)
150 call myBuffer.write(1)
151 call myBuffer.write(1)
152 call myBuffer.write(1)
153 call myBuffer.write(1)
154
155 call wait(1)
156
157 call myBuffer.read()
158 call myBuffer.read()
159 call myBuffer.read()
160 call myBuffer.read()
161 call myBuffer.read()
162 call myBuffer.read()
163 call myBuffer.read()
164 call myBuffer.read()
165 call myBuffer.read()
166 call myBuffer.read()
167 call myBuffer.read()
168 call myBuffer.read()
169 call myBuffer.read()
170 call myBuffer.read()
171 call myBuffer.read()
172 call myBuffer.read()
173 call myBuffer.read()
174 call myBuffer.read()
175 call myBuffer.read()
176 call myBuffer.read()
177 call myBuffer.read()
178 call myBuffer.read()
179 call myBuffer.read()
180 call myBuffer.read()
181 call myBuffer.read()
182 call myBuffer.read()
183 call myBuffer.read()
184 call myBuffer.read()
185 call myBuffer.read()
186 call myBuffer.read()
187 call myBuffer.read()
188 call myBuffer.read()
189 call myBuffer.read()
190 call myBuffer.read()
191 call myBuffer.read()
192 call myBuffer.read()
193 call myBuffer.read()
194 call myBuffer.read()
195 call myBuffer.read()
196 call myBuffer.read()
197 call myBuffer.read()
198 call myBuffer.read()
199 call myBuffer.read()
200 call myBuffer.read()
201 call myBuffer.read()
202 call myBuffer.read()
203 call myBuffer.read()
204 call myBuffer.read()
205 call myBuffer.read()
206 call myBuffer.read()
207 call myBuffer.read()
208 call myBuffer.read()
209 call myBuffer.read()
210 call myBuffer.read()
211 call myBuffer.read()
212 call myBuffer.read()
213 call myBuffer.read()
214 call myBuffer.read()
215 call myBuffer.read()
216 call myBuffer.read()
217
218 call wait(1)
219
220 if myBuffer.empty then
221 call printStr("Clear Test Successful.")
222 else223 call printStr("Clear Test Failed.")
224 endif225 endmethod226 227 endstruct
Feel free to comment.