• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Do Parameters Leak?

Status
Not open for further replies.
Level 4
Joined
Jan 20, 2011
Messages
65
hi

do you need to nullify function parameters so they dont leak?

JASS:
function example takes player p returns nothing
    // do stuff
    set p = null // <-- ??
endfunction
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
As far as I know, they do not leak.

I think your correct.

If a variable is set to a value which is then used as a parameter for a function and the variable is nullified after the function is executed,
Then nullifying the parameter inside the function it's passed through won't make any difference since a paramater is never stored, only used inside the function.

So a parameter doesn't get stored, it only gets used.

For example:
JASS:
function example takes player p returns nothing
    local player someone = p
endfunction

Here you store a variable with the value of the parameter. Which means the variable can leak, however p does not since it's never stored inside the function but only used.
(I don't get why anyone wants to store a variable to be the value of the parameter since the parameter can be used... But that's not the point here)
 
Last edited:
Level 17
Joined
Nov 13, 2006
Messages
1,814
I think your correct.

If a variable is set to a value which is then used as a parameter for a function and the variable is nullified after the function returned the value,
Then nullifying the parameter won't make any difference since a paramater is never stored, only used inside the function.

So a parameter doesn't get stored, it only gets used.

For example:
JASS:
function example takes player p returns nothing
    local player someone = p
endfunction

Here you store a variable with the value of the parameter. Which means the variable can leak, however p does not since it's only used inside the function.
(I don't get why anyone wants to store a variable to be the value of the parameter since the parameter can be used... But that's not the point here)

ah so function blabla takes group g return nothing

g dont leak but local group g after must be nulled at end after destroying
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
If it takes group g and your not setting a variable to be g then g never needs to be nullified since it's a parameter which does not get stored, only used.

So yes, that's correct.

but local group g after must be nulled at end after destroying

If the variable local group g is being used as a parameter for a function then g does not need to be nullified in the function it is passed to but in the function that calls the function that it passes to.

Might sound a bit complicated, here is an example:

JASS:
function example takes group g returns nothing
// do something with g here, it doesn't need to be nullified because it is a parameter which is never stored, only used...
endfunction

function example1 takes nothing returns nothing
   local group g = some random group
   call example(g)
   call DestroyGroup(g)
   set g = null
endfunction

That's exactly what you said right?
 
Last edited:
Level 14
Joined
Apr 20, 2009
Messages
1,543
Who are you Hashjie? Noone here should know that things. :D

I have some experience in several different programming languages, when it comes to parsing parameters to functions they basically act the same in all programming languages, that's how I know ;)
It was just some generall programming knowledge, thats all :p

