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

[JASS] question about Local variable

Status
Not open for further replies.

ABM

ABM

Level 7
Joined
Jul 13, 2005
Messages
279
hi,

local variable create an instance meaning that the same local cannot be over written by another cast of the function.
ex:
local unit a
set a = GetTriggerUnit()
wait 2.00
kill a

---------------------------------------------------------------------------------------
the problem is i use GUI with merged trigger wich run other triggers, and local variable are better be cleanned, because they create a value on each run...but if the value is cleanned while another trigger still is using the same instance of local variable it will create bugs...

how to clean a local when the same local is runned on many trigger with different wait time?
trigger 1
set local unit a = GetTriggerUnit()
if a == 'R000' do stuff
if a == 'Y010' or if a == 'K001' call TriggerExecute(trigger2)
if a == 'H002' call TriggerExecute(trigger3)


trigger 2
if a == 'Y010' do stuff
else if a == 'K001' call TriggerExecute(trigger4)

trigger 3
wait 2.00
if life of a> 50 do stuff
wait 2.00
wait 2.00
if life of a> 50 do stuff
wait 2.00
if life of a> 50 do stuff

trigger 4
move a to loc
etc..whatever
-------------------------------------------------------------------------------------

the important thing is that i have local for (attacking) (attacked) (ownerofattacking) (ownerofattacked) (playernumberofowner...etc)
there are lot of if then else and 100 or more of typeunit, and check, so it would be impossible to make it in one trigger in GUI.

but some trigger because of wait will continue to use "a" for a long time (a,b,c,d,etc...)
to clean them should i make at the end of each divided trigger a call TriggerExecute(trigger6)

trigger6
wait 20 sec
set a = null

so each instance would be cleanned after 20 sec, or add in each trigger the set a= null, but then it will remove value before the a instance finish in some trigger.

???

EDIT:
also i should tell you that since i use GUI, all my local are actually udg_Variable made local with custom text....
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
local variables r only accessible in the function they r created in

ex function1
local unit a
set a = gettriggerunit
endfunction

function2
local unit a
set a = gettriggerunit
endfunction

function 1 and 2 r seperate therefore the unit a is technically different but this is only for local variables
and to clean a local variable u do
set a = null
at the end of each function

hope tht helps
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
globals leak just as much as locals if not nulled, people just dont realize it or ignore it
hence people null all struct variables of type handle
This is true if those globals aren't used very often. In the case of structs, those variables are only used for a specific role, thus nulling them is advised.
To quote the doctor:
If the global is constantly having its value changed, then nulling is a waste of time.
The post I quoted contains some really good info on why and when nulling variables can be important.
 

Cokemonkey11

Spell Reviewer
Level 30
Joined
May 9, 2006
Messages
3,537
hi,

local variable create an instance meaning that the same local cannot be over written by another cast of the function.
ex:
local unit a
set a = GetTriggerUnit()
wait 2.00
kill a

---------------------------------------------------------------------------------------
the problem is i use GUI with merged trigger wich run other triggers, and local variable are better be cleanned, because they create a value on each run...but if the value is cleanned while another trigger still is using the same instance of local variable it will create bugs...

how to clean a local when the same local is runned on many trigger with different wait time?
trigger 1
set local unit a = GetTriggerUnit()
if a == 'R000' do stuff
if a == 'Y010' or if a == 'K001' call TriggerExecute(trigger2)
if a == 'H002' call TriggerExecute(trigger3)


trigger 2
if a == 'Y010' do stuff
else if a == 'K001' call TriggerExecute(trigger4)

trigger 3
wait 2.00
if life of a> 50 do stuff
wait 2.00
wait 2.00
if life of a> 50 do stuff
wait 2.00
if life of a> 50 do stuff

trigger 4
move a to loc
etc..whatever
-------------------------------------------------------------------------------------

the important thing is that i have local for (attacking) (attacked) (ownerofattacking) (ownerofattacked) (playernumberofowner...etc)
there are lot of if then else and 100 or more of typeunit, and check, so it would be impossible to make it in one trigger in GUI.

but some trigger because of wait will continue to use "a" for a long time (a,b,c,d,etc...)
to clean them should i make at the end of each divided trigger a call TriggerExecute(trigger6)

trigger6
wait 20 sec
set a = null

so each instance would be cleanned after 20 sec, or add in each trigger the set a= null, but then it will remove value before the a instance finish in some trigger.

???

EDIT:
also i should tell you that since i use GUI, all my local are actually udg_Variable made local with custom text....

(Use [code=jass][/code] tags to display blocks of jass)

As others have said, if you declare a local in a custom script action in GUI, you cannot access that local in another GUI trigger. You must use a global for this case.

To answer your question more directly, if you want to clear any leak caused by a local variable you must:

* Destroy any object you're finished with (kill unit, destroy special effect, etc)
* null handle variables so that their pointer (IE the local variable) is dereferenced

Here is an example:

JASS:
local unit u=CreateUnit(...)
local timer time=CreateTimer()
...
call KillUnit(u) //only necessary if you actually don't want u to persist
call DestroyTimer(time) //only necessary if you are done with the timer - usually you won't destroy a timer in the same function you create it
set u=null
set time=null

globals leak just as much as locals if not nulled, people just dont realize it or ignore it
hence people null all struct variables of type handle

This is incorrect. If you have a global variable and you're using it properly, you have no reason to null it unless you know it will never be used again. Nulling a variable is purely to dereference its pointer (thereby allowing the engine to recycle it)

struct *instance* variables of type handle need to be nulled because they *aren't* global.

*static* struct members are global, and they behave just like globals and follow the same rules.

Well, you cant use locals with multiple triggers so your other options, hashtable or arrays

This is technically incorrect. You're free to use the same local with multiple trigger objects in jass, but you can't refer to a local between triggers in GUI (because they use the same name for a completely different construct).

Here's an example:

JASS:
private function init takes nothing returns nothing
    local trigger trig1=CreateTrigger()
    local trigger trig2=CreateTrigger()
    local unit u=CreateUnit(...)
    call TriggerRegisterUnitEvent(trig1,u,...)
    call TriggerRegisterUnitEvent(trig2,u,...)
    set trig1=null
    set trig2=null
    set u=null
endfunction
 
I think all this technobabble in this thread just confused the TO, who had a simple misunderstand of how locals work.

To answer the question of the TO:
If you use locals, the problem you are afraid of is not there. Even if all locals have the same name, they are not the same variable.

"a" in trigger 1 is not the same as "a" in trigger 2 or another instance of trigger 1 just because the name is the same.
 

Cokemonkey11

Spell Reviewer
Level 30
Joined
May 9, 2006
Messages
3,537
JASS:
struct AA
    private integer i
endstruct

//---->

globals
    integer array s__AA_i
endglobals
they actually are globals, so why do we null them then?

Yes you're right, I forgot about the struct/integer duality.

You don't need to null them unless you *know* the struct identifier (the struct with this value of integer) will never be used again (unlikely in most applications).
 
Status
Not open for further replies.
Top