HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Another one, big, memoryleak

01-10-2005, 11:33 PM#1
Mjukland
Ok, this is a big one, I got some kind of memory leak which I can't figure out... :/

Code:
function HandleToInt6 takes handle h returns integer
    return h
    return 0
endfunction

function IntToHandle6 takes integer i returns handle
    return i
    return null
endfunction 

function LocalVars6 takes nothing returns gamecache
    return udg_CacheBackDash
endfunction

function SetHandleHandle6 takes handle subject, string name, handle value returns nothing
    if value==null then
        call FlushStoredInteger(LocalVars6(),I2S(HandleToInt6(subject)),name)
    else
        call StoreInteger(LocalVars6(), I2S(HandleToInt6(subject)), name, HandleToInt6(value))
    endif
endfunction

function SetHandleInt6 takes handle subject, string name, integer value returns nothing
    if value==0 then
        call FlushStoredInteger(LocalVars6(),I2S(HandleToInt6(subject)),name)
    else
        call StoreInteger(LocalVars6(), I2S(HandleToInt6(subject)), name, value)
    endif
endfunction

function SetHandleReal6 takes handle subject, string name, real value returns nothing
    if value==0 then
        call FlushStoredReal(LocalVars6(), I2S(HandleToInt6(subject)), name)
    else
        call StoreReal(LocalVars6(), I2S(HandleToInt6(subject)), name, value)
    endif
endfunction

function GetHandleHandle6 takes handle subject, string name returns handle
    return IntToHandle6(GetStoredInteger(LocalVars6(), I2S(HandleToInt6(subject)), name))
endfunction
function GetHandleInt6 takes handle subject, string name returns integer
    return GetStoredInteger(LocalVars6(), I2S(HandleToInt6(subject)), name)
endfunction
function GetHandleReal6 takes handle subject, string name returns real
    return GetStoredReal(LocalVars6(), I2S(HandleToInt6(subject)), name)
endfunction

function FlushHandleLocals6 takes handle subject returns nothing
    call FlushStoredMission(LocalVars6(), I2S(HandleToInt6(subject)) )
endfunction

//=================END HANDELS============

//WEU FUNCTION

function FadingText_child takes nothing returns nothing

local integer alpha=255
local integer red=S2I(SubString(bj_cineFadeContinueTex,1,4))
local integer green=S2I(SubString(bj_cineFadeContinueTex,4,7))
local integer blue=S2I(SubString(bj_cineFadeContinueTex,7,10))
local texttag t= bj_lastCreatedTextTag
call DestroyTrigger(GetTriggeringTrigger())
call TriggerSleepAction(1.00)
loop
set alpha=alpha - 32
exitwhen alpha <= 0
call SetTextTagColor(t,red,green,blue,alpha)
call TriggerSleepAction(0.01)
endloop
call DestroyTextTag(t)
set t = null
endfunction

function FadingText takes string msg, integer red, integer green, integer blue, real x, real y returns nothing

local texttag t = CreateTextTag()
local trigger child = CreateTrigger()
call SetTextTagText(t,msg,0.025)
call SetTextTagPos(t,x,y, 0.00)
call SetTextTagColor(t,red,green,blue,255)
call SetTextTagVelocity(t,0,0.02)
call TriggerAddAction(child, function FadingText_child)
set bj_lastCreatedTextTag=t
set bj_cineFadeContinueTex=I2S(1000000000 + red * 1000000 + green * 1000 + blue)
call TriggerExecute(child)
set child = null
endfunction

//WEU FUNCTION

//INFLICT DAMAGE FUNCTION

function inflictdamage takes unit u, unit target, real damage, integer typeofdamage, sound s returns nothing

local real truedamage
local integer i 
local integer randnr
local integer evasion
local integer showdmg
local location l
local real randomdmg

set l = GetUnitLoc(target)
set i = GetConvertedPlayerId(GetOwningPlayer(target))
set evasion = R2I(udg_HeroEvasion[i])

if ( typeofdamage == 1 ) then

    set randnr = GetRandomInt(1, 100)
    if ( randnr > evasion ) then

        set randomdmg = GetRandomReal(1.00, 10.00)
        set damage = damage + randomdmg
        set truedamage = damage - (udg_HeroDefense[i] * 3)
        call UnitDamageTargetBJ( u, target, truedamage, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL )
        set showdmg = R2I(truedamage)
        call FadingText( I2S(showdmg), 255, 0, 0, GetUnitX(target), GetUnitY(target) )
        call PlaySoundAtPointBJ( s, 100, l, 0 )

     else
     endif

