System Hashtable Attachment System (Local Handle Vars with hashtables)

jwallstone

New Member
Reaction score
33
Hashtable Handle Attachment System (Local Handle Vars with hashtables)

Here's a rewrite of KaTTaNa's Local Handle Vars using hashtable natives. The original can be found here:
http://www.wc3jass.com/viewtopic.php?p=3737

NOTE: I claim absolutely no credit for this. This involved very little work on my part, and definitely no creative work. All credit should go to KaTTaNa. I'm posting this only to help out other people who may be interested in an updated version for patch 1.24.

The system can be used to "attach" or "associate" any of the core data types (integers, reals, strings, booleans) as well as handles of the agent type with any other handle. (Agent type handles are the reference counted handle types.)

There are two ways to use this:
1. Easy way - create a Hashtable global var, and replace the return value in the HATable function with your variable
2. Less easy, but better way - create a Hashtable global var and replace all function calls to HATable() with your global variable. The function HATable can be removed.
Either way, the hashtable must be initialized with a call to InitHA() before use.

Notes:
1. The function for saving handles has been renamed to SetHandleAgent, to reflect the fact that only agent type handles can be saved.
2. To erase an entry, you do not simply save a 0, false, or null value. Instead call the appropriate "Remove_blank_" function. This is to allow these values to be saved as legitimate entries, and to ensure the proper operation of HaveSaved_blank_ when these values are saved. Furthermore, it enforces better code writing in terms of readability and clarity of function use.
3. The Remove functions have an extra step of storing a useless value (0,null,false) to prevent bugs that were discovered with hashtables as of the beta patch 1.24. If the bugs no longer exist, those lines will be removed.

JASS:
function HATable takes nothing returns hashtable
    return udg_HATable
endfunction
function InitHA takes nothing returns nothing
    local hashtable ha = HATable()
    set ha = InitHashtable()
    set ha = null
endfunction

function SetHandleAgent takes handle subject, string name, agent value returns nothing
    call SaveAgentHandle(HATable(), GetHandleId(subject), StringHash(name), value)
endfunction
function SetHandleInt takes handle subject, string name, integer value returns nothing
    call SaveInteger(HATable(), GetHandleId(subject), StringHash(name), value)
endfunction
function SetHandleBoolean takes handle subject, string name, boolean value returns nothing
    call SaveBoolean(HATable(), GetHandleId(subject), StringHash(name), value)
endfunction
function SetHandleReal takes handle subject, string name, real value returns nothing
    call SaveReal(HATable(), GetHandleId(subject), StringHash(name), value)
endfunction
function SetHandleString takes handle subject, string name, string value returns nothing
    call SaveStr(HATable(), GetHandleId(subject), StringHash(name), value)
endfunction

function GetHandleInt takes handle subject, string name returns integer
    return LoadInteger(HATable(), GetHandleId(subject), StringHash(name))
endfunction
function GetHandleBoolean takes handle subject, string name returns boolean
    return LoadBoolean(HATable(), GetHandleId(subject), StringHash(name))
endfunction
function GetHandleReal takes handle subject, string name returns real
    return LoadReal(HATable(), GetHandleId(subject), StringHash(name))
endfunction
function GetHandleString takes handle subject, string name returns string
    return LoadStr(HATable(), GetHandleId(subject), StringHash(name))
endfunction
function GetHandleUnit takes handle subject, string name returns unit
    return LoadUnitHandle(HATable(), GetHandleId(subject), StringHash(name))
endfunction
function GetHandleItem takes handle subject, string name returns item
    return LoadItemHandle(HATable(), GetHandleId(subject), StringHash(name))
endfunction
function GetHandleTimer takes handle subject, string name returns timer
    return LoadTimerHandle(HATable(), GetHandleId(subject), StringHash(name))
endfunction
function GetHandleTrigger takes handle subject, string name returns trigger
    return LoadTriggerHandle(HATable(), GetHandleId(subject), StringHash(name))
endfunction
function GetHandleEffect takes handle subject, string name returns effect
    return LoadEffectHandle(HATable(), GetHandleId(subject), StringHash(name))
endfunction
function GetHandleGroup takes handle subject, string name returns group
    return LoadGroupHandle(HATable(), GetHandleId(subject), StringHash(name))
endfunction
function GetHandleLightning takes handle subject, string name returns lightning
    return LoadLightningHandle(HATable(), GetHandleId(subject), StringHash(name))
endfunction
function GetHandleWidget takes handle subject, string name returns widget
    return LoadWidgetHandle(HATable(), GetHandleId(subject), StringHash(name))
endfunction
function GetHandleLocation takes handle subject, string name returns location
    return LoadLocationHandle(HATable(), GetHandleId(subject), StringHash(name))
endfunction
function GetHandlePlayer takes handle subject, string name returns player
    return LoadPlayerHandle(HATable(), GetHandleId(subject), StringHash(name))
endfunction
function GetHandleRegion takes handle subject, string name returns region
    return LoadRegionHandle(HATable(), GetHandleId(subject), StringHash(name))
