• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[System] Handle Counter

JASS:
library HandleCounting
    globals
        private hashtable H = InitHashtable()
    endglobals

    private function I2A takes integer whichInteger returns agent
        call SaveFogStateHandle(H,0,0,ConvertFogState(whichInteger))
        return LoadAgentHandle(H,0,0)
    endfunction

    function GetHandleCount takes nothing returns integer   
        local location maxHandleIndicator = Location(0.,0.)
        local integer maxHandleId = GetHandleId(maxHandleIndicator)
        local integer countCorrector = 0x100059
        
        call RemoveLocation(maxHandleIndicator)
        
        loop
            exitwhen countCorrector > maxHandleId
            if I2A(countCorrector) == null then
                set maxHandleId = maxHandleId - 1
            endif
            set countCorrector = countCorrector + 1 
        endloop
        
        set maxHandleIndicator = null
        
        return maxHandleId-0x100059
    endfunction

endlibrary

This thing must give accurate number of handles.
Thanks Geries and Magtheridon96 for the tips
 
Last edited by a moderator:
Level 17
Joined
Apr 27, 2008
Messages
2,455
The first handle id will not always be 0x100059.
It all depends the map script and eventually if there is a custom common.j/blizzard.j

Also i suppose that maps with heavy preplaced stuff, the limit op will always be reached when GetHandleCount will be called.

And finally i'm not 100 % sure that all type of handles always share the same stack, sounds for example.
Yes i'm not talking about agents with their own stack, such as image and texttag.
 
Assume the handle count starts at 0x100000. Blizzard.j/Common.j handles should be taken into account :V

This is what is supposed to be done in pseudo code:

Code:
onInit:
- create stack of handles (0 handles in it)

In the function:
while (!consecutive_handles == RESOLUTION)
    create new handle
    if handle id is exactly 1 greater than the previous handle id
        consecutive_handles++
    else
        consecutive_handles = 0
    end if
    prevHandleId = thisHandleId
    push current handle to stack
    genHandleCount++
end while

while (not stack empty)
    destroy handle
end while

return thisHandleId - genHandleCount - 0x100000

edit
This was already done by TRD though.
 
Also i suppose that maps with heavy preplaced stuff, the limit op will always be reached when GetHandleCount will be called.

And finally i'm not 100 % sure that all type of handles always share the same stack, sounds for example.
Yes i'm not talking about agents with their own stack, such as image and texttag.
I'd say those weaknesses don't matter much here.
The snippet is extremely short in code and easy to implement, which serves and matches the purpose of handlecounters perfectly: helping those that want to learn vJASS to make it right.

I'd say no experienced JASSer will ever need a handlecounter to create a clean code, simply because removing leaks at some point becomes a reflex/routine. It's nice to have those tools when learning, and usually when you learn JASS; you don't work on massive projects with millions of handles.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
You don't need millions to reach the limit op there, only several thousands, or maybe even only several hundred.
In some playable maps it's a possible scenario only with preplaced stuff.

Now i'm just saying, as you said i personnaly don't care about a such resource.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
The best way to fix this, then, is to do some BJDebugMsg, launch this from a trigger evaluate which returns true, and if the evaluate returns false then BJDebugMsg how many iterations it took to get to that point.

This script should open up a new thread for all jobs. That way if you call it then you're not getting screwed if your thread was already heavy.
 
Top