I have some experience in the following languages:
HTML (including HTML 5.0 and XHTML, but that's just a matter of header data and syntaxes)
CSS (of course I keep myself up to date with CSS, I love ze stylingz!)
PHP (including templates ofc)
Java (kind of a beginner but looks the same as a lot of languages so..)
Javascript (have done some nice things in this language :D)
C++ (looks a lot like C#)
C# (learning this language on school)
Pascal (highschool, nuff said)
Ruby (I like to go rogue sometimes -,^)
Unrealscript (learning this for my new study, I want to become a succesfull game designer)
Jass (oh rlly?)
Jquery (lovely language to keep parts of your page up to date ^.^ Somewhat of a combination between Javascript and PHP)
Sequence Query Lines (duh, any webdesigner needs to know how to contact a MYSQL database)
XNA Framework (same explenation as for unreal script)
CryEngine SDK (same as XNA Framework)
Unityscript (same as Cryengine SDK)
Assembly (Fuck Yeah)

I'm not saying I'm really good in all of these languages, but I do know enough to create some nice things ;)
I'm 19 years old, I'm a nerd >.>
 
Last edited:
Level 4
Joined
Jan 20, 2011
Messages
65
why do you think it does not get stored? u have some logic behind it? prove?

i ask because i made following test which kinda could be kind of a disprove to ur theory... : /
i would actually have thought too that the parameters are just pointers but the following test shows that it is actually 2 different values
so it is stored?

JASS:
function testfunc2 takes player p returns nothing
    set p = Player(1)// now insite the function we change the variable
    if( p == Player(1) ) then// to test that it really changes
        call DB("jep it really changes")
    endif
endfunction

function testfunc1 takes nothing returns nothing
local player p = Player(0) // we have our variable
    call testfunc2(p) // we pass it as parameter
    if( p == Player(0) ) then// now back here , the variable did not change even though we changed it in the function !!
        call DB("fuck")
    endif
endfunction
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
why do you think it does not get stored? u have some logic behind it? prove?

i ask because i made following test which kinda could be kind of a disprove to ur theory... : /
i would actually have thought too that the parameters are just pointers but the following test shows that it is actually 2 different values
so it is stored?

JASS:
function testfunc2 takes player p returns nothing
    set p = Player(1)// now insite the function we change the variable
    if( p == Player(1) ) then// to test that it really changes
        call DB("jep it really changes")
    endif
endfunction

function testfunc1 takes nothing returns nothing
local player p = Player(0) // we have our variable
    call testfunc2(p) // we pass it as parameter
    if( p == Player(0) ) then// now back here , the variable did not change even though we changed it in the function !!
        call DB("fuck")
    endif
endfunction

You have just proven my theory to be correct.

A parameter is not the same as a variable and does not get stored.
Your not supposed to change the variable p from testfunc1 inside testfunc2 because it can only be used as a parameter.
All your doing here is changing the value of the parameter, which of course does not change the variable p in testfunc1.
And which then of course shows the message "jep it really changes" since your checking if the parameter you've just changed from value Player(0) to Player(1) to be Player(1).
Meaning that in testfunc1 p will not be changed from Player(0) to Player(1) (I assume here that "fuck" is being displayed) because the parameter is not stored inside the variable and does not change, it can only be used.

So if the parameter does not get stored, then how can it leak :)?
 
Level 4
Joined
Jan 20, 2011
Messages
65
i do not trust in what Hashjie sais
is there some pro who has more knowledge about this?
it must be that this parameter and the variable from my example are stored in different parts of memory... since we change one without changeing the other

i did spam this example above in a very fast loop and with 500 actions attached, it does not seem to increase the memory usage when u look at system monitor, also does not make the waittime to enter the chat channels longer
though i also tested without nullifying p at all and no difference^^
ummm... i duno rly lol
mb someone else has any idea?
im not guna keep researching this since i dont have any lags in my map or anything...
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
i do not trust in what Hashjie sais
is there some pro who has more knowledge about this?
it must be that this parameter and the variable from my example are stored in different parts of memory... since we change one without changeing the other

i did spam this example above in a very fast loop and with 500 actions attached, it does not seem to increase the memory usage when u look at system monitor, also does not make the waittime to enter the chat channels longer
though i also tested without nullifying p at all and no difference^^
ummm... i duno rly lol
mb someone else has any idea?
im not guna keep researching this since i dont have any lags in my map or anything...

Pffff so me and Maker both are wrong even though I've fully explained how it works?
And ofcourse you proving me correct by saying that the memory usage does not get increased,
including a trigger which shows that parameters clearly do not store inside variables?

How much more proof do you need man xD

Quotation of Maker:
Maker said:
As far as I know, they do not leak.

So me and Maker both are unexperienced ^.^? That's just.. insulting

Also, let me quote this:
alfalfa said:
it must be that this parameter and the variable from my example are stored in different parts of memory... since we change one without changeing the other

No because the parameter does not get stored at all. As I stated before it's only being used inside the function since you've passed the variable to be the value of the parameter.
Inside the function with the parameter all your doing is changing the value of the parameter, not the value of the variable. That's exactly why it doesn't change!

Is there any way I can break this down into small parts so you can understand even better? I think this can't be any clearer... PLEASE proof me wrong.

Search2Destroy said:
Learn pointer. I think parameter in wc3 send parameter by reference.

This is a pointer:

