- Joined
- Apr 30, 2011
- Messages
- 359
JASS:
//========================================================================================
//
// Hyper Array
// -*- overcold_ice -*-
//
// -[*] Requirements:
// - JNGP
// - latest version of JassHelper
//
// Provides storages with extremely dynamic array
// Uses a hashtable, converting arrays into a key for it, then storing values
// within
//
// -[*] Features:
// - Limitations:
// - 8192 HyperArray instance
// - 2147483647 total dimension
// - 2147483647 storage per instance
//
// - Supports instances with extreme dimension amount (ex: 10D, 99D)
// - Supports up to 2147483647 storage limit per HyperArray instance
// for each variable types
// - Values inserted to HyperArray instances' arrays can be any value
// (they'll be converted to indexes for the system)
// - Adjustable default array size (default array size is inserted to any
// 'null' arrays during .create operator)
//
// -[*] API:
//
// struct HyperArray extends array
// static method operator [] takes integer Dimension returns 'childtype'
// -> method operator [] takes integer DimensionSize returns 'thistype'
// -> method operator create takes nothing returns HyperArray
// allocator for the struct
//
// method destroy takes nothing returns nothing
// deallocator for the struct
//
// method operator [] takes integer Key returns 'childtype'
// -> method operator [] takes integer Key returns 'thistype'
// -> method operator $TYPE$= takes $TYPE$ Value returns nothing
// -> method operator $TYPE$ takes nothing returns $TYPE$
// storage operators
// $TYPE$ == type of variable to store
// (see textmacros below)
//
// -[*] Examples:
/*
// . . .
local HyperArray HA1 = HyperArray [2] [100] [100] // 2D, storage 100 and 100
// Total -> 10000
local HyperArray HA2 = HyperArray [5].create // 5D, all of them has
// Default Storage (configurable)
set HA1 [50] [50].integer = 100
set HA1 [50] [50].unit = GetTriggerUnit() // works
set HA2 [Pow(2, 5)] [Pow(2, 10)] [Pow(2, 15)] [Pow(2, 20)] [Pow(2, 25)].boolean = true
set HA2 [HA1 [50] [50].integer] [0] [0] [0] [HA1 [50] [50].integer].integer /*
*/ = HA1 [50] [50].integer
call HA2.destroy()
// . . .
*/
//========================================================================================
library HyperArray
//====================================================================================
// C A L I B R A T I O N S E C T I O N
//====================================================================================
globals
private constant integer DEFAULT_ARRAY_SIZE = 8192
endglobals
//====================================================================================
globals
private hashtable Hashtable = InitHashtable()
// Hashtable's keys
private constant integer DimensionSize = 0
private constant integer IdCount = 8192
private constant integer ValueStorage = 16384
// Struct's values
private integer array StructId
private integer array MaxDimension
// Temp variables
private integer CurrentDimension
private integer CurrentKey
// Used for StructId's usage
private integer StructId_Count = -1
private integer array StructId_Recycle
private integer array StructId_Dimension
endglobals
private function GetArrayCount takes integer this, integer d returns integer
//arg integer d // dimension number
local integer l = MaxDimension [this] // used in loop
local integer a = 1 // number of arrays
loop
exitwhen l == d
set a = a * LoadInteger(Hashtable, DimensionSize + this, l)
set l = l - 1
endloop
return a
endfunction
private function RegId takes integer this returns nothing
local integer sid = StructId_Recycle [0] // struct id
if sid == 0 and StructId_Dimension [sid] != MaxDimension [this] then
set StructId_Count = StructId_Count - MaxDimension [this]
set sid = StructId_Count
set StructId_Dimension [sid] = MaxDimension [this]
else
set StructId_Recycle [0] = StructId_Recycle [sid]
endif
set StructId [this] = sid
endfunction
private function UnregId takes integer this returns nothing
local integer sid = StructId [this] // struct id
set StructId_Recycle [sid] = StructId_Recycle [0]
set StructId_Recycle [0] = sid
endfunction
private function GetArrayId takes integer this, integer d, integer a returns integer
//arg integer d // what dimension
//arg integer a // what array/key
if HaveSavedInteger(Hashtable, StructId [this] + d, a) then
return LoadInteger(Hashtable, StructId [this] + d, a)
endif
call SaveInteger(Hashtable, IdCount + this, d, LoadInteger(Hashtable, IdCount + this, d) + 1)
call SaveInteger(Hashtable, StructId [this] + d, a, LoadInteger(Hashtable, IdCount + this, d))
return LoadInteger(Hashtable, StructId [this] + d, a)
endfunction
private struct CreateArray extends array
method operator [] takes integer s returns thistype
//arg integer s // this dimension maximum size
set CurrentDimension = CurrentDimension + 1
if CurrentDimension > MaxDimension [this] then
return this
endif
call SaveInteger(Hashtable, DimensionSize + this, CurrentDimension, s)
return this
endmethod
method operator create takes nothing returns HyperArray
loop
exitwhen CurrentDimension == MaxDimension [this]
set CurrentDimension = CurrentDimension + 1
if not HaveSavedInteger(Hashtable, DimensionSize + this, CurrentDimension) then
call SaveInteger(Hashtable, DimensionSize + this, CurrentDimension, DEFAULT_ARRAY_SIZE)
endif
endloop
return this
endmethod
endstruct
private struct GetArray extends array
method operator [] takes integer k returns thistype
//arg integer k // what key
//loc integer aid // k's id
//loc integer sds // this' dimension size
local integer aid = GetArrayId(this, CurrentDimension + 1, k)
local integer sds = LoadInteger(Hashtable, DimensionSize + this, CurrentDimension + 1)
if aid > sds then
return this
endif
set CurrentDimension = CurrentDimension + 1
if CurrentDimension > MaxDimension [this] then
return this
elseif CurrentDimension == MaxDimension [this] then
set CurrentKey = CurrentKey + aid
else
set CurrentKey = CurrentKey + (aid - 1) * GetArrayCount(this, CurrentDimension)
endif
return this
endmethod
//! textmacro HyperArray___MakeStorage takes TYPE, FUNC
method operator $TYPE$ takes nothing returns $TYPE$
return Load$FUNC$(Hashtable, ValueStorage + this, CurrentKey)
endmethod
method operator $TYPE$= takes $TYPE$ v returns nothing
//arg $TYPE$ v // value to store
call Save$FUNC$(Hashtable, ValueStorage + this, CurrentKey, 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")
endstruct
struct HyperArray extends array
private static integer Count
private thistype Recycle
static method [] takes integer d returns CreateArray
//arg integer d // this' max dimension size
local thistype this = thistype(0).Recycle
if this == 0 then
set .Count = .Count + 1
set this = .Count
else
set thistype(0).Recycle = this.Recycle
endif
set MaxDimension [this] = d
set CurrentDimension = 0
return this
endmethod
method destroy takes nothing returns nothing
set this.Recycle = thistype(0).Recycle
set thistype(0).Recycle = this
set StructId [this] = 0
set MaxDimension [this] = 0
call FlushChildHashtable(Hashtable, DimensionSize + this)
call FlushChildHashtable(Hashtable, IdCount + this)
call FlushChildHashtable(Hashtable, ValueStorage + this)
endmethod
method operator [] takes integer k returns GetArray
//arg integer k // what key
//loc integer aid // k's id
//loc integer sds // this' dimension size
local integer aid = GetArrayId(this, 1, k)
local integer sds = LoadInteger(Hashtable, DimensionSize + this, 1)
if aid > sds then
return this
endif
set CurrentDimension = 1
if CurrentDimension > MaxDimension [this] then
return this
elseif CurrentDimension == MaxDimension [this] then
set CurrentKey = CurrentKey + aid
else
set CurrentKey = CurrentKey + (aid - 1) * GetArrayCount(this, CurrentDimension)
endif
return this
endmethod
endstruct
endlibrary
Last edited: