[Snippet] BufferEx

Scripts

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

Code (jass) Select
1
/**********************************
2
*
3
*   BufferEx
4
*   v1.0.0.1
5
*   By Magtheridon96
6
*
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 Bribe
17
*           - https://wc3modding.info/4611/snippet-new-table/
18
*
19
*   API:
20
*   ----
21
*
22
*       struct BufferEx extends array
23
*
24
*           static method create takes nothing returns thistype
25
*               - Creates a new buffer.
26
*
27
*           method read takes nothing returns integer
28
*           method write takes integer i returns nothing
29
*               - Data IO functions.
30
*
31
*           method operator empty takes nothing returns boolean
32
*               - Determines whether the buffer is empty or not.
33
*
34
*           method operator count takes nothing returns integer
35
*               - Determines the amount of data left to read.
36
*
37
*           method clear takes nothing returns nothing
38
*           method reset takes nothing returns nothing
39
*               - Clear all data in the buffer.
40
*
41
*           method destroy takes nothing returns nothing
42
*               - Destroy the buffer.
43
*
44
**********************************/
45
library BufferEx requires optional Table
46
47
    globals
48
        /*
49
        *   An empty buffer will be cleaned if it has more
50
        *   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 user
58
        *   is going to write, then read, then write, then read
59
        *   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
    endglobals
64
    
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
        else
72
            private static hashtable data = InitHashtable()
73
        endif
74
        
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
            else
87
                set rn[0] = rn[this]
88
            endif
89
            
90
            /*
91
            *    If the table is null, we create
92
            *    it. I'm not destroying any tables.
93
            *    I'm only flushing them when a
94
            *    Buffer is destroyed.
95
            */
96
            static if LIBRARY_Table then
97
                if data[this] == 0 then
98
                    set data[this] = Table.create()
99
                endif
100
            endif
101
            
102
            return this
103
        endmethod
104
        
105
        method operator empty takes nothing returns boolean
106
            return readIndex[this] == writeIndex[this]
107
        endmethod
108
        
109
        method operator count takes nothing returns integer
110
            return writeIndex[this] - readIndex[this]
111
        endmethod
112
        
113
        method clear takes nothing returns nothing
114
            /*
115
            *    Reset the write index and the read index
116
            *    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
            else
124
                call FlushChildHashtable(data, this)
125
            endif
126
        endmethod
127
        
128
        method read takes nothing returns integer
129
            local integer value
130
            
131
            /*
132
            *    We will only read from the buffer
133
            *    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
                else
141
                    set value = LoadInteger(data, this, readIndex[this])
142
                endif
143
                
144
                if this.empty and readIndex[this] >= THRESHOLD then
145
                    call this.clear()
146
                endif
147
                
148
                return value
149
            debug else
150
                debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "ATTEMPTED TO READ FROM EMPTY BUFFER.")
151
            endif
152
            
153
            return 0
154
        endmethod
155
        
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
            else
165
                call SaveInteger(data, this, writeIndex[this], i)
166
            endif
167
        endmethod
168
        
169
        method reset takes nothing returns nothing
170
            call this.clear()
171
        endmethod
172
        
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
        endmethod
182
    endstruct
183
    
184
endlibrary


Demo

Code (jass) Select
1
struct Test extends array
2
3
    static BufferEx myBuffer
4
    
5
    private static method printStr takes string s returns nothing
6
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, s)
7
    endmethod
8
    
9
    private static method wait takes real time returns nothing
10
        call TriggerSleepAction(time)
11
    endmethod
12
    
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
        loop
28
            call myBuffer.write(data[index])
29
            exitwhen index == 5
30
            set index = index + 1
31
        endloop
32
        
33
        set index = 0
34
        
35
        loop
36
            if myBuffer.read() != data[index] then
37
                set failure = true
38
            endif
39
            exitwhen index == 5
40
            set index = index + 1
41
        endloop
42
        
43
        if not failure then
44
            call printStr("Buffer Write Test 1 Successful")
45
        else
46
            call printStr("Buffer Write Test 1 Failed")
47
            return
48
        endif
49
        
50
        call wait(1)
51
        
52
        call myBuffer.clear()
53
        if myBuffer.empty then
54
            call printStr("Buffer Clear Test 1 Successful")
55
        else
56
            call printStr("Buffer Clear Test 1 Failed")
57
            return
58
        endif
59
        
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
                    else
73
                        call printStr("Buffer Write Test 2 Failed")
74
                    endif
75
                else
76
                    call printStr("Buffer Write Test 2 Failed")
77
                endif
78
            else
79
                call printStr("Buffer Write Test 2 Failed")
80
            endif
81
        else
82
            call printStr("Buffer Write Test 2 Failed")
83
        endif
84
        
85
        call wait(1)
86
        
87
        call myBuffer.clear()
88
        if myBuffer.empty then
89
            call printStr("Buffer Clear Test 2 Successful")
90
        else
91
            call printStr("Buffer Clear Test 2 Failed")
92
        endif
93
        
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
        else
223
            call printStr("Clear Test Failed.")
224
        endif
225
    endmethod
226
227
endstruct


Feel free to comment.
14 years
I like the code and the style. Approved