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

Memory Leaks Checker v1.6

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
  • Like
Reactions: elm0
Introduction
Sometimes, you make a spell in GUI, when it done, you check leak(s), and check check check until you make sure leakless inside that spell/map, but what happening to you if know very little about Jass/vjass, well when you save map, all trigger converted into jass (most in GUI is JASS/BJs Function).
=> Leaks occur without your knowledge.
Here the solution about that:
System Name
**M E M O R Y L E A K S C H E C K E R**
How it work

This system will check and capturing all leak(s) of your spell/map and return results, or show you where's the leak(s) in your code.
JASS:
"JASS: GetOrderPointLoc/GUI: Target point of issued order"
"JASS: GetSpellTargetLoc/Target point of ability being cast"
"JASS: GroupPickRandomUnit\GUI: Random unit from (Random 4 units from (Units in (Playable map area)))"
"JASS: CreateGroup()/GUI: Automaticaly Create Group)"
"JASS: GetRandomSubGroup(group g)/GUI: (Random 4 units from (Units in (Playable map area)))"
"JASS: CountUnitInGroup(group g)/GUI: (Number of units in (Units in (Playable map area)))"
"JASS: GetRectCenter(rect r)/GUI: Center of (Playable map area)"
"JASS: Location(real x,real y)/GUI: Point(0.00, 0.00))"
"JASS: GetUnitLoc(unit u)/GUI: Position of (Triggering unit)"
"JASS: GetDestructableLoc(destructable d)/GUI: Position of (Last created destructible)"
"JASS: GetItemLoc(item t)/GUI: Position of (Last created item)"
"JASS: GetPlayerStartLocationLoc(player p)/GUI: Player 1 (Red) start location)"
"JASS: ForGroupBJ(group g, code func)/GUI: Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)Loop - Actions"
"JASS: ForGroup(group g, code func)/GUI: None"
"JASS: AddSpecialEffectLocBJ(string m,location loc)/GUI: Special Effect - Create a special effect at (Center of (Playable map area)) using --"
"JASS: AddSpecialEffectLoc(string m,location loc)/GUI: None"
"JASS: AddSpecialEffect(string m,real x,real y)/GUI: None"
"JASS: AddSpecialEffectTargetUnitBJ(string m,real x,real y)/GUI: Special Effect - Create a special effect attached to the overhead of (Triggering unit) using --" 
"JASS: AddSpecialEffectTarget(string m,real x,real y)/GUI: None"
"JASS: ForForce(force f, code func)/GUI: UPlayer Group - Pick every player in (All players) and do (Actions)Loop - Actions"[/HIDDEN]

System test and Screen shot

Map test
untitl63.png

  • Untitled Trigger 001
    • Events
      • Time - Every 0.01 seconds of game time
    • Conditions
    • Actions
      • Set p = (Position of Siege Engine 0022 <gen>)
      • Special Effect - Create a special effect at p using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
      • Special Effect - Destroy (Last created special effect)
      • Unit - Create 1 Footman for Player 1 (Red) at p facing Default building facing degrees
      • Set g = (Units in (Playable map area))
      • Unit Group - Pick every unit in g and do (Actions)
        • Loop - Actions
          • Unit - Kill (Picked unit)
      • Custom script: call DestroyGroup(udg_g)
      • -------- --Improper DestroyGroup-- --------
      • Custom script: call DestroyGroup(udg_g)
      • Custom script: call RemoveLocation(udg_p)
      • -------- --Improper RemoveLocation-- --------
      • Custom script: call RemoveLocation(udg_p)
      • -------- --Improper DestroyForce-- --------
      • Custom script: call DestroyForce(udg_f)
  • [/HIDDEN]
How to remove leak(s)
untit270.jpg


  • Ex Remove Location
    • Events
    • Conditions
    • Actions
      • -------- Follow those steps ;) (Just an example) --------
      • -------- Save a location into variable --------
      • Set p = (Position of (Triggering unit))
      • -------- Use it via this variable --------
      • Unit - Move (Triggering unit) instantly to p
      • -------- After used, remove it, in GUI, you must place udg_ in fronf of the variable (For my example: It's p) --------
      • Custom script: call RemoveLocation(udg_p)
      • -------- Done! --------
  • Ex Destroy Group
    • Events
    • Conditions
    • Actions
      • -------- Follow those steps ;) (Just an example) --------
      • -------- Save a group into variable --------
      • Set g = (Units in (Playable map area))
      • -------- Use it via this variable --------
      • -------- You can use thi line to destroy a group (But unsafer than DestroyGroup tag) --------
      • Custom script: set bj_wantDestroyGroup = true
      • -------- ---------------------------------- --------
      • Unit Group - Pick every unit in g and do (Actions)
        • Loop - Actions
          • Unit - Hide (Picked unit)
      • -------- Or this --------
      • -------- You can use thi line to destroy a group (But unsafer than DestroyGroup tag) --------
      • Custom script: set bj_wantDestroyGroup = true
      • -------- ---------------------------------- --------
      • Unit Group - Pick every unit in g and do (Unit - Hide (Picked unit))
      • -------- After used, destroy it, in GUI, you must place udg_ in fronf of the variable (For my example: It's g) --------
      • -------- If you use: bj_wantDestroyGroup = true tag, you don't need to use DestroyGroup tag --------
      • Custom script: call DestroyGroup(udg_g)
      • -------- Done! --------
  • Ex Destroy Effect
    • Events
    • Conditions
    • Actions
      • -------- Follow those steps ;) (Just an example) --------
      • -------- Create an effect --------
      • Special Effect - Create a special effect attached to the origin of (Triggering unit) using Abilities\Spells\Other\TalkToMe\TalkToMe.mdl
      • -------- Save this effect into variable --------
      • Set e = (Last created special effect)
      • -------- After used, destroy it, in GUI, you must place udg_ in fronf of the variable (For my example: It's e) --------
      • Custom script: call DestroyEffect(udg_e)
      • -------- Or maybe this --------
      • Special Effect - Destroy e
      • -------- Done! --------
  • Ex Destroy Force
    • Events
    • Conditions
    • Actions
      • -------- Follow those steps ;) (Just an example) --------
      • -------- Save a force into variable --------
      • Set f = (All players)
      • -------- Use it via this variable --------
      • Player Group - Pick every player in f and do (Actions)
        • Loop - Actions
          • Player - Set (Picked player) Current gold to 750
      • -------- Or --------
      • Player Group - Pick every player in f and do (Player - Set (Picked player) Current gold to 750)
      • -------- After used, destroy it, in GUI, you must place udg_ in fronf of the variable (For my example: It's f) --------
      • Custom script: call DestroyForce(udg_f)
      • -------- Done! --------
  • Ex Used and Destroy All
    • Events
    • Conditions
    • Actions
      • -------- Follow those steps ;) (Just an example) --------
      • -------- Combine those think at the same time ;) --------
      • -------- Save a location into variable --------
      • Set p = (Position of (Triggering unit))
      • -------- Save a group into variable --------
      • -------- Create a group g, use location p --------
      • Set g = (Units within 500.00 of p)
      • -------- Use group g --------
      • Unit Group - Pick every unit in g and do (Actions)
        • Loop - Actions
          • -------- Create an effect --------
          • Special Effect - Create a special effect attached to the origin of (Picked unit) using Abilities\Spells\Human\Thunderclap\ThunderClapCaster.mdl
          • -------- Destroy it after used --------
          • Special Effect - Destroy (Last created special effect)
          • -------- Save a force into variable --------
          • Set f = (All allies of (Picked player))
          • -------- Use this force f --------
          • Player Group - Pick every player in f and do (Actions)
            • Loop - Actions
              • Player - Add 1000 to (Picked player) Current gold
          • -------- Destroy it after used --------
          • Custom script: call DestroyForce(udg_f)
      • -------- Destroy Group g after used --------
      • Custom script: call DestroyGroup(udg_g)
      • -------- Remove location p after used --------
      • Custom script: call RemoveLocation(udg_p)
      • -------- Done! --------
