/**********************************
*
* BufferEx
* v1.0.0.1
* By Magtheridon96
*
* - Data structure resource.
* This buffer is a FIFO (First in,
* First out) data structure.
* What you write first is read
* first.
*
* Optional Requirement:
* ---------------------
*
* - Table by Bribe
* - https://wc3modding.info/4611/snippet-new-table/
*
* API:
* ----
*
* struct BufferEx extends array
*
* static method create takes nothing returns thistype
* - Creates a new buffer.
*
* method read takes nothing returns integer
* method write takes integer i returns nothing
* - Data IO functions.
*
* method operator empty takes nothing returns boolean
* - Determines whether the buffer is empty or not.
*
* method operator count takes nothing returns integer
* - Determines the amount of data left to read.
*
* method clear takes nothing returns nothing
* method reset takes nothing returns nothing
* - Clear all data in the buffer.
*
* method destroy takes nothing returns nothing
* - Destroy the buffer.
*
**********************************/
library BufferEx requires optional Table
globals
/*
* An empty buffer will be cleaned if it has more
* than THRESHOLD slots of unneeded data.
* This needs to be less than 8192.
* The smaller, the better.
* Do not make it too small though.
* Too Small = 10, 15, etc...
*
* We might as well clear the Buffer whenever possible,
* but that would be incredibly inefficient if a user
* is going to write, then read, then write, then read
* every single time. A threshold will minimize the
* number of times we are going to clear a Buffer.
*/
private constant integer THRESHOLD = 32
endglobals
struct BufferEx extends array
static if LIBRARY_Table then
private static Table array data
else
endif
private static integer array readIndex
private static integer array writeIndex
static method create takes nothing returns thistype
/*
* Allocate struct instance.
*/
local thistype this = rn[0]
if this == 0 then
set ic = ic + 1
set this = ic
else
set rn[0] = rn[this]
endif
/*
* If the table is null, we create
* it. I'm not destroying any tables.
* I'm only flushing them when a
* Buffer is destroyed.
*/
static if LIBRARY_Table then
if data[this] == 0 then
set data[this] = Table.create()
endif
endif
return this
endmethod
method operator empty
takes nothing returns boolean return readIndex[this] == writeIndex[this]
endmethod
method operator count
takes nothing returns integer return writeIndex[this] - readIndex[this]
endmethod
method clear takes nothing returns nothing
/*
* Reset the write index and the read index
* and clear all the data in the buffer.
*/
set writeIndex[this] = 0
set readIndex[this] = 0
static if LIBRARY_Table then
call data[this].flush()
else
endif
endmethod
method read takes nothing returns integer
/*
* We will only read from the buffer
* if it actually has data in it.
*/
if not this.empty then
set readIndex[this] = readIndex[this] + 1
static if LIBRARY_Table then
set value = data[this][readIndex[this]]
else
endif
if this.empty and readIndex[this] >= THRESHOLD then
call this.clear()
endif
return value
debug else
endif
return 0
endmethod
method write
takes integer i
returns nothing /*
* We write the data.
*/
set writeIndex[this] = writeIndex[this] + 1
static if LIBRARY_Table then
set data[this][writeIndex[this]] = i
else
endif
endmethod
method reset takes nothing returns nothing
call this.clear()
endmethod
method destroy takes nothing returns nothing
/*
* Deallocate struct instance.
*/
set rn[this] = rn[0]
set rn[0] = this
call this.clear()
endmethod
endstruct
endlibrary