wikipedia said:
In computer science, a pointer is a programming language data type whose value refers directly to (or "points to") another value stored elsewhere in the computer memory using its address.
For high-level programming languages, pointers effectively take the place of general purpose registers in low-level languages such as assembly language or machine code, but may be in available memory.
A pointer references a location in memory, and obtaining the value at the location a pointer refers to is known as dereferencing the pointer.
A pointer is a simple, more concrete implementation of the more abstract reference data type.
Several languages support some type of pointer, although some have more restrictions on their use than others.
As an analogy, a page number in a book could be considered a pointer to the corresponding page; dereferencing such a pointer would be done by flipping to the page with the given page number.

This is a parameter:

wikipedia said:
In computer programming, a parameter is a special kind of variable, used in a subroutine to refer to one of the pieces of data provided as input to the subroutine.
[1] These pieces of data are called arguments.
An ordered list of parameters is usually included in the definition of a subroutine, so that, each time the subroutine is called, its arguments for that call can be assigned to the corresponding parameters.
Just as in standard mathematical usage, the argument is thus the actual value passed to a function, procedure, or routine (such as x in log x), whereas the parameter is a reference to that value inside the implementation of the function (log in this case).

In the most common case, call-by-value, a parameter acts within the subroutine as a local (isolated) copy of the argument, but in other cases, e.g. call-by-reference, the argument supplied by the caller can be affected by actions within the called subroutine (as discussed in evaluation strategy).
The semantics for how parameters can be declared and how the arguments get passed to the parameters of subroutines are defined by the language, but the details of how this is represented in any particular computer system depend on the calling conventions of that system.

Now where does it say that a parameter points to a location in memory?
Read this part again:

wikipedia said:
In computer science, a pointer is a programming language data type whose value refers directly to (or "points to") another value stored elsewhere in the computer memory using its address.

Just as in standard mathematical usage, the argument is thus the actual value passed to a function, procedure, or routine (such as x in log x), whereas the parameter is a reference to that value inside the implementation of the function (log in this case).
NOT a reference to a value stored somewhere in the memory of the computer, but a reference to the value inside the implementation of the function!

wikipedia said:
a parameter acts within the subroutine as a local (isolated) copy of the argument

Please don't tell me that Jass uses parameters differently then every other programming language.

alfalfa said:
why do you think it does not get stored? u have some logic behind it? prove?

Now.. Did I prove my point based on pure facts from wikipedia or what?
 
Last edited:
Level 14
Joined
Apr 20, 2009
Messages
1,543
parameters doesnt leak

Thank you...

the variables that is used to pass to that parameter that is not
destroyed, nulled leaks...
If your refferencing to this:

JASS:
function testfunc1 takes nothing returns nothing
local player p = Player(0) // we have our variable
    call testfunc2(p) // we pass it as parameter
    if( p == Player(0) ) then// now back here , the variable did not change even though we changed it in the function !!
        call DB("fuck")
    endif
endfunction

Then your incorrect, local player handles never need to be nulled.

If you meant in generall they need to be destroyed and nulled, then sorry :S
 
Last edited:
Level 4
Joined
Jan 20, 2011
Messages
65
Hashjie would you be intrested joining my map project?
the projects goal is to become the most played map on wc3 battle.net , even more played then legion td , it will replace legion td and leave it in the dust

if your intrested, contact me on skype, my nick is "d3cammy" and my skype picture is allways a cat
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
Hashjie would you be intrested joining my map project?
the projects goal is to become the most played map on wc3 battle.net , even more played then legion td , it will replace legion td and leave it in the dust

if your intrested, contact me on skype, my nick is "d3cammy" and my skype picture is allways a cat

Sorry bro, not at this moment I've got way to much stuff to do :(

Working on a website for my uncle to gain 10% of his earnings from his webstore.

Working on reports that I need to do for my school...

Working on an intership for school...

Trying to learn Zbrush sculpting so I can create realistic 3d models...

Working on a terrain for a map from my clan, including recreating 180 GUI triggers into Jass...

Trying to help people on thehiveworkshop in the meanwhile ^.^...

