Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Rects or Regions leaks

Discussion in 'World Editor Help Zone' started by lelyanra, May 1, 2010.

  1. lelyanra

    lelyanra

    Joined:
    Sep 4, 2007
    Messages:
    380
    Resources:
    25
    Icons:
    25
    Resources:
    25
    Does rects and regions leak? if they do, i have to use RemoveRect() and RemoveRegion()???
     
  2. Crazed_seal2

    Crazed_seal2

    Joined:
    Jan 5, 2009
    Messages:
    825
    Resources:
    2
    Tutorials:
    2
    Resources:
    2
    Only if made via trigger
     
  3. lelyanra

    lelyanra

    Joined:
    Sep 4, 2007
    Messages:
    380
    Resources:
    25
    Icons:
    25
    Resources:
    25
    Ok, requestioning: deos this leaks?
    Code (vJASS):
    private function init takes nothing returns nothing
        local trigger BarTool = CreateTrigger(  )
        local region enterbar = CreateRegion()
        local rect r = Rect(1408.0, 2144.0, 1888.0, 2368.0)
        call RegionAddRect(enterbar, r)
        call TriggerRegisterEnterRegion(BarTool, enterbar, null)
        call TriggerAddCondition( BarTool, Condition( function BarEnter ) )
        call TriggerAddAction( BarTool, function BarEnterNice )
        set BarTool = null
    endfunction
     
  4. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,379
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Yes, it leaks. You should recycle rects because they allocate at least twice the memory leak as locations do. Crazed_seal told you mostly incorrect information. Technically (and I mean strictly technically) regions you click-and-drag in the GUI region editor do not leak, but they still have all the effects of any other leak if you do not remove them.

    The only reason they are not technically a "leak" is because it only leaks if you lose the ability to access that rect to remove it. But if you forget to remove it then you might as well call it a leak.

    Regions absolutely leak.

    Code (vJASS):

     
    globals
        //Recycle TempRect each trigger.  When you do "RegionAddRect" the region permanently
        //remembers the rect so you are free to set TempRect to a new rect each time.
        rect TempRect = Rect(0.,0.,0.,0.)
    endglobals
    private function init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local region r = CreateRegion()
        //notice the native command "SetRect".  this is helpful.
        call SetRect(TempRect,1408., 2144., 1888., 2368.)
        call RegionAddRect(r, TempRect)
        call TriggerRegisterEnterRegion(t, r, null)
        //make sure that you do RemoveRegion(GetTriggeringRegion()), TriggerClearActions(GetTriggeringTrigger()
        //and DestroyTrigger(GetTriggeringTrigger()) when/if you are done with this trigger.
        //if you never destroy the trigger/region, you don't have to set these next two to null:
        set r = null
        set t = null
        //Combine trigger conditions with trigger actions because you're leaking 3 handles
        //per trigger.  This should be:
        call TriggerAddAction(t,function BarEnter)
        //and within function BarEnter you type:
        if(BarEnter Conditions)then
            call BarEnterNice()
        endif
        //That way you only need an action handle per trigger instead of 2 condition handles
        //and an action handle.
    endfunction
     
     
     
     
  5. PurgeandFire

    PurgeandFire

    Code Moderator

    Joined:
    Nov 11, 2006
    Messages:
    7,429
    Resources:
    18
    Icons:
    1
    Spells:
    4
    Tutorials:
    9
    JASS:
    4
    Resources:
    18
    @lelyanra: You should remove the rect.

    @Bribe: Yeah, you can recycle rects, but that is usually only with dynamic triggers. But it is perfectly fine to do so, but just not as necessary since you (except for dynamic triggers) will only create/remove them once. =)

    Actually, it should be trigger actions merged into conditions. ;D For some reasons:
    • For dynamic triggers, you need to manually
      TriggerRemoveAction()
      (and null them, and TriggerClearActions() doesn't help with the handle leak as far as I know) whereas you don't need to remove trigger conditions.
    • You can just use
      TriggerEvaluate()
      which is much faster than
      TriggerExecute()
      . Plus, most systems use:
      Code (vJASS):
      if TriggerEvaluate(t) then
          call TriggerExecute(t)
      endif

      So TriggerEvaluate(t) is more direct. (And then TriggerExecute() is a wasted function call, which is why the functions we use for conditions
      return false
      )
    • There is also something about waits with trig actions and trig conditions. Since you can't wait in trigger conditions, you are forced to use a timer. For dynamic triggers, this is good because if two waits occur after the trigger was destroyed it has a chance to double-free the trigger (something along those lines). This is generally just due to carelessness, since with proper coding this can be avoided even if you are using trigger actions, but it still shows that trigger conditions are a bit safer.

    So it is mostly conditional (lol pun) but using trigger conditions is a generally safer method.
     
  6. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,379
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    If you need to remove
    triggeraction
    , why don't you need to remove
    triggercondition
    ?

    If there are no conditions,
    TriggerEvaluate
    defaults true, anway. And if more people started using
    triggeraction
    instead of
    triggercondition
    then those systems could be updated without the evaluater.

    If using
    TriggerEvaluate
    is faster than
    TriggerExecute
    , is the native event-driven execution of the trigger faster, as well? And wouldn't
    TriggerExecute
    be faster if replaced with
    ExecuteFunc
    ? But this is me thinking rationally, something blizzard clearly skipped on with many of their codes.
     
  7. PurgeandFire

    PurgeandFire

    Code Moderator

    Joined:
    Nov 11, 2006
    Messages:
    7,429
    Resources:
    18
    Icons:
    1
    Spells:
    4
    Tutorials:
    9
    JASS:
    4
    Resources:
    18
    I found the thread that I got my info from. It is this one:
    http://www.thehelper.net/forums/showthread.php?t=149771

    I questioned the same things but I assume it is generally safety issues. But you might want to direct your questions to Jesus4Lyf because I don't know the specifics (I haven't tested it much myself)

    Yeah, but you must always consider that some people might implement it into an old map. =P The systems could also be updated to just use TriggerEvaluate() but they don't since they can't expect everyone to follow the correct format. =)

    The first, I don't know. I've heard people say conditions were generally faster but I am not sure how reliable they are.

    TriggerExecute could be replaced with ExecuteFunc() but people generally lead to not using ExecuteFunc since it is crash-prone if not used correctly. Also, TriggerExecute() factors in multiple actions (lol, for whatever reason) and is useful for systems in general where you don't always know the name of the trigger's actions. =)

    But at least in sc2 they fixed this problem. =D
     
  8. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,379
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    From what I've read about the Galaxy Editor you can't make a timer go below 0.4 or something, so SC2 looks like a game I will never waste money on. If "everything" is "done for you" in the "Data Editor" then I don't see it as an opportunity to improve my understanding of programming and apply total creativity like I can with JASS.
     
  9. Pharaoh_

    Pharaoh_

    Joined:
    Nov 6, 2008
    Messages:
    8,128
    Resources:
    11
    Icons:
    3
    Skins:
    1
    Spells:
    6
    Tutorials:
    1
    Resources:
    11
    A bit off-topic, but still on the point. Bribe, don't underestimate Starcraft's Editor. There is a reason why everyone is in a frenzy state. Just because the Beta were a bit disappointing in some features, it doesn't mean that the final product will be a let-down. Warcraft III might not die, but it can handle 48% of what Galaxy Editor can. It's a must for your modding experience.
     
  10. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,379
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Yeah, I noticed that went offtopic, my bad. To further the offtopic experience, I don't even play this game anymore, I just enjoy coding. So I don't consider myself a modder, I consider myself a programmer. Essentially, there would be no point in doing SC2 if I have so little to gain by typing my own raw codes. I'm not going to waste my time if you can just do it in their GUI system.
     
  11. Pharaoh_

    Pharaoh_

    Joined:
    Nov 6, 2008
    Messages:
    8,128
    Resources:
    11
    Icons:
    3
    Skins:
    1
    Spells:
    6
    Tutorials:
    1
    Resources:
    11
    The good thing is that you will discover things by yourself, things that no one might have come along with before, since the engine is pretty new. In Warcraft III, most likely everything has been discovered. Isn't it better to transfer that experience in something more unique and new?
     
  12. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,379
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    I think I should start a new thread.
     
  13. lelyanra

    lelyanra

    Joined:
    Sep 4, 2007
    Messages:
    380
    Resources:
    25
    Icons:
    25
    Resources:
    25
    this trigger will be used during the entire match, so i should recycle the rect.

    Code (vJASS):
    globals
        rect BarEnter = Rect(0.,0.,0.,0.)
    endglobals

    scope BarEnter initializer init

        private function enter takes nothing returns nothing
            local player p = GetOwningPlayer(GetTriggerUnit())
            call BJDebugMsg("entering: The Drunken Panda tavern")
            call SetLightIndoors(p)
            set p = null
        endfunction
       

        private function cond takes nothing returns boolean
            local integer LoopA = 1

            loop
                exitwhen LoopA > 12
                if GetTriggerUnit() == PlayerHero[LoopA] then
                    if isIndoor[LoopA] == false then
                        call enter()
                        return false
                    endif
                    return false
                endif
                set LoopA = LoopA + 1    
            endloop
            return false
        endfunction

    private function init takes nothing returns nothing
        local trigger BarTool = CreateTrigger(  )
        local region enterbar = CreateRegion()
        call SetRect(BarEnter, 1408., 2200., 1880., 2210.)
        call RegionAddRect(enterbar, BarEnter)
        call TriggerRegisterEnterRegion(BarTool, enterbar, null)
        call TriggerAddCondition( BarTool, Condition( function cond ) )
        set BarTool = null
        set BarEnter = null
    endfunction
    endscope


    so, about this?
     
    Last edited: May 3, 2010
  14. PurgeandFire

    PurgeandFire

    Code Moderator

    Joined:
    Nov 11, 2006
    Messages:
    7,429
    Resources:
    18
    Icons:
    1
    Spells:
    4
    Tutorials:
    9
    JASS:
    4
    Resources:
    18
    If you don't use
    rect BarEnter
    in any other trigger, then you should remove it. ;)
     
  15. lelyanra

    lelyanra

    Joined:
    Sep 4, 2007
    Messages:
    380
    Resources:
    25
    Icons:
    25
    Resources:
    25
    call RemoveRect(r)???? it's a global o_O, i wish i could make it constant, but I can't.
     
  16. PurgeandFire

    PurgeandFire

    Code Moderator

    Joined:
    Nov 11, 2006
    Messages:
    7,429
    Resources:
    18
    Icons:
    1
    Spells:
    4
    Tutorials:
    9
    JASS:
    4
    Resources:
    18
    Add
    call RemoveRect(BarEnter)
    in the Init function after
    RegionAddRect()
    .

    Although, I'm not sure what you are asking. =P
     
  17. PurplePoot

    PurplePoot

    Joined:
    Dec 14, 2005
    Messages:
    11,161
    Resources:
    3
    Maps:
    1
    Spells:
    1
    Tutorials:
    1
    Resources:
    3
    TriggerExecute is slower than TriggerEvaluate, but I assume it is faster than ExecuteFunc. Why? TriggerExecute and ExecuteFunc both make threads, hence they are slower than TriggerEvaluate. ExecuteFunc needs to search the script, hence it is probably slower (barring major fuckups on Blizzard's part) than TriggerExecute.

    --

    You don't need to remove triggerconditions because they don't leak; that's all there is to it.
     
  18. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,379
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Ok, so the code mechanism for registering actions causes a leak because each new code reference is like creating a new code object? I get that once you create a Condition any further attempts to create that condition would just reference the same one you already made, but codes not? That would be problematic for people using timers or
    ForGroup
    calls, wouldn't it?
     
  19. lelyanra

    lelyanra

    Joined:
    Sep 4, 2007
    Messages:
    380
    Resources:
    25
    Icons:
    25
    Resources:
    25
    (i don't mind you going offtopic i benefit from the debate)
     
  20. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,379
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Commented:
    Code (vJASS):

    globals
        rect BarEnter = Rect(0.,0.,0.,0.)
    endglobals
     
    scope BarEnter initializer init
        private function enter takes nothing returns nothing
            local player p = GetTriggerPlayer() //returns the same player as owner of triggering unit.
            call BJDebugMsg("entering: The Drunken Panda tavern")
            call SetLightIndoors(p) //Why are you setting a variable if you're only going to use it once?  Just inline it to SetLightIndoors(GetTriggerPlayer())
            //set p = null <!-- nulling players is a waste of time.  They are never destroyed, so you can have a million pointers to them. -->
        endfunction
     
        private function cond takes nothing returns boolean
            local integer LoopA = 1
            local unit trigUnit = GetTriggerUnit() //don't call GetTriggerUnit() so many times, just make it a variable.
            loop
                //Why do you have the players assigned to 1-12?  It's always easier to zap Player(0) to array[0].
                exitwhen LoopA > 12
                if trigUnit == PlayerHero[LoopA] then
                    if not isIndoor[LoopA] then
                        call enter()
                        //return false <!-- no need for this -->
                    endif
                    exitwhen(true) //return false <!-- don't do a return.  Just exit the loop so that the function can finish and set trigUnit to null. -->
                endif
                set LoopA = LoopA + 1
            endloop
            set trigUnit = null
            return false
        endfunction
     
    private function init takes nothing returns nothing
        local trigger BarTool = CreateTrigger(  )
        local region enterbar = CreateRegion()
        call SetRect(BarEnter, 1408., 2200., 1880., 2210.)
        call RegionAddRect(enterbar, BarEnter)
        call TriggerRegisterEnterRegion(BarTool, enterbar, null)
        call TriggerAddCondition( BarTool, Condition( function cond ) )
        //set BarTool = null <!-- Unless you plan to destroy the trigger, don't set it to null. -->
        //set BarEnter = null <!-- Same as above. If the trigger doesn't need destroying, this region doesn't need nulling. -->
    endfunction
    endscope