else
endif

call RemoveLocation(l)
set l = null

endfunction

//INFLICT DAMAGE FUNCTION

function flashunit takes unit u returns nothing

    call SetUnitVertexColorBJ( u, 100, 0.00, 0.00, 0 )
    call TriggerSleepAction( 0.01 )
    call SetUnitVertexColorBJ( u, 0.00, 100.00, 0.00, 0 )
    call TriggerSleepAction( 0.01 )
    call SetUnitVertexColorBJ( u, 0.00, 0.00, 100.00, 0 )
    call TriggerSleepAction( 0.01 )
    call SetUnitVertexColorBJ( u, 100.00, 100.00, 100.00, 0 )

endfunction

//ARROWFUNCTION

function CheckUnit takes nothing returns boolean
    return ( IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(udg_Hero[udg_IntTempAttack])) == true and IsUnitAliveBJ(GetFilterUnit()) )
endfunction


function ArrowAway takes nothing returns nothing

    local location l = null
    local location l2 = null
    local rect r = null
    local unit target = null
    local integer showdmg
    local integer typeofdamage
    local real damage
    local real randomdmg
    local sound s
    local unit u = null
    local boolean b
    local integer i
    local integer i2

    set i2 = GetHandleInt6(GetTriggeringTrigger(),"intnr")
    set i = GetHandleInt6(GetTriggeringTrigger(),"playernr")
    set u = udg_HeroArcherArrowUnit[i2]
    set b = udg_HeroArcherArrowBool[i2]
    set udg_HeroArcherArrowCounterInt[i2] = udg_HeroArcherArrowCounterInt[i2] + 1

    set typeofdamage = 1
    set s = gg_snd_ColdArrow1
    set l = GetUnitLoc(u)
    set l2 = PolarProjectionBJ(l, 18.00, GetUnitFacing(u))

    call SetUnitPositionLoc( u, l2 )
    set r = RectFromCenterSizeBJ(l2, 130.00, 130.00)
    set udg_IntTempAttack = i
    set target = GroupPickRandomUnit(GetUnitsInRectMatching(r, Condition(function CheckUnit)))

    if ( target != null ) then

    if ( IsUnitType( target, UNIT_TYPE_HERO) == true ) then

    set typeofdamage = 1
    set damage = udg_HeroDamageMain[i]

    if (b == false) then
    set damage = damage * 0.05
    endif

    call inflictdamage( udg_Hero[i], target, damage,typeofdamage,s)
    call KillUnit( u )
    call RemoveUnit( u )
    call RemoveLocation(l)
    call RemoveLocation(l2)
    call RemoveRect(r)
    set r = null
    set l = null
    set l2 = null
    set u = null
    set udg_HeroArcherArrowUnit[i2] = null
    set target = null
    call DestroyTrigger( GetTriggeringTrigger() )

    else
        call PlaySoundAtPointBJ( s, 100, l, 0 )
        set damage = udg_HeroDamageMain[i]
  
        if (b==false ) then
        set damage = damage * 0.05
        endif

        set randomdmg = GetRandomReal(1.00, 10.00)
        set damage = damage + randomdmg
        call UnitDamageTargetBJ( udg_Hero[i], target, damage, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL )
        set showdmg = R2I(damage)
        call FadingText( I2S(showdmg), 255, 0, 0, GetUnitX(target), GetUnitY(target) )
        call KillUnit( u )
        call RemoveUnit( u )
        call RemoveLocation(l)
        call RemoveLocation(l2)
        call RemoveRect(r)
        set r = null
        set l = null
        set l2 = null
        set u = null
        set udg_HeroArcherArrowUnit[i2] = null
        set target = null
        call DestroyTrigger( GetTriggeringTrigger() )

    endif
    else
    endif

    if ( udg_HeroArcherArrowCounterInt[i2] > 32 and IsUnitAliveBJ(u) == true) then
        call KillUnit( u )
        call RemoveUnit( u )
        call RemoveLocation(l)
        call RemoveLocation(l2)
        call RemoveRect(r)
        set r = null
        set l = null
        set l2 = null
        set u = null
        set udg_HeroArcherArrowUnit[i2] = null
        set target = null
        call DestroyTrigger( GetTriggeringTrigger() )
    else
        call RemoveLocation(l)
        call RemoveLocation(l2)
        call RemoveRect(r)
        set r = null
        set l = null
        set l2 = null
        set target = null
    endif


