- Joined
- Apr 30, 2011
- Messages
- 359
JASS:
//========================================================================================
//
// [ HyperArray ] v2.0.0.0
// -*- overcold_ice -*-
//
// One hashtable for a map, one HyperArray for a library/scope
//----------------------------------------------------------------------------------------
//
// -[*] Features:
// - Simple operators
// - Extremely optimizes the use of a hashtable
// - Auto resizing array size and dimension length
// - Automatically indexes entered keys
// - Supports up to 8192 dimensions (hell!)
// - Supports up to 2147483648 storage spaces
//----------------------------------------------------------------------------------------
//
// -[*] Configurables:
/*
private constant integer BASE_DIMENSION_NUMBER //= base number for dimension length
private constant integer BASE_ARRAY_NUMBER //= base number for array size
private constant integer INITIAL_DIMENSION_LENGTH //= initial exponent for dimension length
private constant integer INITIAL_ARRAY_SIZE //= initial exponent for array size
*/ //= initial dimension/array size = base ^ exp
// if the dimension/array size overlimits, the current maximum size will be
// multiplied by its base
//----------------------------------------------------------------------------------------
//
// -[*] API:
/*
struct HyperArray extends array
static method create takes nothing returns thistype
method destroy takes nothing returns nothing
*/ //= allocator/deallocator for the struct
// has initial dimension length and initial array size
/*
method operator [] takes integer key returns thistype
*/ //= increases index, multiple increasing is possible
/*
method getIndex takes nothing returns integer
method setIndex takes integer index returns thistype
*/ //= gets/sets index
/*
method operator maxDimension takes nothing returns integer
*/ //= returns maximum dimension length of the array
/*
method getSize takes integer dimension returns integer
*/ //= gets the maximum size in dimension
/*
method operator usedSize takes nothing returns integer
method operator maxSize takes nothing returns integer
*/ //= returns used size or max size of the array
/*
method iterateStart takes nothing returns nothing
method iterateReverseStart takes nothing returns nothing
*/ //= sets iterator to the start/end of the array
/*
method iterateNext takes nothing returns nothing
method iteratePrev takes nothing returns nothing
*/ //= sets iterator to the next/previous index of the array
/*
method iterateIsFirst takes nothing returns boolean
method iterateIsLast takes nothing returns boolean
*/ //= returns whether iterator is at the start/end of the array
/*
method iterateEnd takes nothing returns boolean
method iterateReverseEnd takes nothing returns boolean
*/ //= returns whether iterator is outside of the end/start of the array
/*
method operator iteratorPos takes nothing returns integer
*/ //= returns current iterator position
/*
method operator iterateIndex takes nothing returns integer
*/ //= returns current iteration index
/*
method operator <type> takes nothing returns <type>
method operator <type>= takes <type> value returns nothing
*/ //= saves/loads a value of type <type> at current internal key number
/*
method operator have.<type> takes nothing returns boolean
*/ //= returns whether the value of type <type> is already assigned at
// current internal key number
// <type> can only be the base types
/*
method remove.<type> takes nothing returns nothing
*/ //= removes the value of type <type> at current internal key number
// <type> can only be the base types
/*
method copy takes integer index returns nothing
*/ //= copies the values of another index to this index
/*
method copyTo takes integer index returns nothing
*/ //= copies the values from this index to another index
/*
method swap takes integer index returns nothing
*/ //= swap the values between this index and index
/*
method flush takes nothing returns nothing
*/ //= removes all already assigned values of any types in the instance
// keeps current dimension length and array size
//----------------------------------------------------------------------------------------
//
// -[*] Notes:
// - [] operators resets the index to 0 at its first application, additional
// application won't reset the index
// - Iterating doesn't automatically updates the index of the array, so you
// must use setIndex with iteratorPos or iteratorIndex as its argument
// - iteratorPos is faster compared to iteratorIndex, the main difference is
// that iteratorIndex returns the array index of iteratorPos, while
// iteratorPos returns an internal index of the array
// - copy, copyTo, and swap can only takes array indexes, not internal ones
//----------------------------------------------------------------------------------------
//
// -[*] Examples:
/*
local HyperArray ha = HyperArray.create()
local integer index
set ha [1] [999] [888] [777].boolean = true
set ha.string = "1999888777"
if ha [1] [999] [888] [777] then
if ha.have.string and ha [1] [999] [888] [777].have.boolean then
call ha.remove.string()
call ha [1] [999] [888] [777].remove.boolean()
endif
endif
set ha.integer = 123
set ha [123].integer = 345
set ha [345].integer = 456
set ha [456].integer = 789
set index = ha [123].getIndex()
set ha.setIndex(index).string = "aeiou"
call ha.integer.copy(index)
set index = ha [345].getIndex()
call ha.integer.copyTo(index)
set index = ha [456].getIndex()
call ha.integer.swap(index)
call ha.iterateStart()
loop
exitwhen ha.iterateEnd()
set index = ha.iteratePos
set ha.setIndex(index).boolean = false
if ha.iterateIsLast() then
set ha.setIndex(index).boolean = true
endif
call ha.iterateNext()
endloop
call ha.flush()
if not ha.have.integer then
call ha.destroy()
endif
*/
//----------------------------------------------------------------------------------------
//========================================================================================
library HyperArray
//========================================================================================
// Configurables
//----------------------------------------------------------------------------------------
globals
private constant integer BASE_DIMENSION_NUMBER = 2
private constant integer BASE_ARRAY_NUMBER = 4
private constant integer INITIAL_DIMENSION_LENGTH = 1
private constant integer INITIAL_ARRAY_SIZE = 5
endglobals
//========================================================================================
globals
private hashtable ht = InitHashtable()
private integer idl = R2I(Pow(BASE_DIMENSION_NUMBER, INITIAL_DIMENSION_LENGTH))
private integer ias = R2I(Pow(BASE_ARRAY_NUMBER, INITIAL_ARRAY_SIZE))
private integer cd = 0
private integer id = 0
private integer it
private integer sdl
private integer array sas
private integer array asf
endglobals
private struct Have extends array
//! textmacro HyperArray___MakeHave takes TYPE, FUNC
method operator $TYPE$ takes nothing returns boolean
return HaveSaved$FUNC$(ht, this, id)
endmethod
//! endtextmacro
//! runtextmacro HyperArray___MakeHave("boolean", "Boolean")
//! runtextmacro HyperArray___MakeHave("integer", "Integer")
//! runtextmacro HyperArray___MakeHave("real", "Real")
//! runtextmacro HyperArray___MakeHave("string", "String")
//! runtextmacro HyperArray___MakeHave("handle", "Handle")
endstruct
private struct Remove extends array
//! textmacro HyperArray___MakeRemove takes TYPE, FUNC
method $TYPE$ takes nothing returns nothing
call RemoveSaved$FUNC$(ht, this, id)
endmethod
//! endtextmacro
//! runtextmacro HyperArray___MakeRemove("boolean", "Boolean")
//! runtextmacro HyperArray___MakeRemove("integer", "Integer")
//! runtextmacro HyperArray___MakeRemove("real", "Real")
//! runtextmacro HyperArray___MakeRemove("string", "String")
//! runtextmacro HyperArray___MakeRemove("handle", "Handle")
endstruct
struct HyperArray extends array
private static integer c = 0
private thistype r
private integer dl
private integer pc
private static boolean ns
private method getId takes integer d, integer i returns integer
local integer iid
if HaveSavedInteger(ht, -this * 8192 + d, i) then
return LoadInteger(ht, -this * 8192 + d, i)
endif
set iid = LoadInteger(ht, this + 16384, d) + 1
call SaveInteger(ht, this + 16384, d, iid)
call SaveInteger(ht, -this * 8192 + d, i, iid)
return iid
endmethod
private method getStorage takes integer d returns integer
local integer s = 1
loop
exitwhen d == 0
set s = s * LoadInteger(ht, this + 8192, d)
set d = d - 1
endloop
return s
endmethod
static method create takes nothing returns thistype
local thistype this = thistype(0).r
local integer d = 0
if this == 0 then
set c = c + 1
set this = c
else
set thistype(0).r = this.r
endif
set this.dl = idl
set this.pc = 0
call SaveInteger(ht, this + 24576, 0, 1)
loop
exitwhen d == this.dl
set d = d + 1
call SaveInteger(ht, this + 8192, d, ias)
call SaveInteger(ht, this + 16384, d, 0)
call SaveInteger(ht, this + 24576, d, R2I(Pow(ias, d)))
endloop
return this
endmethod
method flush takes nothing returns nothing
call FlushChildHashtable(ht, this)
set this.pc = 0
endmethod
method destroy takes nothing returns nothing
local integer d = 0
set this.r = thistype(0).r
set thistype(0).r = this.r
call FlushChildHashtable(ht, this)
call FlushChildHashtable(ht, this + 8192)
call FlushChildHashtable(ht, this + 16384)
call FlushChildHashtable(ht, this + 24576)
loop
exitwhen d == this.dl
set d = d + 1
call FlushChildHashtable(ht, -this * 8192 + d)
endloop
set this.dl = 0
set this.pc = 0
endmethod
method operator [] takes integer i returns thistype
local integer iid
local integer d = 0
set cd = cd + 1
if cd == 1 then
set id = 0
set sdl = this.dl
set ns = false
loop
exitwhen d == sdl
set d = d + 1
set sas [d] = LoadInteger(ht, this + 8192, d)
set asf [d] = LoadInteger(ht, this + 24576, d)
endloop
endif
if cd > this.dl then
set this.dl = this.dl * BASE_DIMENSION_NUMBER
set d = cd
loop
call SaveInteger(ht, this + 8192, d, ias)
call SaveInteger(ht, this + 16384, d, 0)
call SaveInteger(ht, this + 24576, d, this.getStorage(d))
exitwhen d == this.dl
set d = d + 1
endloop
endif
set iid = this.getId(cd, i)
if iid > sas [cd] then
call SaveInteger(ht, this + 8192, cd, sas [cd] * BASE_ARRAY_NUMBER)
set d = cd
loop
call SaveInteger(ht, this + 24576, d, this.getStorage(d))
exitwhen d == this.dl
set d = d + 1
endloop
endif
set asf [cd] = LoadInteger(ht, this + 24576, cd) - asf [cd]
set id = id + iid * LoadInteger(ht, this + 24576, cd - 1)
return this
endmethod
private method shift takes nothing returns integer
local integer array i
local integer k = sas [1]
local integer d = sdl
local integer l
local integer s
if ns then
return 0
endif
loop
exitwhen d == 0
if sas [d] != LoadInteger(ht, this + 8192, d) then
return 0
endif
set d = d - 1
endloop
set d = 2
set i [1] = 0
set i [2] = 1
loop
set k = k + 1
set i [1] = i [1] + 1
set l = 0
loop
exitwhen l == d
set l = l + 1
if i [l] > sas [l] then
set i [l] = 1
set i [l + 1] = i [l + 1] + 1
endif
endloop
if i [d + 1] == 1 then
set d = d + 1
exitwhen d > sdl
endif
if HaveSavedInteger(ht, this, k) then
set s = 0
set l = 0
loop
exitwhen l == d
set l = l + 1
set s = s + asf [l - 1] * i [l]
endloop
call SaveInteger(ht, this, k + s, LoadInteger(ht, this, k))
call SaveInteger(ht, this + 32768, LoadInteger(ht, this, k), k + s)
call RemoveSavedInteger(ht, this, k)
endif
endloop
return 0
endmethod
private method point takes nothing returns integer
if id > -1 then
if not HaveSavedInteger(ht, this, id) then
set this.pc = this.pc + 1
call SaveInteger(ht, this, id, -this.pc)
call SaveInteger(ht, this + 32768, -this.pc, id)
endif
set id = LoadInteger(ht, this, id)
endif
// reset
set cd = 0
set ns = true
return 0
endmethod
method getIndex takes nothing returns integer
return id
endmethod
method setIndex takes integer i returns thistype
set id = i
return this
endmethod
method operator maxDimension takes nothing returns integer
return this.dl
endmethod
method getSize takes integer d returns integer
return LoadInteger(ht, this + 24576, d)
endmethod
method operator usedSize takes nothing returns integer
return this.pc
endmethod
method operator maxSize takes nothing returns integer
return this.getSize(this.dl)
endmethod
method iterateStart takes nothing returns nothing
set it = -1
endmethod
method iterateReverseStart takes nothing returns nothing
set it = -this.pc
endmethod
method iterateNext takes nothing returns nothing
set it = it - 1
endmethod
method iteratePrev takes nothing returns nothing
set it = it + 1
endmethod
method iterateIsFirst takes nothing returns boolean
return it == -1
endmethod
method iterateIsLast takes nothing returns boolean
return it == -this.pc
endmethod
method iterateEnd takes nothing returns boolean
return it < -this.pc
endmethod
method iterateReverseEnd takes nothing returns boolean
return it >= 0
endmethod
method operator iteratorPos takes nothing returns integer
return it
endmethod
method operator iterateIndex takes nothing returns integer
return LoadInteger(ht, this + 32768, it)
endmethod
//! textmacro HyperArray___MakeStorage takes TYPE, FUNC
method operator $TYPE$ takes nothing returns $TYPE$
call this.shift()
call this.point()
return Load$FUNC$(ht, this, id)
endmethod
method operator $TYPE$= takes $TYPE$ v returns nothing
call this.shift()
call this.point()
call Save$FUNC$(ht, this, id, v)
endmethod
//! endtextmacro
//! runtextmacro HyperArray___MakeStorage("boolean", "Boolean")
//! runtextmacro HyperArray___MakeStorage("integer", "Integer")
//! runtextmacro HyperArray___MakeStorage("real", "Real")
//! runtextmacro HyperArray___MakeStorage("string", "Str")
//! runtextmacro HyperArray___MakeStorage("ability", "AbilityHandle")
//! runtextmacro HyperArray___MakeStorage("boolexpr", "BooleanExprHandle")
//! runtextmacro HyperArray___MakeStorage("button", "ButtonHandle")
//! runtextmacro HyperArray___MakeStorage("defeatcondition", "DefeatConditionHandle")
//! runtextmacro HyperArray___MakeStorage("destructable", "DestructableHandle")
//! runtextmacro HyperArray___MakeStorage("dialog", "DialogHandle")
//! runtextmacro HyperArray___MakeStorage("effect", "EffectHandle")
//! runtextmacro HyperArray___MakeStorage("event", "TriggerEventHandle")
//! runtextmacro HyperArray___MakeStorage("fogmodifier", "FogModifierHandle")
//! runtextmacro HyperArray___MakeStorage("fogstate", "FogStateHandle")
//! runtextmacro HyperArray___MakeStorage("force", "ForceHandle")
//! runtextmacro HyperArray___MakeStorage("group", "GroupHandle")
//! runtextmacro HyperArray___MakeStorage("hashtable", "HashtableHandle")
//! runtextmacro HyperArray___MakeStorage("image", "ImageHandle")
//! runtextmacro HyperArray___MakeStorage("item", "ItemHandle")
//! runtextmacro HyperArray___MakeStorage("itempool", "ItemPoolHandle")
//! runtextmacro HyperArray___MakeStorage("leaderboard", "LeaderboardHandle")
//! runtextmacro HyperArray___MakeStorage("lightning", "LightningHandle")
//! runtextmacro HyperArray___MakeStorage("location", "LocationHandle")
//! runtextmacro HyperArray___MakeStorage("multiboard", "MultiboardHandle")
//! runtextmacro HyperArray___MakeStorage("multiboarditem", "MultiboardItemHandle")
//! runtextmacro HyperArray___MakeStorage("player", "PlayerHandle")
//! runtextmacro HyperArray___MakeStorage("quest", "QuestHandle")
//! runtextmacro HyperArray___MakeStorage("questitem", "QuestItemHandle")
//! runtextmacro HyperArray___MakeStorage("rect", "RectHandle")
//! runtextmacro HyperArray___MakeStorage("region", "RegionHandle")
//! runtextmacro HyperArray___MakeStorage("sound", "SoundHandle")
//! runtextmacro HyperArray___MakeStorage("texttag", "TextTagHandle")
//! runtextmacro HyperArray___MakeStorage("timer", "TimerHandle")
//! runtextmacro HyperArray___MakeStorage("timerdialog", "TimerDialogHandle")
//! runtextmacro HyperArray___MakeStorage("trackable", "TrackableHandle")
//! runtextmacro HyperArray___MakeStorage("trigger", "TriggerHandle")
//! runtextmacro HyperArray___MakeStorage("triggercondition", "TriggerConditionHandle")
//! runtextmacro HyperArray___MakeStorage("triggeraction", "TriggerActionHandle")
//! runtextmacro HyperArray___MakeStorage("ubersplat", "UbersplatHandle")
//! runtextmacro HyperArray___MakeStorage("unit", "UnitHandle")
//! runtextmacro HyperArray___MakeStorage("unitpool", "UnitPoolHandle")
//! runtextmacro HyperArray___MakeStorage("widget", "WidgetHandle")
method operator have takes nothing returns Have
return this.shift() + this.point() + this
endmethod
method operator remove takes nothing returns Remove
return this.shift() + this.point() + this
endmethod
method copy takes integer i returns nothing
call SaveInteger(ht, this, id, LoadInteger(ht, this, i))
endmethod
method copyTo takes integer i returns nothing
call SaveInteger(ht, this, i, LoadInteger(ht, this, id))
endmethod
method swap takes integer i returns nothing
local integer cp = LoadInteger(ht, this, id)
call SaveInteger(ht, this, id, LoadInteger(ht, this, i))
call SaveInteger(ht, this, i , cp)
endmethod
endstruct
endlibrary
Last edited: