• 🏆 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!

[Solved] y is this leaking

Status
Not open for further replies.
Level 29
Joined
Oct 24, 2012
Messages
6,543
i have no idea y but i think this is leaking can anyone tell me y ? thx for ur help

note: this is not fully done it is just another minigame im making for my map.

JASS:
scope flameCircles initializer circleOfFlames

globals
    trigger trg_circleOfFlames
    private trigger trg_timer
    private integer Marker = 'e00D'
    private integer Flames = 'e00E'
    private real array tempX
    private real array tempY
    private integer array handleID
    private unit array markerUnits
    private unit array flameUnits
    private real rectMinX
    private real rectMaxX
    private real rectMinY
    private real rectMaxY
    private integer index
    private integer indexEnd = 20
    private unit array playerUnit
    private group unitG
    private integer Group
    private real array CoFX
    private real array CoFY
    private real startX
    private real startY
    private integer ttlPlayers
endglobals

private function winner takes nothing returns nothing
    local integer p = 0
    local region r = CreateRegion()
    call RegionAddRect( r, gg_rct_circleOfFlames)
    loop
        exitwhen p > 5
        if IsUnitInRegion( r, playerUnit) then
            call textall( "Player " + I2S(p+1) + "has won the minigame", p)
            call pauseall( false)
            call DisableTrigger( trg_timer)
        endif
        set p = p + 1
    endloop
    set r = null
endfunction

private function whichTimer takes timer t returns integer
    local integer L = 0
    local integer id = GetHandleId( t)
    loop
        exitwhen L > indexEnd
        if handleID[L] == id then
            return L
        endif
        set L = L + 1
    endloop
    return L
endfunction

private function killing takes nothing returns nothing
    local integer p = GetPlayerId( GetOwningPlayer( GetEnumUnit()))
    if IsUnitInRangeXY( playerUnit, tempX[Group], tempY[Group], 100) then
        set ttlPlayers = ttlPlayers - 1
        call textall( "Player " + I2S(p+1) + " has been killed", p)
        call SetUnitX( playerUnit, CoFX)
        call SetUnitY( playerUnit, CoFY)
        call texti( ttlPlayers)
        if ttlPlayers <= 1 then
            call winner()
        endif
    endif
endfunction

private function flameTimerEnd takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = whichTimer( t)
    call RemoveUnit( markerUnits[h])
    call RemoveUnit( flameUnits[h])
    set Group = h
    call ForGroup( unitG, function killing)
    set markerUnits[h] = null
    set flameUnits[h] = null
    call DestroyTimer( t)
    set t = null
endfunction

private function markerTimerEnd takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = whichTimer( t)
    local timer t1 = CreateTimer()
    set flameUnits[h] = CreateUnit( Player(11), Flames, tempX[h], tempY[h], 0)
    call UnitAddAbility( flameUnits[h], 'Aloc')
    call TimerStart( t1, 1.50, false, function flameTimerEnd)
    set handleID[h] = GetHandleId( t1)
    call DestroyTimer( t)
    set t = null
    set t1 = null
endfunction

private function Actions takes nothing returns nothing
    local timer t = CreateTimer()
    if index == indexEnd then
        set index = 0
    endif
    set tempX[index] = GetRandomReal( rectMinX, rectMaxX)
    set tempY[index] = GetRandomReal( rectMinY, rectMaxY)
    set markerUnits[index] = CreateUnit( Player(11), Marker, tempX[index], tempY[index], 0)
    call UnitAddAbility( markerUnits[index], 'Aloc')
    call TimerStart( t, 2.50, false, function markerTimerEnd)
    set handleID[index] = GetHandleId( t)
    set index = index + 1
    set t = null
endfunction

private function setup takes nothing returns nothing
    local integer p = 0
    call pauseall( true)
    set ttlPlayers = 0
    loop
        exitwhen p > 5
        if GetPlayerSlotState(Player(p)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(p)) == MAP_CONTROL_USER then
            call PauseUnit( playerUnit, false)
            set ttlPlayers = ttlPlayers + 1
            call SetUnitX( playerUnit, startX)
            call SetUnitY( playerUnit, startY)
        endif
        set p = p + 1
    endloop
    call EnableTrigger( trg_timer)
endfunction

private function startup takes nothing returns nothing
    local integer p = 0
    set startX = GetRectCenterX( gg_rct_circleOfFlames)
    set startY = GetRectCenterY( gg_rct_circleOfFlames)
    set unitG = CreateGroup()
    set CoFX[0] = GetRectCenterX( gg_rct_CoF_P0)
    set CoFX[1] = GetRectCenterX( gg_rct_CoF_P1)
    set CoFX[2] = GetRectCenterX( gg_rct_CoF_P2)
    set CoFX[3] = GetRectCenterX( gg_rct_CoF_P3)
    set CoFX[4] = GetRectCenterX( gg_rct_CoF_P4)
    set CoFX[5] = GetRectCenterX( gg_rct_CoF_P5)
    set CoFY[0] = GetRectCenterY( gg_rct_CoF_P0)
    set CoFY[1] = GetRectCenterY( gg_rct_CoF_P1)
    set CoFY[2] = GetRectCenterY( gg_rct_CoF_P2)
    set CoFY[3] = GetRectCenterY( gg_rct_CoF_P3)
    set CoFY[4] = GetRectCenterY( gg_rct_CoF_P4)
    set CoFY[5] = GetRectCenterY( gg_rct_CoF_P5)
    loop
        exitwhen p > 5
        set playerUnit = CreateUnit( Player(p), 'hpea', CoFX, CoFY, 0)
        call PauseUnit( playerUnit, true)
        call GroupAddUnit( unitG, playerUnit)
        set p = p + 1
    endloop
    set rectMinX = GetRectMinX( gg_rct_circleOfFlames)
    set rectMaxX = GetRectMaxX( gg_rct_circleOfFlames)
    set rectMinY = GetRectMinY( gg_rct_circleOfFlames)
    set rectMaxY = GetRectMaxY( gg_rct_circleOfFlames)
    set index= 0
endfunction

private function circleOfFlames takes nothing returns nothing
    set trg_timer = CreateTrigger()
    set trg_circleOfFlames = CreateTrigger()
    call DisableTrigger( trg_timer)
    call startup()
    call TriggerRegisterTimerEvent( trg_timer, 0.25, true)
    call TriggerAddAction( trg_timer, function Actions)
    call TriggerRegisterPlayerChatEvent( trg_circleOfFlames, Player(0), "run", true) //testing purposes
    call TriggerAddAction( trg_circleOfFlames, function setup)
endfunction

endscope
 
Last edited:
Level 29
Joined
Oct 24, 2012
Messages
6,543
You leak the timers. You have to destroy the timer "t" at the end of both flameTimerEnd and markerTimerEnd (you could recycle them but you use a very bizarre identification system...).

However, you don't need to null the objects when they are arguments of functions (such as function whichTimer takes timer t).

wow i cant believe i forgot the destroytimer thing lol thx for catching tht. and i like the way i use my timers ik u can reuse them but i just find this easier to read and to deal w lol. thx for ur help

updated w the changes thx do u see any ways i can optimize it ? also i never knew u didnt have to null variables when u take them in a function call. y dont u have to null them ?
 
About leak, it's fine now.
About optimization, if you stick with your 2-timers system (which I can understand), I see only one thing to do : use a global for your region "circleOfFlames" and don't create/destroy it every time.
However, there is a bug you must be aware : never put a CreateRegion() in a global declaration bloc. You have to create the region inside the init function (you wouldn't put a CreateUnit in a global bloc, right? That's the same thing here).

deathismyfriend said:
y dont u have to null them ?
I can't tell ^^. It has been tested and it doesn't leak like local variables.
Returning a local variable however leaks.
This leaks :
JASS:
function NewTimer takes nothing returns timer
    local timer t = CreateTimer()
    return t
endfunction
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
ok thts good to know thx and for the region thing r u tlking about this function ?
JASS:
private function winner takes nothing returns nothing
    local integer p = 0
    local region r = CreateRegion()
    call RegionAddRect( r, gg_rct_circleOfFlames)
    loop
        exitwhen p > 5
        if IsUnitInRegion( r, playerUnit) then
            call textall( "Player " + I2S(p+1) + "has won the minigame", p)
            call pauseall( false)
            call DisableTrigger( trg_timer)
        endif
        set p = p + 1
    endloop
    set r = null
endfunction
cause tht function only gets called once.

also i did know about how u cannot createRegions in global block. thx tho
 
Status
Not open for further replies.
Top