Trying to create a game in Unreal Development Kit...

Setting up a C++ library that links to Unrealscript...

And I promised to create a 50 page long user manual on how to maintain a computer system for the complete noob >.<

Don't even get me started about my free-time which I barely have left to play games or hang out with friends xD
 
Then your incorrect, local player handles never need to be nulled.
If you meant in generall they need to be destroyed and nulled, then sorry :S
even units need not to be nulled although they leak but very little, I've tested to create
3000+ units many times, still the leak is very minimal, sometimes the function with the
nulled varible consumes more ram usage than the non-nulled...
and yes Im talking in general like units/groups/locations etc...
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
sometimes the function with the
nulled varible consumes more ram usage than the non-nulled...

But then using the same function AND nulling the variable would be more optimized I suppose? since nulling a variable is not a function...
Or am I missing something here? Could you give me an example perhaps?

even units need not to be nulled although they leak but very little, I've tested to create
3000+ units many times, still the leak is very minimal

Hmm even so, better to just do it. It doesn't hurt... :)
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
correct, its Highly recommended but not a must :)...

sample?, see our topic on post starting on Post25
Confinement

I still don't understand how a non-nulled instance can be less then a nulled one :S

How can something that's not empty take up less RAM memory then something that's empty?? For me, that's a mystery xD
Unless ofcourse your nullifying an already empty instance, meaning you don't have to nullify it since nullifying it takes up more RAM then keeping it like the way it already is: empty?

Really I have no idea how this can be achieved 0.o...
Please elaborate
 
I still don't understand how a non-nulled instance can be less then a nulled one :S

How can something that's not empty take up less RAM memory then something that's empty?? For me, that's a mystery xD

me too but I've tested it a month ago and it happened 'only sometimes'
I did something like this...
JASS:
scope testu initializer init
globals
   integer I = 0
endglobals

function TestU takes nothing returns nothing
   local unit u
   set I = I+1
   if I < 3000 then 
      set u = CreateUnit(Player(0), 'hpea', 0,0,0)
      call KillUnit(u)
   else
      call DestroyTimer(GetExpiredTimer())
   endif
endfunction

function init takes nothing returns nothing
   call TimerStart(CreateTimer(), 0.03, true, function TestU)
endfunction
endscope

maybe the dead unit is automatically nulled???...
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
me too but I've tested it a month ago and it happened 'only sometimes'
I did something like this...
JASS:
scope testu initializer init
globals
   integer I = 0
endglobals

function TestU takes nothing returns nothing
   local unit u
   set I = I+1
   if I < 3000 then 
      set u = CreateUnit(Player(0), 'hpea', 0,0,0)
      call KillUnit(u)
   else
      call DestroyTimer(GetExpiredTimer())
   endif
endfunction

function init takes nothing returns nothing
   call TimerStart(CreateTimer(), 0.03, true, function TestU)
endfunction
endscope

maybe the dead unit is automatically nulled???...

I think it's because units are being removed from the game after 60 second expiration timer on their decaying corpse.
Causing the unit to be removed from the memory and therefore does not need to be nulled.
Meaning that if you'd null the variable it's the same as a Do Nothing :p

I'm gonna test that later on...
 
Level 10
Joined
May 28, 2011
Messages
455
JASS:
function testfunc2 takes player p returns nothing
    set p = Player(1)// now insite the function we change the variable
    if( p == Player(1) ) then// to test that it really changes
        call DB("jep it really changes")
    endif
endfunction

function testfunc1 takes nothing returns nothing
local player p = Player(0) // we have our variable
    call testfunc2(p) // we pass it as parameter
    if( p == Player(0) ) then// now back here , the variable did not change even though we changed it in the function !!
        call DB("fuck")
    endif
endfunction

Damn it, i got parameter pass by value -.-" i get both DB output.
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
Damn it, i got parameter pass by value -.-" i get both DB output.

As I've explained 3 times already it's supposed to do that.
Let me just change the comments for a sec...

