• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Integer to Handle function

Status
Not open for further replies.
Level 12
Joined
Mar 13, 2012
Messages
1,121
Is there any other I2Handle function besides the fogstate bug in 1.26a?


edit: To rephrase the question: Is there a way to check if a handle is null while only having its id?


edit2: Is a real I2H actually possible with the fogstate bug? I2X sure is possible (X being unit, widget,...)
 
Last edited:
Level 12
Joined
Mar 13, 2012
Messages
1,121
If you know to what the handle belonged and load it into such variable type, then imo you will find out if it exists or not by checking if the value in variable is null or not.

In my test scenario I dont know that. I just want a I2H function which takes an integer and returns the corresponding handle (or null if there is no such handle) aka the reverse of GetHandleId().
 
I accidentally pressed my back button on my keyboard (stupid Lenovo's), so this information will likely be a bit short.

To implement an I2H that way would require exhaustion. Here is the basic process:
  1. Save the ID in a hashtable using SaveFogStateHandle()
  2. Load every type from the hashtable. If it does not return null, then that means it is that type, in which case, you would simply return that handle.
  3. If every "Load" call returns null, then the handle is either destroyed or no handle exists at that ID.

Why does this work? When you save an object in a hashtable and attempt to load it, the hashtable likely performs a type-check on the loading type and the type associated with the ID. For example, if you save a location at (0, 0) and try to load it as a unit, it will return null. If you load it as a location, it will return the proper handle.

However, there is one issue with that: not all handle ID's are unique. Only agent ID's are unique (an agent is any reference counted object with a handle ID greater than 0x100000). So if you tried this method with a texttag or a lightning, you could possibly have a collision (one texttag and one lightning can possess the same handle ID). Well, the method fails anyway in general. It turns out you cannot load a texttag or a lightning using the fogstate casting method, even if a handle exists at that ID. Since their handle ID's aren't unique, I assume Blizzard uses a different type-checking technique, which is why the fogstate method will always return null.

Bummer. But that doesn't mean the method won't work! It just means that you're restricted to agents. Here is a general skeleton of the function:
JASS:
function I2H takes integer id returns handle
    if id < 0x100000 then
        debug call BJDebugMsg("[I2H] Expected agent ID > 0x100000.")
        return null
    endif
    call SaveFogStateHandle(ht, 0, 0, ConvertFogState(id))
    if LoadUnitHandle(ht, 0, 0) != null then
        return LoadUnitHandle(ht, 0, 0)
    endif
    if LoadPlayerHandle(ht, 0, 0) != null then
        return LoadPlayerHandle(ht, 0, 0)
    endif
    // etc..

    /* destroyed or unused handle ID */
    return null
endfunction

But this presents a question: did Blizzard provide a hashtable function for all agents? No. They left out gamecache. And camerasetup, which is technically an agent considering its handle ID is greater than 0x100000. In those cases, you would need hooking. Or if this is a map-specific implementation, you could just monitor those types yourself.

Why not make it I2Agent? Well, Blizzard might've been a little lazy when implementing the agent type. Some types are agents even if they don't extend it*: triggeraction, camerasetup (I assume), unitpool, itempool
So it has to be I2H, or else it'll give an error if you try to return a triggeraction/unitpool/etc.
*assuming that agents are defined as reference counted objects with handle ID's greater than 0x100000

But it should work. It may seem like a performance heavy function, but I assume this would be for debugging? If not, you can always run it in its own thread. That won't help performance but it'll help prevent hitting the op limit. AFAIK, there isn't any other way that has been discovered yet.
 
Status
Not open for further replies.
Top