• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

Where is the handle leak in this function ???

Status
Not open for further replies.
Level 12
Joined
Jan 30, 2020
Messages
875
Hello guys.

I have tested my map with a handle counter :

JASS:
function HandleCount takes nothing returns boolean
    local location l=Location(0,0)
    call BJDebugMsg(I2S(GetHandleId(l)-0x100000))
    call RemoveLocation(l)
    set l=null
    return false   
endfunction


function LeakTest takes nothing returns nothing
    local trigger t=CreateTrigger()

    call TriggerRegisterTimerEvent(t,2.00,true)
    call TriggerAddCondition(t,function HandleCount)
    set t=null
endfunction

First of all sorry, I actually didn't put proper spacing on my code, and I am sorry for that.

Next, this trigger is created at map initialization.

After hours of testing, it shows me that the map starts with a handle count of about 700-800
And at the last level (50), it gets close to 100k handles.
I'm not a handle expert, but this is definitely not a leak free behavior.

This is difficult, as everywhere in all my functions, i null local handles, and destroy objects when not used anymore. The only thing I don't care to destroy are the trigger conditions (all my triggers actions have been moved to conditions with no issue).
Fact is, I read in these forums that Conditions have a specific advantage over actions : they get destroyed when the owning trigger is destroyed (don't have the thread link, but it was a compilation of performance benchmarks).

Anyways, I decided to track handle leaks in each and every function I can identify.


The first thing I noticed to increase the handle count slightly but continuously is a custom "Auto Blink" ability that all my units have (buildings and heroes).

here it is :

JASS:
function DoTheBlink takes nothing returns boolean
    local integer order=GetIssuedOrderId()
    local unit theUnit
    local real dX
    local real dY
    local real oX
    local real oY
    local real tX
    local real tY

    if ((order==OrderId("patrol")) or (order==OrderId("smart"))) then
        set theUnit=GetOrderedUnit()
        set oX=GetUnitX(theUnit)
        set oY=GetUnitY(theUnit)
        set tX=GetOrderPointX()
        set tY=GetOrderPointY()
        set dX=oX-tX
        set dY=oY-tY
        if ((dX*dX+dY*dY)>FreeBlinkRange*FreeBlinkRange) then
            call PlayCleanSFX(SFXBlinkCaster , oX , oY, 1.40, 0.00, 0, 1.00)
            call PlayCleanSFX(SFXBlinkTarget , tX , tY, 1.40, 0.00, 0, 1.00)
            call SetUnitPosition(theUnit, tX, tY)
        endif
    endif
    set theUnit=null
    return false
endfunction


function Auto_Blink takes nothing returns nothing
    local integer i=0
    local trigger autoBlink=CreateTrigger()

    loop
      exitwhen i>3
      if ((GetPlayerSlotState(Player(i))==PLAYER_SLOT_STATE_PLAYING)) then
          call TriggerRegisterPlayerUnitEvent(autoBlink, Player(i), EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, null)
      endif
      set i=i+1
    endloop
    call TriggerAddCondition(autoBlink, function DoTheBlink)
    set autoBlink=null
endfunction

As far as I can see, there is no reason for that code to leak, so I want to inspect the PlaySFX function I made to control SFX and their duration with a timer :


JASS:
function CleanSFX takes nothing returns nothing
    local timer sfxTimer=GetExpiredTimer()
    local integer parentKey=GetHandleId(sfxTimer)
    local effect sfx=LoadEffectHandle(SFXTable, parentKey, 0)

    call RemoveSavedHandle(SFXTable, parentKey, 0)
    call FlushChildHashtable(SFXTable, parentKey)
    call DestroyEffect(sfx)
    set sfx=null
    call DestroyTimer(sfxTimer)
    set sfxTimer=null
endfunction


function PlayCleanSFX takes string sfxString,real x,real y, real scale, real angle, integer colorindex, real duration returns nothing
    local timer sfxTimer=CreateTimer()
    local effect sfx=AddSpecialEffect(sfxString, x, y)
    local integer parentKey=GetHandleId(sfxTimer)

    call BlzSetSpecialEffectScale(sfx, scale)
    call BlzSetSpecialEffectRoll(sfx, angle)
    if (colorindex!=0) then
        call BlzSetSpecialEffectColor(sfx, Red[colorindex], Green[colorindex], Blue[colorindex])
    endif
    call SaveEffectHandle(SFXTable, parentKey, 0, sfx)
    set sfx=null
    call TimerStart(sfxTimer, duration, false, function CleanSFX)
    set sfxTimer=null
endfunction

But there again, every handle seems to be treated properly to prevent leaks. So I am stuck.

Can anyone identify the source of the leak ? Because thats honestly beyond me at this point.
And trust me most of my functions treat handles in the same way, so if I don't find out, I am condemned to a perpetually leaking map.

Please help me, I reached the limit of my knowledge right there.
 
Status
Not open for further replies.
Top