JASS:
function testfunc2 takes player p returns nothing
    set p = Player(1)// now inside the function we change the VALUE of the PARAMETER, NOT the VARIABLE
    if( p == Player(1) ) then// to see if Player(1) == Player(1)...
        call DB("wait, what?")
    endif
endfunction

function testfunc1 takes nothing returns nothing
local player p = Player(0) // Here we create a variable and set it to Player(0)
    call testfunc2(p) // Here we pass the VALUE of the variable to the PARAMETER of the function
    if( p == Player(0) ) then// now back here , the variable did not change because we didn't change the variable at all, we only changed the VALUE of the PARAMETER in testfunc2
        call DB("fuck, this is supposed to happen")
    endif
endfunction

I really hope this is easier to understand...
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
Yep. You are right. If im not mistaken... Now there is two memory location of p -.-"

No, because as I've already tryed to explain to you 2 times:
A parameter is not a variable, a parameter doesn't store anything.
A parameter is not stored inside the memory.
The only purpose of a parameter is that you can pass values through it which can then be used inside the function.
See it as a reference to the value that is being passed.
NOT a reference to a value being stored inside the memory... (which is called a pointer)


Example:
in testfunc2 set p = Player(1) makes no sense since the value of p was already Player(0), all you did here was change it. Nothing gets stored inside p since it's the parameter and not a variable.
of course the parameters value can change but that doesn't have to mean the value gets stored. If p was a variable inside testfunc2, then it would get stored.

Remember: the parameter is just a reference to the value that is being passed to the function.
Changing the value of the parameter doesn't change the variable that was used to pass the value of the variable to the parameter.
Nor does it store the value anywhere since all you did was change the value of the parameter, which is not a variable that stores values.

in testfunc1 local player p = Player(0) now this is stored inside the memory since it's a variable.

I hope this helps.
 
Last edited:
Level 14
Joined
Apr 20, 2009
Messages
1,543
afaik, pointer store the address of the memory location. passed value must store in another location since it doesnt change the original one. if it is not variable. how can it act as variable. my head messed up now. ill revise this topic -.-" lol

That's the whole point of the parameter, it can act like a variable even though its not :p
See it as a pointer that points to the value that is passed to the function (a parameter), not a pointer that points to a value inside the memory (a variable).

I know it looks as if there is no difference since both are values, but a parameter does not get stored inside the memory and a variable simply does.


