HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Eliminating I2H

07-03-2007, 04:54 PM#1
Here-b-Trollz
Would this be probable? (Will there be a need for more than 8000 references to any handle of each type? 8000 item, 8000 units, 8000 boolexrs, etc.)

Collapse JASS:
globals
    gamecache udg_gc    

    unit array I2H___Unit

    item array I2H___Item

    group array I2H___Group

    timer array I2H___Timer

    etc.
endglobals

function GameCache takes nothing returns gamecache
    if(udg_gc==null)then
        set udg_gc=InitCache("MyCache.w3v")
        call FlushGameCache(udg_gc)
    endif
    return udg_gc
endfunction

function H2I takes handle h returns integer
    if(h!=null)then
        return h
    endif
    return 0
endfunction

function HandleAttachUnit takes handle base, string key, unit attachme returns boolean
    local integer a=1
    loop
         exitwhen a>8190 or I2H___Unit[a]==attachme
         set a=a+1         //Checks to see if the unit is already stored
    endloop                 //If so, it will just assign the pointer
    
    if(a>8190)then //No match was found
        set a=1
        loop
            exitwhen a>8190 or I2H___Unit[a]==null
            set a=a+1
        endloop
        if(a>8190)then
            return false
        endif
        set I2H___Unit[a]=attachme
    endif
    call StoreInteger(GameCache(),I2S(H2I(base)),key,a) //The pointer value
    return true
endfunction

function HandleGetUnit takes handle base, string key returns unit
    return I2H___Unit[GetStoredInteger(GameCache(),I2S(H2I(base)),key)]
endfunction

function HandleClearUnit takes handle base, string key returns nothing
    set I2H___Unit[GetStoredInteger(GameCache(),I2S(H2I(base)),key)]=null
    call StoreInteger(GameCache(),I2S(H2I(base)),key,0)
endfunction

I just typed this up, without help from JassCraft, so it might have errors. Basically, I want to eliminate the need for the return bug's inverse opperation, I2H. As we know, this function can, sometimes, bug, thus screwing up the handle index (the reference in which all the pointers are stored), causing massive errors.

So, this group of functions attempts to solve that issue.

Each unit you store is stored in a global unit array. Then, the handle you attached it to recieves a pointer (just like the 7-digit one, but it is instead an integer 1-8190 {0 is not used, as it indicates a null reference}). When you look up the handle's pointer, under a key which you can define, it returns the unit stored in the array under the pointer index. This works for all handle types (but each type needs its own globals array and attach, return, and clear functions.)

What I hope I am doing, in the first loop under HandleAttachUnit, is looking to see if the unit in question is already stored. If so, I just find the index, and assign that as the pointer value to the base handle. Thus, 2+ handles can point to the same unit/group/timer/etc., yet save space. It would be possible to implement more than one array for each type, and I am considering doing it, but I need to know if people would use this (along with a compilation of other database functions developed/edited by me).


Vexorian said that he remove all I2H references from CasterSystem, so I assume he is doing something like this. Not original then, but I would be willing to implement it up to 81,900 references per handle type. Possibly more.


If people would use this, then I will get to work on it, and implement it for all handle types (even the ones nobody uses). If you would use this, would 81,900 references per type be acceptable? And, before you leave, answer this:

Would you rather use one function for each type (HandleGetUnit, HandleGetItem, HandleGetTimer, etc.), or have one universal function, but another parameter (a string) that tells which type of of handle you are using?



Thnx!
07-03-2007, 05:21 PM#2
Vexorian
An opinion about this idea: I hate it.

A more practical way of doing things would be, simply attaching and loading integers, for that Set/GetHandleInt , GetAttachedInt/AttachInt , Set/GetTableInt, SetUnit/ItemUserData are all right.

Once you do that, you can simply use structs (aka global arrays) to do that.

It is of course logically equivalent to what you are trying, but the deal is that we get rid of any need to actually make functions specific for a handle type, instead we make storage devices specific for applications, which actually make the code cleaner...

Most of the Caster system is I2H free, at least the important parts are, although I hope I will once find the time, and will to boot in windows so I finish and release xe and get rid of friging caster system for good.

I am about to become able to run linux on a virtual machine from windows, I got plenty of RAM and I also got some distro that is very light-weight, if everything works, I will be able to use Linux for most of the things and when I need warcraftish stuff I just get out of the virtual machine and open WE
07-03-2007, 06:05 PM#3
Here-b-Trollz
Yeah, this code is getting pretty messy. I started out just wanting to use it for items, but then I though, why not units too? And then of course timers, for the big three.

Apparently I am retarded, but how will I know where to store the handle given? e.g. You give the function a unit to attach, how will I know that it is a unit?

Anyway, I will look into implementing this with structs. Thanks.
07-03-2007, 06:24 PM#4
Vexorian
you are not retarded.

What I do right now when I need to pass data to a unit, item or trigger (I don't have to do this on timers thanks to timelib) is to make an struct with all the data that I have to attach (typically you need to attach more than one thing) , then I can just use CSData or AttachInt to store the reference to the struct on the unit,item/trigger.

I use CSData when the object is private, this means I am sure that no other system will use CSData on that object.

This can be ported to the no struct world, by simply using arrays to store the data. And then attach the index for that object...
07-03-2007, 06:32 PM#5
Here-b-Trollz
...Isn't that what I'm doing? I store the handle in the array of its type, then, any handle that is "attached" to that handle, simply recieves the index so that it can go look it up from its respective array... The only reason I use multiple array types (unit/timer/group/etc.) is because there is not such thing as a handle array - or variable, for that matter.
07-03-2007, 07:16 PM#6
Vexorian
well it is logically equivalent, but one is cleaner than the other and requires less functions.

Also, with mine I only need to store one thing in gamecache, for whatever group of data.
07-03-2007, 08:02 PM#7
Here-b-Trollz
Well... because new things are evil <Vjass>, I suppose I will just struggle with the no struct world. OOP is for squares o.O Oh, and it's best to be able to understand your own code... (curse my lack of initiative)