endfunction
function GetHandleRect takes handle subject, string name returns rect
    return LoadRectHandle(HATable(), GetHandleId(subject), StringHash(name))
endfunction
function GetHandleForce takes handle subject, string name returns force
    return LoadForceHandle(HATable(), GetHandleId(subject), StringHash(name))
endfunction
function GetHandleFogmodifier takes handle subject, string name returns fogmodifier
    return LoadFogModifierHandle(HATable(), GetHandleId(subject), StringHash(name))
endfunction
function GetHandleTimerDialog takes handle subject, string name returns timerdialog
    return LoadTimerDialogHandle(HATable(), GetHandleId(subject), StringHash(name))
endfunction

function HaveHandleHandle takes handle subject, string name returns boolean
    return HaveSavedHandle(HATable(), GetHandleId(subject), StringHash(name))
endfunction
function HaveHandleInt takes handle subject, string name returns boolean
    return HaveSavedInteger(HATable(), GetHandleId(subject), StringHash(name))
endfunction
function HaveHandleReal takes handle subject, string name returns boolean
    return HaveSavedReal(HATable(), GetHandleId(subject), StringHash(name))
endfunction
function HaveHandleString takes handle subject, string name returns boolean
    return HaveSavedString(HATable(), GetHandleId(subject), StringHash(name))
endfunction
function HaveHandleBoolean takes handle subject, string name returns boolean
    return HaveSavedBoolean(HATable(), GetHandleId(subject), StringHash(name))
endfunction

function RemoveHandle takes handle subject, string name returns nothing
    call SaveAgentHandle(HATable(),GetHandleId(subject),StringHash(name), null)
    call RemoveSavedHandle(HATable(),GetHandleId(subject),StringHash(name))
endfunction
function RemoveInt takes handle subject, string name returns nothing
    call SaveInteger(HATable(),GetHandleId(subject),StringHash(name), 0)
    call RemoveSavedInteger(HATable(),GetHandleId(subject),StringHash(name))
endfunction
function RemoveReal takes handle subject, string name returns nothing
    call SaveReal(HATable(),GetHandleId(subject),StringHash(name), 0.0)
    call RemoveSavedReal(HATable(),GetHandleId(subject),StringHash(name))
endfunction
function RemoveBoolean takes handle subject, string name returns nothing
    call SaveBoolean(HATable(),GetHandleId(subject),StringHash(name), false)
    call RemoveSavedBoolean(HATable(),GetHandleId(subject),StringHash(name))
endfunction
function RemoveStr takes handle subject, string name returns nothing
    call SaveStr(HATable(),GetHandleId(subject),StringHash(name), null)
    call RemoveSavedString(HATable(),GetHandleId(subject),StringHash(name))
endfunction

function FlushHandle takes handle subject returns nothing
    call FlushChildHashtable(HATable(), GetHandleId(subject) )
endfunction
 

RaiJin

New Member
Reaction score
40
completely pointess, there's no need for this because vex already wrote one...reinvent the wheel ? :S
 

black.sheep

Active Member
Reaction score
24
Eh, helps me.
I luv you, my map would've required serious work to fix if it wasnt for this.
But no FlushHandleLocals funct FTL.
 

jwallstone

New Member
Reaction score
33
@blacksheep
I thought this might at least help some people who were still using the old system. It does have a flushing function, though I think I changed the name to FlushHandle. But it does exactly the same thing and you can just rename it.

I did find Vex's version:
http://www.wc3c.net/showthread.php?t=106558&highlight=Faux+Handle+Vars

There are a few important differences: his is trying to reproduce Local Handle Vars EXACTLY. However, there are a few major changes now that I think need to be reflected in the code. They are noted above in the original post too.

First, only Agents can be saved, not all handles, so the main saving function name was changed to reflect this. It's important for people to at least see this so they don't try to save other handles and have all sorts of problems.

Second, the old LHV deleted entries by having people save sort of a "default" value, like 0, null, or false, over the old entry. This behavior is quite faulty/buggy for several reasons and is poor programming practice.

1. By using this method to save new values, you prevent anybody from actually using those "default" values as valid entries. 0 is no longer a valid number to store, nor is false, etc. If you should ever try to save one of those values and later on check if something is stored in that entry with HaveSaved_blank_, then your code will fail.

2. Deleting entries by simply storing a new value makes code unreadable and confusing. People would have no clear idea whether someone is actually trying to save a value for later use or just deleting it. The old way was always horribly counterintuitive. Since there are explicit Remove functions, it's a lot better this way to actually call a Remove function when you want to remove.
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
So, if you want it able to attach handles, use a wrapper like this :
JASS:
struct HandleWrap
handle data
endstruct
 

Romek

Super Moderator
Reaction score
963
Moved to Graveyard.
 

black.sheep

Active Member
Reaction score
24
Err, problem.
This doesnt seem to work for me. Neither does Vexs version. This one either has issues with attaching or getting handles and Vexs version crashes my JassHelper.
Help?
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top