(well theoretically both don't get stored inside the memory since a variable is a pointer to something stored inside the memory, parameter just doesn't point to something in the memory but to a value that is being passed. That's why you need to destroy a group inside the memory before you nullify the pointer (variable). Use the pointer (variable) to point to the group that needs to be destroyed and then empty the pointer (variable))

Don't know if that last part confused you again :p
 
Last edited:
Level 9
Joined
Nov 19, 2011
Messages
516
why do you think it does not get stored? u have some logic behind it? prove?

i ask because i made following test which kinda could be kind of a disprove to ur theory... : /
i would actually have thought too that the parameters are just pointers but the following test shows that it is actually 2 different values
so it is stored?

JASS:
function testfunc2 takes player p returns nothing
    set p = Player(1)// now insite the function we change the variable
    if( p == Player(1) ) then// to test that it really changes
        call DB("jep it really changes")
    endif
endfunction

function testfunc1 takes nothing returns nothing
local player p = Player(0) // we have our variable
    call testfunc2(p) // we pass it as parameter
    if( p == Player(0) ) then// now back here , the variable did not change even though we changed it in the function !!
        call DB("fuck")
    endif
endfunction

Let me explain it in Delphi.

When you call function

my_func(var p):integer;
call my_func(player(0));

Variable "p" is pointer. Which means all changes on that variable will be exacly changes on player(0). But if you will define it my_func(p):integer; variable "p" is parameter and is destroyed after end of function. In vJass (but ask someone other too) you can't make diffrence between pointers and parameter, so all are second one. So:

function testfunc2 takes player p returns nothing
set p = Player(1)// now insite the function we change the variable
if( p == Player(1) ) then// to test that it really changes
call DB("jep it really changes")
endif
destroy(p) //thats hidden call
endfunction

If you want to save your variable do it this way:

JASS:
function testfunc1 takes nothing returns nothing

function testfunc2 takes player a returns nothing
    set a = Player(1)// now insite the function we change the variable
    p=a
    if( p == Player(1) ) then// to test that it really changes
        call DB("jep it really changes")
    endif
endfunction

local player p = Player(0) // we have our variable
    call testfunc2(p) // we pass it as parameter
    if( p == Player(0) ) then// now back here , the variable did not change even though we changed it in the function !!
        call DB("fuck")
    endif
endfunction

EDIT
Its recomended to not double names. Of course if you do so it will not crash but program will only see last named variable/parameter/pointer.

JASS:
function testfunc takes nothing returns nothing
local p=1
function testfunc_bis takes nothing returns nothing
local p=2
if( p == 2 ) then// returns true!
        call DB("I can see only 2nd one!")
endif
endfunction
endfunction
 
Last edited:
Level 14
Joined
Apr 20, 2009
Messages
1,543
You can not create a function within a function, this causes a syntax error.
Jass does not support it.
You can of course create a function after the function and use ExecuteFunc in order to execute it even though it's created after the function that calls it.
Or simply create the function before the function and call the function before the function.
Also: local variables need to be defined before everything else inside a function.

And you can not change a local variable in a different function, then it would need to be a global variable.

This will simply not work.

A local variable can only be changed and used inside the function it is created in. Else the name local will make no sense...
Of course you can pass it to a parameter but then it won't change the local variable unless you return a value to set the local variable inside the function the local variable is created in.
 
- Parameters don't leak, you don't need to null them
- Locals leak, null them
- Parameters can be modified as if they were locals without affecting the original variable passed by another function
- Theoretically, this:
JASS:
function hi takes unit a, unit b, unit c, unit d returns nothing

endfunction

is faster than this:

JASS:
function hi takes nothing returns nothing
    local unit a
    local unit b
    local unit c
    local unit d
    set a = null
    set b = null
    set c = null
    set d = null
endfunction

Jass is an interpreted language, what do you expect from some fat sweaty programmer at Blizzard? :p
He's obviously going to treat parameters like locals because that would make his life easier. (OnFunctionCall, loop through parameter list, allocate memory based on type, when at the end, loop through all the lines, if "local" is the first word, allocate memory else, stop allocating and get ready for more function calls, comparisons and memory modifications, go to next line, loop)
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
- Locals leak, null them

This doesn't necessarily have to be true.

- Parameters don't leak, you don't need to null them
- Parameters can be modified as if they were locals without affecting the original variable passed by another function

That's exactly what I've explained like 5 times in a row.
I hope people will finally understand how it works.
This thread has been going on for way to long now.
 
Parametar is just memory adress of some data (value), while local variable is some new memory addres reserved for some new data (value).

Or at least it look like that to me when we speak about jass.

Now in Visual Basic (.Net and many other programming languages in general) you can use parametar in 2 different ways as value or as reference. Call-by-value, Call-by-reference.
I won't bother explaining how they work, it's unimportant here (search with google if you want to know more).
Point is that using adress to get some data > copy and pasting data into new local adress.

Care also how many local variables you use, more locals will require more memory space reserved for them. Ofc this doesn't mather in wc3 so much, but sometimes in huge maps like DotA, that have more than 26.000 lines of cleaned and optimized code, 500 unneeded local declarations can de/increase efficiency a bit.

I will do some testing when I come home, will see can I found something interesting.
 
That's exactly what I've explained like 5 times in a row.
I hope people will finally understand how it works.
This thread has been going on for way to long now.

The more it's mentioned, the more reliable it gets (It doesn't get reliable, it just gets more reliable)

huge maps like DotA, that have more than 26.000 lines of cleaned and optimized code

Even the optimized version of DotA isn't so optimal :p
DotA can be at least 16x faster on average. When it comes to the spells, it could be approximately 4800x lighter on handles and 432x lighter on spell event executions.
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
I think it's because units are being removed from the game after 60 second expiration timer on their decaying corpse.
Causing the unit to be removed from the memory and therefore does not need to be nulled.
Meaning that if you'd null the variable it's the same as a Do Nothing :p