endfunction

//ARROWFUNCTION



//MAIN

function AttackArcherCondition takes nothing returns boolean
    if (GetSpellAbilityId() == 'A000' and GetUnitTypeId(GetTriggerUnit()) == 'H001' )then
        return true
    endif
    return false
endfunction


function AttackArcherAction takes nothing returns nothing

    local unit u = null
    local location l = null
    local integer i
    local trigger t = null
    local triggeraction ta = null
    local boolean ArrowCharged = false
    local player p

    set udg_HeroArcherInteger = udg_HeroArcherInteger + 1

    set t = CreateTrigger()
    set p = GetOwningPlayer(GetTriggerUnit())
    set i = GetConvertedPlayerId(p)

    set udg_BoolHeroArrowUp[i] = false
    set udg_BoolHeroArrowDown[i] = false
    set udg_BoolHeroArrowLeft[i] = false
    set udg_BoolHeroArrowRight[i] = false
    set udg_RealTimerMovement[i] = 1

    set l = GetUnitLoc(udg_Hero[i])
    call ResetUnitAnimation( udg_Hero[i] )
    call SetUnitAnimation( udg_Hero[i], "attack" )
    set udg_IntTempAttack = i

    if (udg_HeroCharge[i] >= 100 ) then
    set udg_HeroArcherArrowBool[udg_HeroArcherInteger] = true
    endif   

    call CreateNUnitsAtLoc( 1, 'h002', p, l, GetUnitFacing(udg_Hero[i]) )
    set udg_HeroArcherArrowUnit[udg_HeroArcherInteger] = GetLastCreatedUnit()

 
    call SetHandleInt6(t,"intnr",udg_HeroArcherInteger)
    call SetHandleInt6(t,"playernr",i)

    call TriggerRegisterTimerEventPeriodic( t, 0.03 )
    call TriggerAddAction( t, function ArrowAway )
    set ta = TriggerAddAction(t, function ArrowAway)

    set udg_HeroCharge[i] = 0
    set udg_StringTest[i] = ""

    call RemoveLocation (l)
    set l = null
    set u = null
    set p = null
    call PolledWait(3)
    call TriggerRemoveAction( t, ta )
    set ta = null

endfunction


//===========================================================================
function InitTrig_Attack_Archer takes nothing returns nothing
    set gg_trg_Attack_Archer = CreateTrigger(  )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Attack_Archer, Player(0), EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Attack_Archer, Player(1), EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Attack_Archer, Player(2), EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Attack_Archer, Player(3), EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Attack_Archer, Player(4), EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Attack_Archer, Player(5), EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Attack_Archer, Player(6), EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Attack_Archer, Player(7), EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Attack_Archer, Player(8), EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Attack_Archer, Player(9), EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Attack_Archer, Condition( function AttackArcherCondition ) )
    call TriggerAddAction( gg_trg_Attack_Archer, function AttackArcherAction )
endfunction
01-11-2005, 12:31 AM#2
PitzerMike
call DestroyTrigger(child) is still missing in the FadingText function, but I guess it won't cause heavy leaks.

Also the following two lines look weird:

call TriggerAddAction( t, function ArrowAway )
set ta = TriggerAddAction(t, function ArrowAway)

the first line isn't needed.
That's what I've found at a first glance.
01-11-2005, 03:03 AM#3
Ryude
Ya, what pitzer means is you don't have to call a function if you are setting a variable to it.

set u=CreateUnit(player(0),1235.67,1234.56,270.00)
and
call CreateUnit(player(0),1234.56,1234.56,270.00) are the same thing.
01-11-2005, 09:57 AM#4
Mjukland
Quote:
Originally Posted by Ryude
Ya, what pitzer means is you don't have to call a function if you are setting a variable to it.

set u=CreateUnit(player(0),1235.67,1234.56,270.00)
and
call CreateUnit(player(0),1234.56,1234.56,270.00) are the same thing.

Ops, yeah, I forgot to delete the first line, either way that's not the cause of the leak... deleting the child trigger does'nt make any noticable diffrence either... the problem seems to be somewhere in the arrowfunction, I have another trigger that uses almost the same function and that one does'nt leak..

I belive its something with creating a unit, move it and destroy it that leaks...
01-11-2005, 12:46 PM#5
PitzerMike
set target = GroupPickRandomUnit(GetUnitsInRectMatching(r, Condition(function CheckUnit)))

That line leaks the passed unit group and the condition.