Leak(s) code founder - Well, Let's do an example about this:

  • Leak Ex
    • Events
      • Time - Elapsed game time is 0.00 seconds
    • Conditions
    • Actions
      • Unit - Move Siege Engine 0022 <gen> instantly to (Center of (Playable map area))
So this is a location leak (Center of (Playable map area)

Let's check the result:

=>

untitl61.png


Well, this system have captured this leak location.

Let's check it via keyword -lf

=>

untitl65.png


Cool hah? ^^!



--
How to import:
- Just copy this trigger Leaks Checker into your map and change the keyword or leave it alone.

How to use:
- Very easy, just -lc, -lf or -fl :D
JASS:
//*********************************************************************************************************************************
//*********************************************************************************************************************************
//*********************************************************************************************************************************
//          L E A K S    C H E C K E R   S Y S T E M
//                                       Version: 1.6
//          Noticed:
//                  - Please read this before using this system -
//                  - This system used for check the leaks of your spells/maps, so, It will capture and saving your data
//                    locations, groups, forces, effects each times functions is called. It will cause laggy on your map if you keep using it for play game.
//                  -----------------------------------------------------------------------------
//                  - REMOVE THIS SYSTEM TO YOUR MAP AFTER USING
//
//          Requires: Jass New Gen Pack
//          System Type: vjass
//          Using for: Check leak(s)/For GUI Users
//
//          By:
//                  - Elphis
//          Keyword:
//                  -lc: When you chat this keyword, system will return all leak(s) that it captured.
//                  -lf: When you chat this keyword, system will show you where's the leak(s) in your code.
//                  -fl: When you chat this keyword, system will show you how to remove leak(s).
//          How it work:
//                      - This system will check and capturing all leak(s) of your spell/map and return results, or show you where's the leak(s) in your code.
//---------------------------------------------------------------------------------------------------------------------------------
//          How to import:
//                        - Just copy this trigger Leaks Checker into your map and change keyword or leave it alone.
//
//*********************************************************************************************************************************
//*********************************************************************************************************************************
//*********************************************************************************************************************************
library LeaksChecker initializer Init
    //
    globals
            //***********************************************SYSTEM CONFIGURATION***********************************************//
        //*********************************************************************************************************************************
        //Use indexing version, if this boolean = true, this system will use indexing to check the leak location
        //if = false, this system will use hashtable to check the leak location
        private             constant                boolean             INDEXING_VERSION                =           true
        //Keyword to run system
        private             constant                string              KEYWORD_LEAKS_CHECKER           =           "-lc"
        //Keyword to check where the leak(s) is
        private             constant                string              KEYWORD_LEAKS_FOUNDER           =           "-lf"
        //Keyword to show how to remove leak(s)
        private             constant                string              KEYWORD_LEAKS_FIX               =           "-fl"
        //Allow reset data when use
        private             constant                boolean             RESET_DATA                      =           false
        //Leaks display period
        private             constant                real                DISPLAY_PERIODIC                =           0.5
        //Player you want to display leak(s)
        private             constant                player              PLAYER_DISPLAY                  =           Player(0)
            //***********************************************NON - CONFIGURATION***********************************************//
        //*********************************************************************************************************************************
        //*********************************************************************************************************************************
        //
        private                                     integer             LocationTotalLeaks              =           0
        //
        private                                     integer             LocationLeaksRemaining          =           0
        //
        private                                     integer             LocationTotalFree               =           0
        //
        private                                     integer             LocatioTotalRemove              =           0
        //
        private                                     integer             UnidentifiedLocation            =           0
        //*********************************************************************************************************************************
        //*********************************************************************************************************************************
        //
        private                                     integer             GroupTotalLeaks                 =           0
        //
        private                                     integer             GroupLeaksRemaining             =           0
        //
        private                                     integer             GroupTotalFree                  =           0
        //
        private                                     integer             GroupTotalRemove                =           0
        //
        //*********************************************************************************************************************************
        //*********************************************************************************************************************************
        private                                     integer             EffectTotalLeaks                =           0
        //
        private                                     integer             Effect_Leaks_Remaining          =           0
        //
        private                                     integer             EffectTotalFree                 =           0
        //
        private                                     integer             EffectTotalRemove               =           0
        //*********************************************************************************************************************************
        //*********************************************************************************************************************************
        private                                     integer             ForceTotalLeaks                 =           0
        //
        private                                     integer             ForceLeaksRemaining             =           0
        //
        private                                     integer             ForceTotalFree                  =           0
        //
        private                                     integer             ForceTotalRemove                =           0
        //*********************************************************************************************************************************
        //*********************************************************************************************************************************
                //***********************************************STRING SYSTEM EDITOR***********************************************//
        //
        private             constant                string              LEAKS_GROUP_UNKNOWN             =           "Total leaks unknown group results: "
        //
        private             constant                string              LEAKS_GROUP_RESULTS             =           "Total leaks group results: "
        //
        private             constant                string              LEAKS_EFFECT_RESULTS            =           "Total leaks effect results: "
        //
        private             constant                string              LEAKS_LOCATION_RESULTS          =           "Total leaks location results: "
        //
        private             constant                string              LEAKS_LOCATION_UNIDENTIFIED     =           "Unidentified location (null handler): "
        //
        private             constant                string              LEAKS_FORCE_RESULTS             =           "Total leaks force results: "
        //*********************************************************************************************************************************
        //*********************************************************************************************************************************
        private             constant                string              LEAKS_GROUP_REMAINING           =           "Total leaks group remaining: "
        //
        private             constant                string              LEAKS_EFFECT_REMAINING          =           "Total leaks effect remaining: "
        //
        private             constant                string              LEAKS_LOCATION_REMAINING        =           "Total leaks location remaining: "
        //
        private             constant                string              LEAKS_FORCE_REMAINING           =           "Total leaks force remaining: "
        //*********************************************************************************************************************************
        //*********************************************************************************************************************************
        private             constant                string              LEAKS_GROUP_CLEANED             =           "Total leaks group cleaned: "
        //
        private             constant                string              LEAKS_EFFECT_CLEANED            =           "Total leaks effect cleaned: "
        //
        private             constant                string              LEAKS_LOCATION_CLEANED          =           "Total leaks location cleaned: "
        //
        private             constant                string              LEAKS_FORCE_CLEANED             =           "Total leaks force cleaned: "
        //*********************************************************************************************************************************
        //*********************************************************************************************************************************
        private             constant                string              LEAKS_GROUP_ERROR               =           "Total leaks group clean improper: "
        //
        private             constant                string              LEAKS_EFFECT_ERROR              =           "Total leaks effect clean improper: "
        //
        private             constant                string              LEAKS_LOCATION_ERROR            =           "Total leaks location clean improper: "
        //
        private             constant                string              LEAKS_FORCE_ERROR               =           "Total leaks force clean improper: "
        //**********************************************************************************************************************************
        private                                     integer             TotalWantDestroy                =           0
        private                                     group      array    GroupCount
        private                                     integer             TotalGroup                      =           0
        //
        private                                     force      array    ForceCount                    
        private                                     integer             TotalForce                      =           0
        //
        private                                     effect      array   EffectCount                    
        private                                     integer             TotalEffect                     =           0
        //
        private             constant                timer               TIMER                           =           CreateTimer()
        private                                     integer             LeaksCounter
        private                                     integer             LeaksDataCounter                =           0
        private                                     integer             TotalLeaksData                  =           0
        private                                     string      array   LeaksFounderAdd
        private                                     string      array   LeaksData[14]
        //
        endglobals
        //
        //***Can't use static if inside globals***
        static if INDEXING_VERSION then
        //
        globals
        //
        private                                     real       array    LocationCount
        private                                     integer             TotalLocation                   =           0
        private                                     integer    array    LocationTag
        //
        endglobals
        //
        else
        //
        globals
        //
        private                                     hashtable           HASH                            =           InitHashtable()
        //
        endglobals
        //
        endif
         //*********************************************************************************************************************************
    //
        //***********************************************Don't touch anything below***********************************************//
    //
    private function RemoveData takes string s returns nothing
        local integer i = 1
        //
        loop
            exitwhen i > LeaksDataCounter
            if LeaksFounderAdd[i] == s then
                set LeaksFounderAdd[i] = LeaksFounderAdd[LeaksDataCounter]
                set LeaksFounderAdd[LeaksDataCounter] = null
                set LeaksDataCounter = LeaksDataCounter - 1
            endif
            set i = i + 1
        endloop
        //
    endfunction
    //
    private function GetUnitLocDetector takes unit u returns nothing
        static if not INDEXING_VERSION then
            local integer w
        endif
        if u == null then
            set UnidentifiedLocation = UnidentifiedLocation + 1
        else
            set LeaksDataCounter =LeaksDataCounter + 1
            set LeaksFounderAdd[LeaksDataCounter] = LeaksData[6]
            set LocationTotalLeaks = LocationTotalLeaks + 1
            set LocationLeaksRemaining = LocationLeaksRemaining + 1
            static if INDEXING_VERSION then
            set LocationCount[TotalLocation] = GetWidgetX(u)
            set LocationTag[TotalLocation] = 6
            set TotalLocation = TotalLocation + 1
            else
            set w = R2I(GetWidgetX(u))
            call SaveBoolean(HASH,1,w,true)
            call SaveInteger(HASH,2,w,6)
            endif
        endif
    endfunction
    //
    hook GetUnitLoc GetUnitLocDetector
    //
    private function RemoveLocationDetector takes location loc returns nothing
        local boolean c = false
        static if INDEXING_VERSION then
        local real r = GetLocationX(loc)
        local integer i = TotalLocation
        local integer tag
        else
        local integer w
        endif
        static if INDEXING_VERSION then
        loop
            exitwhen i < 0
            if r == LocationCount[i] and LocationCount[i] != 0. then
                set c = true
                set tag = LocationTag[i]
                set LocationCount[i] = LocationCount[TotalLocation]
                set LocationCount[TotalLocation] = -1.
                set TotalLocation = TotalLocation - 1
                exitwhen true
            endif
            set i = i - 1
        endloop
        else
        set w = R2I(GetLocationX(loc)
        if LoadBoolean(HASH,1,w) then
            set c = true
            call RemoveSavedHandle(HASH,1,w)
            call RemoveData(LoadInteger(HASH,2,w)
            call RemoveSavedHandle(HASH,2,w)
        endif
        endif
        if loc == null or not c then
            set LocationTotalFree = LocationTotalFree + 1
        elseif c then
            call RemoveData(LeaksData[tag])
            set LocationLeaksRemaining = LocationLeaksRemaining - 1
            set LocatioTotalRemove = LocatioTotalRemove + 1
        endif
    endfunction
    //
    hook RemoveLocation RemoveLocationDetector
    //
    private function GetOrderPointLocDetector takes nothing returns nothing
        static if not INDEXING_VERSION then
            local integer w
        endif
        set LocationTotalLeaks = LocationTotalLeaks + 1
        set LocationLeaksRemaining = LocationLeaksRemaining + 1
        set LeaksDataCounter =LeaksDataCounter + 1
        set LeaksFounderAdd[LeaksDataCounter] = LeaksData[14]
        static if INDEXING_VERSION then
        set LocationCount[TotalLocation] = GetOrderPointX()
        set LocationTag[TotalLocation] = 14
        set TotalLocation = TotalLocation + 1
        else
        set w = R2I(GetOrderPointX())
        call SaveBoolean(HASH,1,w,true)
        call SaveInteger(HASH,2,w,14)
        endif
    endfunction
    //
    hook GetOrderPointLoc GetOrderPointLocDetector
    //
    private function GetSpellTargetLocDetector takes nothing returns nothing
        static if not INDEXING_VERSION then
            local integer w
        endif
        set LocationTotalLeaks = LocationTotalLeaks + 1
        set LocationLeaksRemaining = LocationLeaksRemaining + 1
        set LeaksDataCounter =LeaksDataCounter + 1
        set LeaksFounderAdd[LeaksDataCounter] = LeaksData[13]
        static if INDEXING_VERSION then
        set LocationCount[TotalLocation] = GetSpellTargetX()
        set LocationTag[TotalLocation] = 13
        set TotalLocation = TotalLocation + 1
        else
        set w = R2I(GetSpellTargetX())
        call SaveBoolean(HASH,1,w,true)
        call SaveInteger(HASH,2,w,13)
        endif
    endfunction
    //
    hook GetSpellTargetLoc GetSpellTargetLocDetector
    //
    private function LocationDetector takes real x,real y returns nothing
        static if not INDEXING_VERSION then
            local integer w
        endif
        set LocationTotalLeaks = LocationTotalLeaks + 1
        set LocationLeaksRemaining = LocationLeaksRemaining + 1
        set LeaksDataCounter =LeaksDataCounter + 1
        set LeaksFounderAdd[LeaksDataCounter] = LeaksData[5]
        static if INDEXING_VERSION then
        set LocationCount[TotalLocation] = x
        set LocationTag[TotalLocation] = 5
        set TotalLocation = TotalLocation + 1
        else
        set w = R2I(x)
        call SaveBoolean(HASH,1,w,true)
        call SaveInteger(HASH,2,w,5)
        endif
    endfunction
    //
    hook Location LocationDetector
    //
    private function GetRectCenterDetector takes rect r returns nothing
        static if not INDEXING_VERSION then
            local integer w
        endif
        if r == null then
            set UnidentifiedLocation = UnidentifiedLocation + 1
        else
            set LocationTotalLeaks = LocationTotalLeaks + 1
            set LocationLeaksRemaining = LocationLeaksRemaining + 1
            set LeaksDataCounter =LeaksDataCounter + 1
            set LeaksFounderAdd[LeaksDataCounter] = LeaksData[4]
            static if INDEXING_VERSION then
            set LocationCount[TotalLocation] = GetRectCenterX(r)
            set LocationTag[TotalLocation] = 4
            set TotalLocation = TotalLocation + 1
            else
            set w = R2I(GetRectCenterX(r))
            call SaveBoolean(HASH,1,w,true)
            call SaveInteger(HASH,2,w,4)
            endif
        endif
    endfunction
    //
    hook GetRectCenter GetRectCenterDetector
    //
    private function GetDestructableLocDetector takes destructable d returns nothing
        static if not INDEXING_VERSION then
            local integer w
        endif
        if d == null then
            set UnidentifiedLocation = UnidentifiedLocation + 1
        else
            set LocationTotalLeaks = LocationTotalLeaks + 1
            set LocationLeaksRemaining = LocationLeaksRemaining + 1
            set LeaksDataCounter =LeaksDataCounter + 1
            set LeaksFounderAdd[LeaksDataCounter] = LeaksData[7]
            static if INDEXING_VERSION then
            set LocationCount[TotalLocation] = GetWidgetX(d)
            set LocationTag[TotalLocation] = 7
            set TotalLocation = TotalLocation + 1
            else
            set w = R2I(GetWidgetX(d))
            call SaveBoolean(HASH,1,w,true)
            call SaveInteger(HASH,2,w,7)
            endif
        endif
    endfunction
    //
    hook GetDestructableLoc GetDestructableLocDetector
    //
    private function GetItemLocDetector takes item t returns nothing
        static if not INDEXING_VERSION then
            local integer w
        endif
        if t == null then
            set UnidentifiedLocation = UnidentifiedLocation + 1
        else
            set LocationTotalLeaks = LocationTotalLeaks + 1
            set LocationLeaksRemaining = LocationLeaksRemaining + 1
            set LeaksDataCounter =LeaksDataCounter + 1
            set LeaksFounderAdd[LeaksDataCounter] = LeaksData[8]
            static if INDEXING_VERSION then
            set LocationCount[TotalLocation] = GetWidgetX(t)
            set LocationTag[TotalLocation] = 8
            set TotalLocation = TotalLocation + 1
            else
            set w = R2I(GetWidgetX(t))
            call SaveBoolean(HASH,1,w,true)
            call SaveInteger(HASH,2,w,8)
            endif
        endif
    endfunction
    //
    hook GetItemLoc GetItemLocDetector
    //
    private function GetPlayerStartLocationLocDetector takes player p returns nothing
        static if not INDEXING_VERSION then
            local integer w
        endif
        if p == null then
            set UnidentifiedLocation = UnidentifiedLocation + 1
        else
            set LocationTotalLeaks = LocationTotalLeaks + 1
            set LocationLeaksRemaining = LocationLeaksRemaining + 1
            set LeaksDataCounter =LeaksDataCounter + 1
            set LeaksFounderAdd[LeaksDataCounter] = LeaksData[9]
            static if INDEXING_VERSION then
            set LocationCount[TotalLocation] = GetStartLocationX(GetPlayerId(p))
            set LocationTag[TotalLocation] = 9
            set TotalLocation = TotalLocation + 1
            else
            set w = R2I(GetStartLocationX(GetPlayerId(p)))
            call SaveBoolean(HASH,1,w,true)
            call SaveInteger(HASH,2,w,9)
            endif
        endif
    endfunction
    //
    hook GetPlayerStartLocationLoc GetPlayerStartLocationLocDetector
    //
    private function GroupPickRandomUnitDetector takes group g returns nothing
        set LeaksDataCounter =LeaksDataCounter + 1
        set LeaksFounderAdd[LeaksDataCounter] = LeaksData[1]
        set GroupTotalLeaks = GroupTotalLeaks + 1
        set GroupLeaksRemaining = GroupLeaksRemaining + 1
        set GroupCount[TotalGroup] = g
        set TotalGroup = TotalGroup + 1
    endfunction
    //
    hook GroupPickRandomUnit GroupPickRandomUnitDetector
    //
    private function GetRandomSubGroupDetector takes integer i, group g returns nothing
        set LeaksDataCounter =LeaksDataCounter + 1
            set LeaksFounderAdd[LeaksDataCounter] = LeaksData[2]
        set GroupTotalLeaks = GroupTotalLeaks + 1
        set GroupLeaksRemaining = GroupLeaksRemaining + 1
        set GroupCount[TotalGroup] = g
        set TotalGroup = TotalGroup + 1
    endfunction
    //
    hook GetRandomSubGroup GetRandomSubGroupDetector
    //
    private function ForGroupDetector takes group g, code func returns nothing
        set LeaksDataCounter =LeaksDataCounter + 1
        set LeaksFounderAdd[LeaksDataCounter] = LeaksData[10]
        set GroupCount[TotalGroup] = g
        set TotalGroup = TotalGroup + 1
        set GroupLeaksRemaining = GroupLeaksRemaining + 1
        set GroupTotalLeaks = GroupTotalLeaks + 1
        //
        if bj_wantDestroyGroup then
            set TotalWantDestroy = TotalWantDestroy + 1
        endif
        //
    endfunction
    //
    hook ForGroup ForGroupDetector
    hook ForGroupBJ ForGroupDetector
    //
    private function CountUnitsInGroupDetector takes group g returns nothing
        set TotalGroup = TotalGroup - 1
        set GroupLeaksRemaining = GroupLeaksRemaining - 1
    endfunction
    //
    hook CountUnitsInGroup CountUnitsInGroupDetector
    //
    private function DestroyGroupDetector takes group g returns nothing
        local integer i = TotalGroup
        local boolean c = false
        loop
            exitwhen i < 0
            if g == GroupCount[i] and GroupCount[i] != null then
                set c = true
                set GroupCount[i] = GroupCount[TotalGroup]
                set GroupCount[TotalGroup] = null
                set TotalGroup = TotalGroup - 1
                exitwhen true
            endif
            set i = i - 1
        endloop
        if g == null or not c then
            set GroupTotalFree = GroupTotalFree + 1
        elseif c then
            call RemoveData(LeaksData[10])
            set GroupTotalRemove = GroupTotalRemove + 1
            set GroupLeaksRemaining = GroupLeaksRemaining - 1
        endif
    endfunction
    //
    hook DestroyGroup DestroyGroupDetector
    //
    private function AddSpecialEffectLocBJDetector takes location loc, string path returns nothing
        set LeaksDataCounter =LeaksDataCounter + 1
        set LeaksFounderAdd[LeaksDataCounter] = LeaksData[11]
        set EffectTotalLeaks = EffectTotalLeaks + 1
        set Effect_Leaks_Remaining = Effect_Leaks_Remaining + 1
    endfunction
    //
    hook AddSpecialEffectLocBJ AddSpecialEffectLocBJDetector
    //
    private function AddSpecialEffectLocDetector takes string path, location loc returns nothing
        set EffectTotalLeaks = EffectTotalLeaks + 1
        set Effect_Leaks_Remaining = Effect_Leaks_Remaining + 1
    endfunction
    //
    hook AddSpecialEffectLoc AddSpecialEffectLocDetector
    //
    private function AddSpecialEffectDetector takes string path, real x, real y returns nothing
        set EffectTotalLeaks = EffectTotalLeaks + 1
        set Effect_Leaks_Remaining = Effect_Leaks_Remaining + 1
    endfunction
    //
    hook AddSpecialEffect AddSpecialEffectDetector
    //
    private function AddSpecialEffectTargetDetector takes string path, widget Widget, string attachment returns nothing
        set EffectTotalLeaks = EffectTotalLeaks + 1
        set Effect_Leaks_Remaining = Effect_Leaks_Remaining + 1
    endfunction
    //
    hook AddSpecialEffectTarget AddSpecialEffectTargetDetector
    //
    private function AddSpecialEffectTargetUnitBJDetector takes string path, widget Widget, string attachment returns nothing
        set LeaksDataCounter =LeaksDataCounter + 1
        set EffectTotalLeaks = EffectTotalLeaks + 1
        set Effect_Leaks_Remaining = Effect_Leaks_Remaining + 1
    endfunction
    //
    hook AddSpecialEffectTargetUnitBJ AddSpecialEffectTargetUnitBJDetector
    //
    private function DestroyEffectBJDetector takes effect e returns nothing
        local integer i = 0
        
        loop
            exitwhen i > TotalEffect
            
            if EffectCount[i] == e then
                set EffectTotalFree = EffectTotalFree + 1
                return
            endif
            
            set i = i + 1
        endloop
        
        if e != null then
            call RemoveData(LeaksData[11])
            set Effect_Leaks_Remaining = Effect_Leaks_Remaining - 1
            set EffectTotalRemove = EffectTotalRemove + 1
            set EffectCount[TotalEffect] = e
            set TotalEffect = TotalEffect + 1
        else
            set EffectTotalFree = EffectTotalFree + 1
        endif
        
    endfunction
    //
    hook DestroyEffectBJ DestroyEffectBJDetector
    hook DestroyEffect DestroyEffectBJDetector
    //
    private function DestroyForceDetector takes force f returns nothing
        local integer i = TotalForce
        local boolean c = false
        loop
            exitwhen i < 0
            if f == ForceCount[i] and ForceCount[i] != null then
                set c = true
                set ForceCount[i] = ForceCount[TotalForce]
                set ForceCount[TotalForce] = null
                set TotalForce = TotalForce - 1
                exitwhen true
            endif
            set i = i - 1
        endloop
        if f == null or not c then
            set ForceTotalFree = ForceTotalFree + 1
        elseif c then
            call RemoveData(LeaksData[12])
            set ForceLeaksRemaining = ForceLeaksRemaining - 1
            set ForceTotalRemove = ForceTotalRemove + 1
        endif
    endfunction
    //
    hook DestroyForce DestroyForceDetector
    //
    private function ForForceDetector takes force f,code func returns nothing
        set LeaksDataCounter =LeaksDataCounter + 1
        set LeaksFounderAdd[LeaksDataCounter] = LeaksData[12]
        set ForceTotalLeaks = ForceTotalLeaks + 1
        set ForceLeaksRemaining = ForceLeaksRemaining + 1
        set ForceCount[TotalForce] = f
        set TotalForce = TotalForce + 1
    endfunction
    //
    hook ForForce ForForceDetector
    //This function display total leaks in your Spell/Map
    private function Leaks_Checker_Action takes nothing returns boolean
        local player p = GetTriggerPlayer()
        //
        call DisplayTextToPlayer(p,0,0,LEAKS_GROUP_RESULTS+I2S(GroupTotalLeaks))
        call DisplayTextToPlayer(p,0,0,LEAKS_EFFECT_RESULTS+I2S(EffectTotalLeaks))
        call DisplayTextToPlayer(p,0,0,LEAKS_FORCE_RESULTS+I2S(ForceTotalLeaks))
        call DisplayTextToPlayer(p,0,0,LEAKS_LOCATION_RESULTS+I2S(LocationTotalLeaks)+"/"+LEAKS_LOCATION_UNIDENTIFIED+I2S(UnidentifiedLocation))
        //
        call DisplayTextToPlayer(p,0,0,LEAKS_FORCE_REMAINING+I2S(ForceLeaksRemaining))
        call DisplayTextToPlayer(p,0,0,LEAKS_GROUP_REMAINING+I2S(GroupLeaksRemaining))
        call DisplayTextToPlayer(p,0,0,LEAKS_EFFECT_REMAINING+I2S(Effect_Leaks_Remaining))
        call DisplayTextToPlayer(p,0,0,LEAKS_LOCATION_REMAINING+I2S(LocationLeaksRemaining))
        //
        call DisplayTextToPlayer(p,0,0,LEAKS_FORCE_CLEANED+I2S(ForceTotalRemove))
        call DisplayTextToPlayer(p,0,0,LEAKS_GROUP_CLEANED+I2S(GroupTotalRemove)+"/bj_wantDestroyGroup used: "+I2S(TotalWantDestroy))
        call DisplayTextToPlayer(p,0,0,LEAKS_EFFECT_CLEANED+I2S(EffectTotalRemove))
        call DisplayTextToPlayer(p,0,0,LEAKS_LOCATION_CLEANED+I2S(LocatioTotalRemove))
        //
        call DisplayTextToPlayer(p,0,0,LEAKS_FORCE_ERROR+I2S(ForceTotalFree))
        call DisplayTextToPlayer(p,0,0,LEAKS_GROUP_ERROR+I2S(GroupTotalFree))
        call DisplayTextToPlayer(p,0,0,LEAKS_EFFECT_ERROR+I2S(EffectTotalFree))
        call DisplayTextToPlayer(p,0,0,LEAKS_LOCATION_ERROR+I2S(LocationTotalFree))
        //
        static if RESET_DATA then
            //Reset data to default
            static if not INDEXING_VERSION then
                call FlushChildHashtable(HASH,1)
            endif
            set UnidentifiedLocation = 0
            set TotalWantDestroy = 0
            set TotalForce = 0
            set TotalGroup = 0
            set GroupTotalLeaks = 0
            set EffectTotalLeaks = 0
            set ForceTotalLeaks = 0
            set LocationTotalLeaks = 0
            set ForceTotalFree = 0
            set EffectTotalFree = 0
            set LocationTotalFree = 0
            set GroupTotalFree = 0
            set LocatioTotalRemove = 0
            set EffectTotalRemove = 0
            set GroupTotalRemove = 0
            set ForceTotalRemove = 0
            set Effect_Leaks_Remaining = 0
            set GroupLeaksRemaining = 0
            set ForceLeaksRemaining = 0
            set LocationLeaksRemaining = 0
        endif
        //
        set p = null
        //
        return false
    endfunction
    //
    private function LeaksDisplay takes nothing returns nothing
        local integer i = 0
        local integer counter = 0
        
        if LeaksCounter < TotalLeaksData then
            set LeaksCounter = LeaksCounter + 1
            
            loop
                exitwhen i > LeaksDataCounter
                if LeaksFounderAdd[i] == LeaksData[LeaksCounter] then
                    set counter = counter + 1
                endif
                set i = i + 1
            endloop
            
            if counter > 0 then
                call DisplayTextToPlayer(PLAYER_DISPLAY,0.,0.,"Leak(s) tag found: "+LeaksData[LeaksCounter]+" - Leak(s) tag count: |cffFFFF00"+I2S(counter)+"|r")
            endif
        else
            call PauseTimer(TIMER)
        endif
    endfunction
    //
    private function Leaks_Founder_Action takes nothing returns boolean
        set LeaksCounter = 0
        if GetLocalPlayer() == PLAYER_DISPLAY then
            call ClearTextMessages()
        endif
        if LeaksDataCounter > 0 then
            call DisplayTextToPlayer(PLAYER_DISPLAY,0.,0.,"Check leak(s) list below :), you might know where's the leak(s) in your spell/map (|cffCC0000GUI Tags Only|r)")
            call TimerStart(TIMER,DISPLAY_PERIODIC,true,function LeaksDisplay)
        else
            call DisplayTextToPlayer(PLAYER_DISPLAY,0.,0.,"Leakless in this time !!")
        endif
        return false
    endfunction
    //
    private function Leaks_Fix_Action takes nothing returns boolean
        local player p = GetTriggerPlayer()
        if GetLocalPlayer() == p then
            call ClearTextMessages()
        endif
        call DisplayTextToPlayer(p,0.,0.,"For Leak(s) location: \n To remove it: Use |cffFF33FFRemoveLocation(|cffFFFF66whichLocation|r|cffFF33FF)|r tag.")
        call DisplayTextToPlayer(p,0.,0.,"For Leak(s) group: \n To remove it: Use |cffFF33FFDestroyGroup(|cffFFFF66whichGroup|r|cffFF33FF)|r tag.")
        call DisplayTextToPlayer(p,0.,0.,"For Leak(s) effect: \n To remove it: Use |cffFF33FFDestroyEffect(|cffFFFF66whichEffect|r|cffFF33FF)|r tag.")
        call DisplayTextToPlayer(p,0.,0.,"For Leak(s) force: \n To remove it: Use |cffFF33FFDestroyForce(|cffFFFF66whichForce|r|cffFF33FF)|r tag.")
        call DisplayTextToPlayer(p,0.,0.,"|cff00CC66You can see example about those things in the |cffFFFF00Leaks Destroy Ex|r folder (Open this map in the world editor)")
        return false
    endfunction
    //
    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local trigger lf = CreateTrigger()
        local trigger fl = CreateTrigger()
        local integer i = bj_MAX_PLAYERS
        //
        loop
            exitwhen i < 0
            call TriggerRegisterPlayerChatEvent(t,Player(i),KEYWORD_LEAKS_CHECKER,true)
            call TriggerRegisterPlayerChatEvent(lf,Player(i),KEYWORD_LEAKS_FOUNDER,true)
            call TriggerRegisterPlayerChatEvent(fl,Player(i),KEYWORD_LEAKS_FIX,true)
            set i = i - 1
        endloop
        //
        call TriggerAddCondition(t,function Leaks_Checker_Action)
        call TriggerAddCondition(lf,function Leaks_Founder_Action)
        call TriggerAddCondition(fl,function Leaks_Fix_Action)
        //
        set i = 1
        //1
        set LeaksData[i] = "Jass: GroupPickRandomUnit/GUI: Random unit from (Random <|cffFFFF00?|r> units from (Units in <|cffFFFF00Rect|r>))"
        set i = i + 1
        //2
        set LeaksData[i] = "Jass: GetRandomSubGroup/GUI: (Random <|cffFFFF00?|r> units from (Units in Rect|r>)))"
        set i = i + 1
        //3
        set LeaksData[i] = "Jass: CountUnitInGroup/GUI: (Number of units in (Units in <|cffFFFF00Rect|r>))"
        set i = i + 1
        //4
        set LeaksData[i] = "Jass: GetRectCenter/GUI: Center of <|cffFFFF00Rect|r>"
        set i = i + 1
        //5
        set LeaksData[i] = "Jass: Location/GUI: Point(<|cffFFFF00Real|r>, <|cffFFFF00Real|r>))"
        set i = i + 1
        //6
        set LeaksData[i] = "Jass: GetUnitLoc/GUI: Position of <|cffFFFF00Unit|r>)"
        set i = i + 1
        //7
        set LeaksData[i] = "Jass: GetDestructableLoc/GUI: Position of <|cffFFFF00Destructable|r>)"
        set i = i + 1
        //8
        set LeaksData[i] = "Jass: GetItemLoc/GUI: Position of <|cffFFFF00Item|r>"
        set i = i + 1
        //9
        set LeaksData[i] = "Jass: GetPlayerStartLocationLoc/GUI: <|cffFFFF00Player|r> (<|cffFFFF00Color|r>) start location)"
        set i = i + 1
        //10
        set LeaksData[i] = "Jass: ForGroupBJ/GUI: Unit Group - Pick every unit in (Units in <|cffFFFF00Rect|r>) and do (Actions)Loop - Actions"
        set i = i + 1
        //11
        set LeaksData[i] = "Jass: AddSpecialEffectLocBJ/GUI: Special Effect - Create a special effect at (<|cff33CC33Location|r>) using --"
        set i = i + 1
        //12
        set LeaksData[i] = "Jass: ForForce/GUI: UPlayer Group - Pick every player in (<|cffFFFF00Force|r>) and do (Actions)Loop - Actions"
        set i = i + 1
        //13
        set LeaksData[i] = "Jass: GetSpellTargetLoc/GUI: Target point of ability being cast"
        set i = i + 1
        //14
        set LeaksData[i] = "Jass: GetOrderPointLoc/GUI: Target point of issued order"
        //
        set TotalLeaksData = i
        //
        set t = null
    endfunction
    //
endlibrary
v1.0: First release version.
v1.0: First release version.
v1.1: Adding some code.
v1.2: Fixed some bugs, and add new code.
v1.3: Lagg fixed.
v1.4: Add hashtable version to location leaks.
v1.5: v1.5: Bugs fixed, effects checker updated, add GroupPickRandomUnit in capture list.
v.15b: Minor bugs fixed.
v1.6: Bugs fixed, now you can know where's the leak(s) in your code, add "How to remove leak(s)" with some example, minor changes.


Keywords:
memory,leak,checker,capture
Contents

Memory leaks checker (Map)

Reviews
KILLCIDE
Due to many reports of this system reporting incorrect leaks, I've decided to move this submission to Substandard. I recommend people learn how to find leaks themselves using many of the useful tutorials in the website (Memory Leaks).

Moderator

M

Moderator

12:03, 6th Dec 2013
Maker: This system can be useful but I still recommend learning
to check leaks yourself
 
Level 7
Joined
Apr 12, 2011
Messages
124
If it can't check
JASS:
bj_wantDestroyGroup = true
does that also mean it can't check
JASS:
call RemoveLocation(udg_Point)
and the likes either or just that single line?

EDIT: I couldn't get it to work when importing it gave me a bunch of errors, this could be my issue only though since I've never imported a jass trigger before. I'm using standard Wc3 World Editor if Jass requires something specific.
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
This is not JASS
This is vJass

Please name the systems correctly.

In your how to import please note that they need JNGP as this is vJass.

You are naming your variables wrong.
ThisIsForFunctionNames
thisIsForMethodNames
ThisIsForStructNames
thisIsForGlobalVariables
thisIsForLocalVariables
THIS_IS_FOR_CONSTANT_VARIABLES
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
Cool, counts leaks. Will you include a garbage collector for GUI next update? that would be great. Sorry that was a stupid suggestion lol.
 
Level 9
Joined
Dec 12, 2007
Messages
489
I'm wondering about one thing,

this requires JNGP while most GUI user aren't using JNGP after all and those who use JNGP probably using vJASS or at least JASS. aside from that, this thing is good for GUI user, but can you tell me what does yours do that different with this, both are designed for GUI users, require JNGP, and working with leaks.

btw, from your screenshot, mind if you explain what is the meaning of "result", "remaining", "cleaned", "improper"?

how come total leak result = 66, leak cleaned = 131, and remaining leak = -65? there are 66 leak and you clean 131, probably your system interfere with other used variables.

also, I suggest you to only display those message during debug mode.

JASS:
    private function ForGroupBJDetector takes group g,code c returns nothing
        set GROUP_TOTAL_LEAKS = GROUP_TOTAL_LEAKS + 1
        set GROUP_LEAKS_REMAINING = GROUP_LEAKS_REMAINING + 1
    endfunction
    //
    hook ForGroupBJ ForGroupBJDetector
    //
    private function ForGroupDetector takes group g,code c returns nothing
        set GROUP_TOTAL_LEAKS = GROUP_TOTAL_LEAKS + 1
        set GROUP_LEAKS_REMAINING = GROUP_LEAKS_REMAINING + 1
    endfunction
    //
    hook ForGroup ForGroupBJDetector
    //
function ForGroupDetector is not used
 
Last edited:
Level 16
Joined
Jul 31, 2012
Messages
2,217

Personal Words

Review

Suggestions

Rating

Judgement

Note

COOL
You need to specify that it's vJASS and not JASS
You should do like this for example:
Total Effect Leaks = effects remaining - cleaned
Anyway, my KB3D System is leakless lol xD

You should do like this for example:
Total Effect Leaks = effects remaining - cleaned
225233-albums6523-picture74071.jpg
225233-albums6523-picture74103.jpg
If You want me to review an Update of This Spell, Please Notifiy me this by VM or PM
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
The best usage of this VS Leak Destroyer is that this one trains user knowledge and make them learn more about leaks, which I really supports.

Yes that is the good part.
Don't make this so it cleans the leak. Just so it's a leak detector. It is nice.
You should hook some functions for jassers though.
Jassers shouldn't need it but i guess it is good to have it for them also.
 
I'm wondering about one thing,

this requires JNGP while most GUI user aren't using JNGP after all and those who use JNGP probably using vJASS or at least JASS. aside from that, this thing is good for GUI user, but can you tell me what does yours do that different with this, both are designed for GUI users, require JNGP, and working with leaks.

btw, from your screenshot, mind if you explain what is the meaning of "result", "remaining", "cleaned", "improper"?

how come total leak result = 66, leak cleaned = 131, and remaining leak = -65? there are 66 leak and you clean 131, probably your system interfere with other used variables.

also, I suggest you to only display those message during debug mode.

JASS:
    private function ForGroupBJDetector takes group g,code c returns nothing
        set GROUP_TOTAL_LEAKS = GROUP_TOTAL_LEAKS + 1
        set GROUP_LEAKS_REMAINING = GROUP_LEAKS_REMAINING + 1
    endfunction
    //
    hook ForGroupBJ ForGroupBJDetector
    //
    private function ForGroupDetector takes group g,code c returns nothing
        set GROUP_TOTAL_LEAKS = GROUP_TOTAL_LEAKS + 1
        set GROUP_LEAKS_REMAINING = GROUP_LEAKS_REMAINING + 1
    endfunction
    //
    hook ForGroup ForGroupBJDetector
    //
function ForGroupDetector is not used

Only display text when you type -lc, i think it's good for some reason.
Let's take a look here:
result: 1 + 1 = 2, the result is: 2
"there are 66 leak and you clean 131", Yup, Rheiko destroy/remove leak too much, remove it > set it, haha
remaining: If you have two candy, you eat one, candy remaining is: one
cleaned: Well, when you RemoveLocation/DestroyGroup/DestroyForce/DestroyEffect, leak(s) clean + 1, it's just a total those function is called.
improper: When you destroy a null varriable.
--
I don't think Automatic Leak Destroyer is good, if the author use hook for capture, well, it okay but if use it for destroy the leak, i think it impossible.
Vexorian said:
There are functions that are outside of our control most of the times, like natives and those in blizzard.j. The hook keyword allows us to detect them.

Use hook, the name of the native/bj function and the name of a function or static method and you will be able to detect when that native is called and also capture the arguments given to it.

The arguments hook just same with arguments of that function.

It's just a first version, system running not good as well, but i'll update it as soon as possible.

@Death: Yup, i'll update it :)
 
Last edited:
Level 9
Joined
Dec 12, 2007
Messages
489
"there are 66 leak and you clean 131", Yup, Rheiko destroy/remove leak too much, remove it > set it, haha
remaining: If you have two candy, you eat one, candy remaining is: one
cleaned: Well, when you RemoveLocation/DestroyGroup/DestroyForce/DestroyEffect, leak(s) clean + 1, it's just a total those function is called.
improper: When you destroy a null varriable.
so this can be summarized into: count how many times handle created through each function hook, then count how many times the destroy & remove handle is called, wouldn't it report the wrong value if the user is put destroy on wrong handle or in case of double-destroy?

look at this post of yours and compare it with the trigger itself, I do find the result is different from the expected result. it has at least 33 group leak per second yet yours record 0 group leak.
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
Maybe you should change the label leaking to using so as to not confuse the potential users.
 
Level 13
Joined
Mar 29, 2012
Messages
530
bj_wantDestroyGroup = true is still can be used, right?
When it's 'true' and we pick a unit group using ForGroupBJ that contain:
JASS:
function ForGroupBJ takes group whichGroup, code callback returns nothing
    // If the user wants the group destroyed, remember that fact and clear
    // the flag, in case it is used again in the callback.
    local boolean wantDestroy = bj_wantDestroyGroup
    set bj_wantDestroyGroup = false

    call ForGroup(whichGroup, callback)

    // If the user wants the group destroyed, do so now.
    if (wantDestroy) then
        call DestroyGroup(whichGroup)
    endif
endfunction
 
It will also report wrong results if those locations are used throughout the whole map.
Example: I create a location array for spawn locations for each player called spawnLoc[Players 1 to 12]
If i use them throughout the whole game they do not leak but the leak detector will show them as leaking.

I don't think so, when you use location/group or force, your map/my system show them as leaking because it's leak even you use it thoughout the game

@mana: just requires JNGP and i add it already :).

@Ofe: Yup but my system can't check bj_wantDestroyGroup even it = true or false but that group still destroyed :) if = true
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
I don't think so, when you use location/group or force, your map/my system show them as leaking because it's leak even you use it throughout the game
It's not a leak since it can be manipulated and is still useful. Leaks are data occupying memory that cannot be returned to the system. If the object is to be used throughout the game then it's not a leak.

The more appropriate term is memory usage.

EDIT: clarified my last sentence on the first paragraph.
 
It's not a leak since it can be manipulated and is still useful. Leaks are data occupying memory that cannot be returned to the system, if it's used throughout the game then it's not a leak.

The more appropriate term is memory usage.

Hmm, but it was created and it still occupies ram, more like that still lag the game, right?
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
Yes, but that doesn't mean it's leaking memory. It needs to be placed in memory to be used.

Your analogy is wrong, if we follow your analysis, then everything in memory is a leak, we might as well not use memory (since programs needs to use memory), or the computer.
 
Yes, but that doesn't mean it's leaking memory. It needs to be placed in memory to be used.

Your analogy is wrong, if we follow your analysis, then everything in memory is a leak, we might as well not use memory (since programs needs to use memory), or the computer.

Okay, i get it, i'll try to fix it, thanks a lot. :)
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
I don't think so, when you use location/group or force, your map/my system show them as leaking because it's leak even you use it thoughout the game
@Ofe: Yup but my system can't check bj_wantDestroyGroup even it = true or false but that group still destroyed :) if = true

That was my point for the first one.

For the second it should detect it since bj_wantDestroyGroup is a boolean used for an ITE. In that ITE DestroyGroup is called. As long as your system detects DestroyGroup it will detect that also.

Yes, but that doesn't mean it's leaking memory. It needs to be placed in memory to be used.

Your analogy is wrong, if we follow your analysis, then everything in memory is a leak, we might as well not use memory (since programs needs to use memory), or the computer.

It is not his analogy it is just the capabilities of the system can't catch that
 
Level 9
Joined
Dec 3, 2010
Messages
162
No, it doesn't, after tested it, i can't catch bj_wantDestroyGroup :(

bj_wantDestroyGroup is simply a boolean which determines whether DestroyGroup should be ran or not. I'll just post the ForGroupBJ code as an example.

JASS:
function ForGroupBJ takes group whichGroup, code callback returns nothing
    // If the user wants the group destroyed, remember that fact and clear
    // the flag, in case it is used again in the callback.
    local boolean wantDestroy = bj_wantDestroyGroup
    set bj_wantDestroyGroup = false

    call ForGroup(whichGroup, callback)

    // If the user wants the group destroyed, do so now.
    if (wantDestroy) then
        call DestroyGroup(whichGroup)
    endif
endfunction
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
bj_wantDestroyGroup is simply a boolean which determines whether DestroyGroup should be ran or not. I'll just post the ForGroupBJ code as an example.

JASS:
function ForGroupBJ takes group whichGroup, code callback returns nothing
    // If the user wants the group destroyed, remember that fact and clear
    // the flag, in case it is used again in the callback.
    local boolean wantDestroy = bj_wantDestroyGroup
    set bj_wantDestroyGroup = false

    call ForGroup(whichGroup, callback)

    // If the user wants the group destroyed, do so now.
    if (wantDestroy) then
        call DestroyGroup(whichGroup)
    endif
endfunction

That is exactly what i have said lol. The trigger should be able to catch the call DestroyGroup() in the ForGroupBJ.

The thing that may give bad results is that ForgGoupBJ and ForGroup run when using ForGroupBJ. Which will show it as 2 leaks instead of 1 if both are hooked.

@TO
You should only hook ForGroup. Do not hook ForGroupBJ. It will give unwanted results because of the explanation above.
You should only hook the native functions not the GUI functions for everything.
 
GUI func didn't add a weird code like hooked func, so why not ? :D,
Yeah i missing something here, i'll check and fix it :D. Thank both of you ^^
----------
bj_wantDestroyGroup is not a native function, so i can't hook it also my system can't catch it too, just catch when destroygroup func is called, you can test whatever i say is true, i can show test map about this thing right now because i'm using mobile.
 
Last edited:
Level 9
Joined
Dec 3, 2010
Messages
162
GUI func didn't add a weird code like hooked func, so why not ? :D,
Yeah i missing something here, i'll check and fix it :D. Thank both of you ^^
----------
bj_wantDestroyGroup is not a native function, so i can't hook it also my system can't catch it too, just catch when destroygroup func is called, you can test whatever i say is true, i can show test map about this thing right now because i'm using mobile.

If you did hook DestroyGroup, then your system should detect it perfectly fine.
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
That doesn't make sense and as we have said a ton of times already we know bj_wantDestroyGroup is not native. It isn't even a function it is a boolean. You can't hook it.....

If your DestroyGroup function is hooked then it should work. You should only hook native function calls not BJs that call natives.

Please supply test maps so we can better help test this to make it better.
 
Okay, a ton of times, a heavy word to me :(, my heart is broken........, i'm just try to tell: i can't catch it, anyway, the test very simple:

  • Melee Initialization
    • Events
      • Time - Elapsed game time is 0.00 seconds
    • Conditions
    • Actions
      • Custom script: set bj_wantDestroyGroup = true
      • Set g = (Units in (Playable map area))
      • Unit Group - Pick every unit in g and do (Actions)
        • Loop - Actions
Here the results:
Total leaks group results: 1
Total leaks group remaining: 1
Total leaks group cleaned (Destroyed): 0

That it's :), if my system catch bj_wantDestroyGroup = true. Total leaks group cleaned (Destroyed) must = 1, != 0 ....Correct me if i show a wrong test code.
 
Level 9
Joined
Dec 3, 2010
Messages
162
Ah yes, just remembered that BJ functions do not call the hook functions (even if the actual hooked native is called within the BJ).

And IIRC, hooks compiles into bunch of ugly trigger evaluations instead of function calls. But I guess it isn't relevant here, since efficiency isn't a problem at all.
 
Last edited:
Level 22
Joined
Sep 24, 2005
Messages
4,821
Won't this work? I don't know how hooks are implemented internally, but as I understand, it replaces the hooked function.
JASS:
    private function ForGroupBJDetector takes group g,code c returns nothing
        if (not bj_wantDestroyGroup) then
        set GROUP_TOTAL_LEAKS = GROUP_TOTAL_LEAKS + 1
        set GROUP_LEAKS_REMAINING = GROUP_LEAKS_REMAINING + 1
        endif
    endfunction
 
Level 9
Joined
Dec 3, 2010
Messages
162
Won't this work? I don't know how hooks are implemented internally, but as I understand, it replaces the hooked function.
JASS:
    private function ForGroupBJDetector takes group g,code c returns nothing
        if (not bj_wantDestroyGroup) then
        set GROUP_TOTAL_LEAKS = GROUP_TOTAL_LEAKS + 1
        set GROUP_LEAKS_REMAINING = GROUP_LEAKS_REMAINING + 1
        endif
    endfunction

Just tested this and it works. So yeah, could use this to detect bj_wantDestroyGroup.
 
Top