I'm gonna test that later on...

@ mckill2009: My theory is incorrect, the variable is not nullified.

Here's my approach on testing it (Don't laugh I'm not a Jass expert yet...):
JASS:
function CheckRemainingTime takes timer WhichTimer returns string RemainingTime
local integer RemainingTime

call PauseTimer(WhichTimer)
set RemainingTime = R2I(TimerGetRemaining(WhichTimer))
call ResumeTimer(WhichTimer)
return I2S(RemainingTime)
endfunction

function CheckTime takes nothing returns nothing
local string remainingtime

set remainingtime = CheckRemainingTime(udg_UnitExpiration)
call DisplayTextToPlayer(Player(0), 0, 0, remainingtime)

if remainingtime == "0" then
    set udg_Expired = true
    call PauseTimer(udg_UnitExpiration)
    call DestroyTimer(udg_UnitExpiration)
endif
endfunction

function Trig_Untitled_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    local unit u = CreateUnit(Player(0), 'hpea', 0,0,0)
    
    set udg_UnitExpiration = CreateTimer()
    call KillUnit(u)
    call TimerStart(udg_UnitExpiration, 60, false, null)
    call TimerStart(t, 1, true, function CheckTime)
    
    loop
        exitwhen udg_Expired == TRUE
        call TriggerSleepAction(0.5)
    endloop

    call DisplayTextToPlayer(Player(0), 0, 0, "Unit ID after the expiration timer of the unit has expired: " + I2S(GetHandleId(u)))
    call PauseTimer(t)
    call DestroyTimer(t)
    set t = null
endfunction

//===========================================================================
function InitTrig_Untitled takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterTimerEvent(t, 0.00, false)
    call TriggerAddAction( t, function Trig_Untitled_Actions )
    set t = null
endfunction

I guess this can be way more optimized. If anyone is interested, please tell me what I'm doing wrong. I'm verry willing to learn from my mistakes. :)
 
Just null all variables.


Removing a unit will only make the integer that points to them point to a null struct/class.
It will not make the variables themselves point to null.

That's why something like this:

JASS:
function CreateUnitAndGetShadow takes nothing returns image
    // Handle id of this image is now 0
    local image i = CreateImage("dummy.blp", 64, 64, 0, 0, 0, 0, 64, 64, 0, 3)
    // Image destroyed, i points to 0
    call DestroyImage(i)
    // This unit will also create an image (it's shadow)
    // This shadow will have a Handle Id of 0
    // i points to an image with Id 0
    call CreateUnit(...)
    // Thus i is now the actual shadow of the unit ^_^
    return i
endfunction

Works perfectly.

Optimizations:

- Remove the == TRUE and == true's in there (100% useless)
- Use timers instead of periodic triggers

It's just a Demo code, so there aren't a lot of important improvements.

- TriggerSleepActions are inaccurate and /bad/.
- Destroying timers is buggy, that's why TimerUtils is extremely useful.
etc..
 
- Destroying timers is buggy, that's why TimerUtils is extremely useful.
etc..
that's really not true coz I have spells like that and it works fine, besides you
cant use TU in jass mode only...

@Hashjie
there's no need for all that conversions...checking the remaining time is as simpel as this...
JASS:
scope Nullings initializer init

globals
    unit U
    integer RTime = 61
endglobals

private function TestIt takes nothing returns nothing
    set RTime = RTime - 1
    call BJDebugMsg(I2S(RTime))
    if RTime < 1 then
        call PauseTimer(GetExpiredTimer())
        call DestroyTimer(GetExpiredTimer())
        if U==null then
            call BJDebugMsg("nulled")
        else
            call BJDebugMsg("not nulled")
        endif    
    endif
endfunction

private function init takes nothing returns nothing
    set U = CreateUnit(Player(15), 'hpea', 0,0,0)
    call KillUnit(U)
    call TimerStart(CreateTimer(), 1, true, function TestIt)    