Use local group and conditionfunc variables, to be able to destroy them afterwards (using DestroyGroup() and DestroyCondition())
01-11-2005, 01:01 PM#6
Mjukland
Quote:
Originally Posted by PitzerMike
set target = GroupPickRandomUnit(GetUnitsInRectMatching(r, Condition(function CheckUnit)))

That line leaks the passed unit group and the condition.

Use local group and conditionfunc variables, to be able to destroy them afterwards (using DestroyGroup() and DestroyCondition())

Oh, Ok, I'll change that, but will it leak even if there is no unit in that rect? If not, there is another big leak somewhere,

I guess you've figured it out already, but if not , what the trigger does is, when a unit uses an ability, a "arrow" is created that moves with high speed forward until it hits something or is destroyed automaticly after a certain time.

the trigger leaks even if it does'nt hit something, so most of the code should be clean. But I'll fix this leak, hopefully it's the one causing the heavy leak.

btw. thanks for all help
01-11-2005, 08:48 PM#7
Mjukland
Ok, I've fixed some thing, still leaks though, running the trigger every 0.5 sec for 10 min will increase the memory usage by about 10mb :/

Code:
//ARROWFUNCTION

function CheckUnit takes nothing returns boolean
  
    local unit u
    local player p
    set udg_TempPlayer = GetOwningPlayer(udg_Hero[udg_IntTempAttack])
    set udg_TempUnit = GetFilterUnit()
    return ( IsUnitEnemy(udg_TempUnit,udg_TempPlayer ) == true and IsUnitAliveBJ(udg_TempUnit) )

endfunction

function ArrowAway takes nothing returns nothing

    local location l = null
    local location l2 = null
    local rect r = null
    local unit target = null
    local integer showdmg
    local integer typeofdamage
    local real damage
    local real randomdmg
    local sound s
    local unit u = null
    local boolean b
    local integer i
    local integer i2
    local conditionfunc c
    local group g = null

    set i2 = GetHandleInt6(GetTriggeringTrigger(),"intnr")
    set i = GetHandleInt6(GetTriggeringTrigger(),"playernr")
    set u = udg_HeroArcherArrowUnit[i2]
    set b = udg_HeroArcherArrowBool[i2]
    set udg_HeroArcherArrowCounterInt[i2] = udg_HeroArcherArrowCounterInt[i2] + 1

    set typeofdamage = 1
    set s = gg_snd_ColdArrow1
    set l = GetUnitLoc(u)
    set l2 = PolarProjectionBJ(l, 18.00, GetUnitFacing(u))

    call SetUnitPositionLoc( u, l2 )

    set r = RectFromCenterSizeBJ(l2, 130.00, 130.00)
    set udg_IntTempAttack = i
    set c = Condition(function CheckUnit)
    
    set udg_TempUnit = null
    set udg_TempPlayer = null
    set g = GetUnitsInRectMatching(r,c)

    if (CountUnitsInGroup(g) > 0 ) then
    set target = GroupPickRandomUnit(g)
    endif
    
    call DestroyGroup(g)
    call DestroyCondition(c)
    set g = null
    set c = null

    if ( target != null ) then

    if ( IsUnitType( target, UNIT_TYPE_HERO) == true ) then

    set typeofdamage = 1
    set damage = udg_HeroDamageMain[i]

    if (b == false) then
    set damage = damage * 0.05
    endif

    call inflictdamage( udg_Hero[i], target, damage,typeofdamage,s)
    call KillUnit( u )
    call RemoveUnit( u )
    call RemoveLocation(l)
    call RemoveLocation(l2)
    call RemoveRect(r)
    set r = null
    set l = null
    set l2 = null
    set u = null
    set udg_HeroArcherArrowUnit[i2] = null
    set target = null
    call DestroyTrigger( GetTriggeringTrigger() )

    else
        call PlaySoundAtPointBJ( s, 100, l, 0 )
        set damage = udg_HeroDamageMain[i]
  
        if (b==false ) then
        set damage = damage * 0.05
        endif

        set randomdmg = GetRandomReal(1.00, 10.00)
        set damage = damage + randomdmg
        call UnitDamageTargetBJ( udg_Hero[i], target, damage, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL )
        set showdmg = R2I(damage)
        call FadingText( I2S(showdmg), 255, 0, 0, GetUnitX(target), GetUnitY(target) )
        call KillUnit( u )
        call RemoveUnit( u )
        call RemoveLocation(l)
        call RemoveLocation(l2)
        call RemoveRect(r)
        set r = null
        set l = null
        set l2 = null
        set u = null
        set udg_HeroArcherArrowUnit[i2] = null
        set target = null
        call DestroyTrigger( GetTriggeringTrigger() )

    endif
    else
    endif

    if ( udg_HeroArcherArrowCounterInt[i2] > 32 and IsUnitAliveBJ(u) == true) then
        call KillUnit( u )
        call RemoveUnit( u )
        call RemoveLocation(l)
        call RemoveLocation(l2)
        call RemoveRect(r)
        set r = null
        set l = null
        set l2 = null
        set u = null
        set udg_HeroArcherArrowUnit[i2] = null
        set target = null
        call DestroyTrigger( GetTriggeringTrigger() )
    else
        call RemoveLocation(l)
        call RemoveLocation(l2)
        call RemoveRect(r)
        set r = null
        set l = null
        set l2 = null
        set target = null
    endif


