• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

Local Variables inside Trigger, not working for Unit Group?

Status
Not open for further replies.
Level 5
Joined
Sep 29, 2016
Messages
43
Hey guys,

I couldn't find any answer to this case in any thread, so i thought i would ask it over here:

By checking stuff i noticed that inside the Unit Group Action the Tmp_Point and Tmp_Real are not the local variables anymore but the global variables. What would be the correct way to get the values of Tmp_Real and Tmp_Point inside the Unit Group Action, while still using local variables? Initialize and set them every time in the Unit Group?

  • Events
  • Conditions
  • Actions
  • Custom script: local location udg_Tmp_Point
  • Custom script: local location udg_Tmp_Point2
  • Custom script: local location udg_Tmp_Point3
  • Custom script: local real udg_Tmp_Real
  • Custom script: local real udg_Tmp_Real2
  • Custom script: local real udg_Tmp_Real3
  • Custom script: local group udg_Tmp_UnitGroup
  • Set Tmp_Point = (Position of (Triggering unit))
  • Set Tmp_Point2 = (Target point of ability being cast)
  • Set Tmp_Real = (Angle from Tmp_Point to Tmp_Point2)
  • Set Tmp_UnitGroup = (Units within SAndSFlashofSteelSize of Tmp_Point matching (((Owner of (Matching unit)) is an enemy of (Owner of (Triggering unit))) Equal to True))
  • Unit Group - Pick every unit in Tmp_UnitGroup and do (Actions)
    • Loop - Actions
      • Set Tmp_Point3 = (Position of (Picked unit))
      • Set Tmp_Real2 = (Angle from Tmp_Point to Tmp_Point3)
      • Set Tmp_Real3 = (Tmp_Real2 - Tmp_Real)
      • Game - Display to (All players) the text: ((String((X of Tmp_Point))) + (String((Y of Tmp_Point))))
      • Game - Display to (All players) the text: (String(Tmp_Real))
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
You can't use local variables inside unit group actions.
Why do you even need local variables in the first place?
That's not entirely true. You can't use local variables declared outside of the unit group loop because the unit group is an entirely different function. If you want to use local variables, they will need to be declared inside the loop.
 
Nothing like newly introduced lua can fix.

  • Custom script: //! beginusercode
  • Custom script: ForGroupBJ(udg_Tmp_Unit_Group, function(udg_Tmp_Point, udg_Tmp_Point2, udg_Tmp_Point3, udg_Tmp_Real, udg_Tmp_Real2, udg_Tmp_Real3)
  • .... Copy Loop Actions ....
  • Custom script: end)
Note: This should only work in the latest PTR and the latest patch.

In the end, I am wondering about the intentions behind this as well.
 
Level 5
Joined
Sep 29, 2016
Messages
43
Well, the biggest reason is to prevent leaks from Points and other stuff. I also thought that if the variable used is only necessary for this function and is getting calculated or set inside the function i don't need it as a global one.
Size of attack spells and stuff are global.
Points redirecting to center of positions and Reals that are only calculated inside that triggers (and maybe local integer Index for Loop Actions) stay local as much as i can make them do with GUI & simple Custom Scripts. This will help me a lot to reduce unnecessary Global Variables in my map.

But the moment I noticed that the Unit Group doesn't detect the local variables, I thought that it would be stupid to initialize and set them again and again for every Picked Unit...
That's why I decided to ask you guys about the reason for that behaviour, before I stick to global variables for those cases.

As always, thanks for your answers!
 

Wrda

Spell Reviewer
Level 26
Joined
Nov 18, 2012
Messages
1,905
Well, it's good that you want to reduce unnecessary global variables, but in this case, you can reuse these variables in an another trigger as well, as long as it is excecuted without interruption (without waits).
Local variables don't prevent leaks, in fact, they leak more (reference leaks). Memory Leaks
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,217
I recommend converting the trigger to custom script and looking at the output. You will quickly see why the locals do not work. This is why one should not be using hacky work arounds for locals in GUI because it masks errors like this.

Also now that Lua has been released, one can fix all leaks from a high level thanks to garbage collection and global namespace modification. This is assuming that Blizzard has not finally added Garbage collection for them automatically (someone needs to test...). I proved the concept back in the 1.31 PTR, and now in 1.31 release it does not even cause a crash when exiting.

The concept is to replace all functions that create and destroy groups, locations and forces with proxies. These proxies register the object for automatic garbage collection. Registration is done by creating a table which holds a reference to the object and has a garbage collection metamethod set to run the appropriate destructor on the object. To prevent this table being recycled prematurely a weak key map is used to map the object to the table. The properties of a weak keyed map mean that the table reference to the object becomes a weak reference and so once all strong references to the object are lost (when the object would normally leak) the table becomes eligible for garbage collection. When the table is garbage collected then it runs the appropriate destructor on the object, preventing a leak. When an appropriate destructor is explicitly called one can deregister the object for collection. Due to how it works, all GUI code will automatically change to calling the proxy functions. Hence making the solution, a single piece of custom script, fix all group, location and force leaks in a map.

Due to how Lua garbage collection works (does not factor in the memory used by the objects) the leaks might not be removed immediately. If this does cause performance or memory problems one can explicitly modify the garbage collection behaviour to be more aggressive. No matter how long the object is allowed to exist for after it is no longer needed, it will eventually be garbage collected and freed when the Lua garbage collector runs, hence no leaks.
 
Last edited:
Status
Not open for further replies.
Top