endfunction

endscope
 
cant use TU in jass mode only...

Writing your own Jass version is easy :p
I've done it for a lot of people countless times ^.^

that's really not true coz I have spells like that and it works fine

Destroying timers causes rare bugs, not bugs that happen 100% of the time :/
Either way, recycling is much better. When using Timer Recyclers, you won't have to constantly destroy and create new timers.
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
Just null all variables.

Even local real, string, integer, and boolean?
Including globals? :S

why?

Removing a unit will only make the integer that points to them point to a null struct/class.
It will not make the variables themselves point to null.

So how can I check if the struct/class is null then?

That's why something like this:

JASS:
function CreateUnitAndGetShadow takes nothing returns image
    // Handle id of this image is now 0
    local image i = CreateImage("dummy.blp", 64, 64, 0, 0, 0, 0, 64, 64, 0, 3)
    // Image destroyed, i points to 0
    call DestroyImage(i)
    // This unit will also create an image (it's shadow)
    // This shadow will have a Handle Id of 0
    // i points to an image with Id 0
    call CreateUnit(...)
    // Thus i is now the actual shadow of the unit ^_^
    return i
endfunction

Works perfectly.

So I can interact with the shadow then :O?
That's awesome to know :ogre_haosis:

Just so that I know:
When removing a handle from the memory the variable that points to that address will stay the same if the variable is not nullifyed ofcourse.
Then when creating a new handle of the same type the handle id of the previous handle that was removed will be the same as the one of the new handle?
Meaning you point the variable to the new handle instead of the one that got removed.

Is that right?

However,

Optimizations:

- Remove the == TRUE and == true's in there (100% useless)

As in doing this instead?:
JASS:
exitwhen (udg_Expired)
- Use timers instead of periodic triggers

Am I not already doing that? Where exactly do you see any periodic triggers?

It's just a Demo code, so there aren't a lot of important improvements.
- TriggerSleepActions are inaccurate and /bad/.

Please take refference in this thread why I'm using TriggerSleepActions:
http://www.hiveworkshop.com/forums/...98/how-do-i-get-expiration-timer-unit-210174/

- Destroying timers is buggy, that's why TimerUtils is extremely useful.
etc..

In what way do they bug? Could you please give examples?


that's really not true coz I have spells like that and it works fine, besides you
cant use TU in jass mode only...

@Hashjie
there's no need for all that conversions...checking the remaining time is as simpel as this...
JASS:
scope Nullings initializer init

globals
    unit U
    integer RTime = 61
endglobals

private function TestIt takes nothing returns nothing
    set RTime = RTime - 1
    call BJDebugMsg(I2S(RTime))
    if RTime < 1 then
        call PauseTimer(GetExpiredTimer())
        call DestroyTimer(GetExpiredTimer())
        if U==null then
            call BJDebugMsg("nulled")
        else
            call BJDebugMsg("not nulled")
        endif    
    endif
endfunction

private function init takes nothing returns nothing
    set U = CreateUnit(Player(15), 'hpea', 0,0,0)
    call KillUnit(U)
    call TimerStart(CreateTimer(), 1, true, function TestIt)    
endfunction

endscope

I see now how ignorant I have been, how did I not think of this!

I haven't read any vJass tutorials yet, I guess it's time to do so. This code looks way cleaner :)
I do understand the Globals, Initializer and Private functions. I don't really know what the scope does.
If I recall correctly I did read something about scope being a library and your extending it with a standard wc3 library using the Initializer right?

Then how can I check what a standard wc3 library contains?
 
Last edited:
libraries and scopes have the same function except that libraries can use
explicit requirements and it's rested above scopes...

you can use initializers like what I did but you can use also onInit & module
in a struct structure (modules are better)...

Either way, recycling is much better. When using Timer Recyclers, you won't have to constantly destroy and create new timers.
200% agree, but nothing wrong with destroying them, thats why DestroyTimer is there ;)...
 
Status
Not open for further replies.
Top