endfunction

//ARROWFUNCTION



//MAIN

function AttackArcherCondition takes nothing returns boolean
    if (GetSpellAbilityId() == 'A000' and GetUnitTypeId(GetTriggerUnit()) == 'H001' )then
        return true
    endif
    return false
endfunction


function AttackArcherAction takes nothing returns nothing

    local unit u = null
    local location l = null
    local integer i
    local trigger t = null
    local triggeraction ta = null
    local boolean ArrowCharged = false
    local player p

    set udg_HeroArcherInteger = udg_HeroArcherInteger + 1

    set t = CreateTrigger()
    set p = GetOwningPlayer(GetTriggerUnit())
    set i = GetConvertedPlayerId(p)

    set udg_BoolHeroArrowUp[i] = false
    set udg_BoolHeroArrowDown[i] = false
    set udg_BoolHeroArrowLeft[i] = false
    set udg_BoolHeroArrowRight[i] = false
    set udg_RealTimerMovement[i] = 1

    set l = GetUnitLoc(udg_Hero[i])
    call ResetUnitAnimation( udg_Hero[i] )
    call SetUnitAnimation( udg_Hero[i], "attack" )
    set udg_IntTempAttack = i

    if (udg_HeroCharge[i] >= 100 ) then
    set udg_HeroArcherArrowBool[udg_HeroArcherInteger] = true
    endif   

    call CreateNUnitsAtLoc( 1, 'h002', p, l, GetUnitFacing(udg_Hero[i]) )
    set udg_HeroArcherArrowUnit[udg_HeroArcherInteger] = GetLastCreatedUnit()

    call SetHandleInt6(t,"intnr",udg_HeroArcherInteger)
    call SetHandleInt6(t,"playernr",i)

    call TriggerRegisterTimerEventPeriodic( t, 0.03 )
    set ta = TriggerAddAction(t, function ArrowAway)

    set udg_HeroCharge[i] = 0
    set udg_StringTest[i] = ""

    call RemoveLocation (l)
    set l = null
    set u = null
    set p = null
    call PolledWait(3)
    call TriggerRemoveAction( t, ta )
    set ta = null
    set t = null
    
endfunction
01-11-2005, 10:35 PM#8
PitzerMike
I realized that you don't clean up all local variables in every case.
For example why is it that you only clean up some variables in the last else of that function?
Maybe I'm wrong but I don't think they've been cleaned up before.

Though the strange indentation might have fooled my eyes.
01-11-2005, 11:35 PM#9
Mjukland
Quote:
Originally Posted by PitzerMike
I realized that you don't clean up all local variables in every case.
For example why is it that you only clean up some variables in the last else of that function?
Maybe I'm wrong but I don't think they've been cleaned up before.

Though the strange indentation might have fooled my eyes.

You see, when the if gets true, this is when the arrow has moved its "attackrange" and not hit anything, then its automaticly destroyed, otherwise only locations and rects are destroyed.

Code:
    if ( udg_HeroArcherArrowCounterInt[i2] > 32 and IsUnitAliveBJ(u) == true) then
        call KillUnit( u )
        call RemoveUnit( u )
        call RemoveLocation(l)
        call RemoveLocation(l2)
        call RemoveRect(r)
        set r = null
        set l = null
        set l2 = null
        set u = null
        set udg_HeroArcherArrowUnit[i2] = null
        set target = null
        call DestroyTrigger( GetTriggeringTrigger() )
    else
        call RemoveLocation(l)
        call RemoveLocation(l2)
        call RemoveRect(r)
        set r = null
        set l = null
        set l2 = null
        set target = null
    endif