| 10-31-2006, 02:55 PM | #1 |
Well, just look at this script: JASS:function z takes nothing returns nothing call DisplayTextToPlayer( GetLocalPlayer(), 0, 0, "End" ) call DestroyTimer( GetExpiredTimer() ) endfunction function F takes nothing returns nothing local timer t call TimerStart( t, 2, false, function z ) endfunction The local var timer t does leak, doesn't it? If I nullify it, the timer does not work. Any other ideas to get this leak free? Thanks for help! |
| 10-31-2006, 03:24 PM | #2 |
you are not initializing the timer. ... |
| 10-31-2006, 03:44 PM | #3 |
Translation: There is no timer object. You need to do: local timer t = CreateTimer() |
| 10-31-2006, 04:53 PM | #4 |
Ah, I'm a little dumb, thanks for opening my eyes! So the following should be perfectly working leakless code to build an exact wait, or not? JASS:function z takes nothing returns nothing local timer t = GetExpiredTimer() call PauseTimer( t ) call DestroyTimer( t ) //Any actions to do when timer ends endfunction function F takes nothing returns nothing local timer t = CreateTimer() call TimerStart( t, 2, false, function z ) set t=null endfunction |
| 10-31-2006, 05:00 PM | #5 |
Add a PauseTimer before you destroy the it, that prevents some bugs I think |
| 10-31-2006, 05:10 PM | #6 |
OK, I edited the post above and added a local to function z, too because "GetExpiredTimer()" in DestroyTimer does leak again, or not? Which bugs may occur btw if I destroy an unpaused timer? What does it actually change if the timer is already expired? |
| 10-31-2006, 05:12 PM | #7 |
I would say nothing since this isn't a repeating timer, but its better to be safe than sorry imo. |
| 10-31-2006, 05:18 PM | #8 |
Also, set t = null in the second function, otherwise your leaking a pointer in the second function. |
| 10-31-2006, 05:28 PM | #9 |
I do this for timer handling: JASS://! library CSSafety //****************************************************************************************** //* //* CSSafety 14.1 //* ¯¯¯¯¯¯¯¯ //* //* Utilities to make things safer. Currently this simply includes a timer recycling //* Stack. Once you replace CreateTimer with NewTimer and DestroyTimer with ReleaseTimer //* you no longer have to care about setting timers to null nor about timer related issues //* with the handle index stack. //* //****************************************************************************************** //========================================================================================== globals private timer array T private integer N = 0 endglobals //========================================================================================== function NewTimer takes nothing returns timer if (N==0) then return CreateTimer() endif set N=N-1 return T[N] endfunction //========================================================================================== function ReleaseTimer takes timer t returns nothing call PauseTimer(t) if (N==8191) then debug call BJDebugMsg("Warning: Timer stack is full, destroying timer!!") //stack is full, the map already has much more troubles than the chance of bug call DestroyTimer(t) else set T[N]=t set N=N+1 endif endfunction //! endlibrary Of course, you might need some modiffications in order to make it work without preprocessors... But that way I can just use New and Release instead of Create and Destroy, and there is no need to set to null anymore - no unstability risks |
| 10-31-2006, 05:30 PM | #10 |
I've run across some bugs when destroying the ExpiredTimer before running my actions. Pause is ok, but wait to destroy the timer until your actions are run. |
| 10-31-2006, 07:59 PM | #11 |
But doesn't executing a wait in a timer callback end the thread? |
| 11-01-2006, 01:43 AM | #12 | |
Quote:
Also, I noted the issue Awakening mentioned awhile ago. I actually made a topic on it, to which I got maybe 3 replies. I am almost certain the issue exists, but I need to perform additional testing. Hopefully my testing will be done in the coming weeks -- I'll start a new topic when I get results. |
| 11-01-2006, 01:50 AM | #13 |
Yes waits kill the thread when used in a timer. Basically with clearing up hardwired variables set integer = 0 set real = 0 set boolean = false strings cannot be cleaned These types of variables however don't leak very much compared to handles. For handles there are 2 ways to clean, one is proper and the other isn't. When you set a handle to null you clear the variable that stored the information for the handle, but the handle still exits. For example if you do this JASS:set t = null // t is a timer The variable t no longer has the timer value stored in it BUT it still exits which means it will still leak. To properly destroy a handle there is a specific function to destroy most types of handles e.g. for a timer its DestroyTimer(t). Not only does the function remove the handle from the game but it also clears the variable t (since the value was deleted) |
| 11-01-2006, 02:43 AM | #14 |
- If you don't set int/real/bool to something they leak: False - Timers should never be set to null (with one exception for if you keep main thread around) - Your pronouns are ambiguous and confusing - No native affects the value of any JASS variable. |
| 11-01-2006, 10:42 AM | #15 |
Basically, ignore PandaMine's post because it's almost entirely wrong. http://www.wc3campaigns.net/showthread.php?t=81872 |
