SerraAvenger
Cuz I can
- Reaction score
- 234
What's this?
Implementations for two real basic datastructures, the ringbuffer (fifo) and the stack (lifo)
Needs?
JassPack NewGen (or just the JassHelper parser)
How to import?
Just copy and paste this into a Custom Script section.
How to use?
There are two textmacros, Stack and RingBuffer that both take the four arguments VISIBILITY, NAME, TYPE and SIZE.
For linked implementations, use LinkedStack and LinkedRingBuffer, respectively. Note that they have "unlimited" size per instance, which is why the SIZE parameter is ommitted.
RingBuffer methods:
When you're trying to read from an empty structure / write into a full structure, it will return the "null" type (0 for ints, 0.0 for reals, null for handles). In debug mode, the Normal version will also spit out an error message.
Here's an example:
The Code
Implementations for two real basic datastructures, the ringbuffer (fifo) and the stack (lifo)
Needs?
JassPack NewGen (or just the JassHelper parser)
How to import?
Just copy and paste this into a Custom Script section.
How to use?
There are two textmacros, Stack and RingBuffer that both take the four arguments VISIBILITY, NAME, TYPE and SIZE.
For linked implementations, use LinkedStack and LinkedRingBuffer, respectively. Note that they have "unlimited" size per instance, which is why the SIZE parameter is ommitted.
- VISIBILITY - The "visibility" of the structure outside of the scope you're currently in. Possible arguments: "public" (needs the scope prefix to use); "private" (only useable within the scope)
- NAME - The name of the default structure and the structure's name (string)
- TYPE - What needs to be saved in the structure (type)
- SIZE - How much data can be saved in the structure (integer)
- NAME_struct.create() -> NAME_struct
- push( TYPE ) -> nothing
- pop() -> TYPE
Returns and removes the last pushed value - get() -> TYPE
Returns the last pushed value, but doesn't remove it - used -> integer
The number of entries in the structrure.
RingBuffer methods:
- NAME_struct.create() -> NAME_struct
- write( TYPE ) -> nothing
- read() -> TYPE
Returns and removes the last written value - get() -> TYPE
Returns the last written value, but doesn't remove it - used -> integer
The number of entries in the structrure.
When you're trying to read from an empty structure / write into a full structure, it will return the "null" type (0 for ints, 0.0 for reals, null for handles). In debug mode, the Normal version will also spit out an error message.
Here's an example:
JASS:
scope TestLinked initializer INIT
//! runtextmacro LinkedStack( "private", "ExampleStack", "integer" )
//! runtextmacro LinkedRingBuffer( "private", "ExampleRingbuffer", "integer" )
private function INIT takes nothing returns nothing
local ExampleStack_struct test2 // NAME_struct
local integer i = 0
set test2 = ExampleStack_struct.create() // creates a new ExampleStack instance.
loop
exitwhen i == 10
call ExampleStack.push( i ) // pushes i into the default stack
call test2.push( ExampleStack.pop() ) // gets and removes the last value of the default stack, then pushes it into the test2 stack
call ExampleRingbuffer.write( i + 4 ) // writes i+4 into the default ringbuffer
set i = i + 1
endloop
call test2.pop() // simply removes the last value out of the stack
call BJDebugMsg( "Linked: " + I2S( test2.get() ) + " + " + I2S( ExampleRingbuffer.get() ) + " = " + I2S( test2.get() + ExampleRingbuffer.get() ) )
// get() doesn't remove the values.
endfunction
endscope
scope TestNonlinked initializer INIT
//! runtextmacro Stack( "private", "ExampleStack", "integer", "10" )
//! runtextmacro RingBuffer( "private", "ExampleRingbuffer", "integer","10" )
private function INIT takes nothing returns nothing
local ExampleStack_struct test2 // NAME_struct
local integer i = 0
set test2 = ExampleStack_struct.create() // creates a new ExampleStack instance.
loop
exitwhen i == 10
call ExampleStack.push( i ) // pushes i into the default stack
call test2.push( ExampleStack.pop() ) // gets and removes the last value of the default stack, then pushes it into the test2 stack
call ExampleRingbuffer.write( i + 4 ) // writes i+4 into the default ringbuffer
set i = i + 1
endloop
call test2.pop() // simply removes the last value out of the stack
call BJDebugMsg( "Nonlinked: " + I2S( test2.get() ) + " + " + I2S( ExampleRingbuffer.get() ) + " = " + I2S( test2.get() + ExampleRingbuffer.get() ) )
// get() doesn't remove the values.
endfunction
endscope
The Code
JASS:
// Array implementations
//! textmacro Stack takes VISIBILITY, NAME, TYPE, SIZE
$VISIBILITY$ keyword $NAME$_struct
globals
$VISIBILITY$ $NAME$_struct $NAME$
endglobals
$VISIBILITY$ struct $NAME$_struct
private $TYPE$ array data[ $SIZE$ ]
static constant integer size = $SIZE$
readonly integer used = 0
method get takes nothing returns $TYPE$
return .data[ .used ]
endmethod
method push takes $TYPE$ value returns nothing
set .used = .used + 1
set .data[ .used ] = value
set value = .data[ 0 ]
endmethod
method pop takes nothing returns $TYPE$
if .used > 0 then
set .used = .used - 1
return .data[ .used + 1 ]
endif
return .data[ 0 ]
endmethod
static method onInit takes nothing returns nothing
set $NAME$ = thistype.create()
endmethod
endstruct
//! endtextmacro
//! textmacro RingBuffer takes VISIBILITY, NAME, TYPE, SIZE
$VISIBILITY$ keyword $NAME$_struct
globals
$VISIBILITY$ $NAME$_struct $NAME$
endglobals
$VISIBILITY$ struct $NAME$_struct
private $TYPE$ array data[ $SIZE$ ]
static constant integer size = $SIZE$
readonly integer readIndex = 1
readonly integer writeIndex = 1
private boolean mayRead = true
private boolean mayWrite = true
method get takes nothing returns $TYPE$
return .data[ .readIndex ]
endmethod
method write takes $TYPE$ value returns nothing
if .writeIndex != .readIndex or .mayWrite then
set .data[ .writeIndex ] = value
if .writeIndex == $SIZE$ then
set .writeIndex = 1
else
set .writeIndex = .writeIndex + 1
endif
set .mayRead = .writeIndex == .readIndex
set .mayWrite = false
else
debug call BJDebugMsg( "$NAME$ #"+I2S( this )+": Insufficient ring size!" )
endif
set value = .data[ 0 ]
endmethod
method read takes nothing returns $TYPE$
local $TYPE$ value = .data[ 0 ]
if .readIndex != .writeIndex or .mayRead then
set value = .data[ .readIndex ]
if .readIndex == $SIZE$ then
set .readIndex = 1
else
set .readIndex = .readIndex + 1
endif
set .mayWrite = .writeIndex == .readIndex
set .mayRead = false
else
debug call BJDebugMsg( "$NAME$ #"+I2S( this )+": Trying to access empty field 039;" +I2S( .readIndex ) + "039;!" )
endif
return value
endmethod
static method onInit takes nothing returns nothing
set $NAME$ = $NAME$_struct.create()
endmethod
endstruct
//! endtextmacro
//Linked Implementations
//! textmacro LinkedStack takes VISIBILITY, NAME, TYPE
$VISIBILITY$ keyword $NAME$_struct
globals
$VISIBILITY$ $NAME$_struct $NAME$
endglobals
private struct $NAME$_struct_chain
thistype last = 0
$TYPE$ value
integer used = 0
method operator nextChain= takes $TYPE$ value returns thistype
local thistype new = .allocate()
set new.last = this
set new.value = value
set new.used = .used + 1
return new
endmethod
method get takes nothing returns $TYPE$
return .value
endmethod
method getNextChain takes nothing returns thistype
call .destroy()
return .last
endmethod
endstruct
$VISIBILITY$ struct $NAME$_struct
readonly delegate $NAME$_struct_chain chain
static method onInit takes nothing returns nothing
set $NAME$ = thistype.create()
endmethod
static method create takes nothing returns thistype
local thistype new = .allocate()
set new.chain = 0
return new
endmethod
method push takes $TYPE$ value returns nothing
set .chain.nextChain = value
endmethod
method pop takes nothing returns $TYPE$
local $TYPE$ val = .get()
if .chain != 0 then
set .chain = .chain.getNextChain()
endif
return val
endmethod
endstruct
//! endtextmacro
//! textmacro LinkedRingBuffer takes VISIBILITY, NAME, TYPE
$VISIBILITY$ keyword $NAME$_struct
globals
$VISIBILITY$ $NAME$_struct $NAME$
endglobals
private struct $NAME$_struct_chain
thistype next = 0
$TYPE$ value
method get takes nothing returns $TYPE$
return .value
endmethod
method operator nextChain= takes $TYPE$ value returns thistype
local thistype new = .allocate()
set .next = new
set new.value = value
return new
endmethod
method getNextChain takes nothing returns thistype
call .destroy()
return .next
endmethod
endstruct
$VISIBILITY$ struct $NAME$_struct
readonly delegate $NAME$_struct_chain chainRead
readonly $NAME$_struct_chain chainWrite
integer used = 0
method write takes $TYPE$ value returns nothing
set .chainWrite.nextChain = value
set .used = .used + 1
if .chainRead == 0 then
set .chainRead = .chainWrite
endif
endmethod
method read takes nothing returns $TYPE$
local $TYPE$ value = .get()
set .chainRead = .chainRead.getNextChain()
set .used = .used - 1
return value
endmethod
static method onInit takes nothing returns nothing
set $NAME$ = $NAME$_struct.create()
endmethod
endstruct
//! endtextmacro