1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. We have recently started the 16th edition of the Mini Mapping Contest. The theme is mini RPG. Do check it out and have fun.
    Dismiss Notice
  4. Choose your ride to damnation in the 5th Special Effect Contest Poll.
    Dismiss Notice
  5. The winners of the 13th Techtree Contest have been announced!
    Dismiss Notice
  6. The 13th Music Contest Poll is up! Vote for the best tracks in this symphony of frost and flame.
    Dismiss Notice
  7. Race against the odds and Reforge, Don't Refund. The 14th Techtree Contest has begun!
    Dismiss Notice
  8. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Local Variables inside Trigger, not working for Unit Group?

Discussion in 'Triggers & Scripts' started by Jimpanse1, Jun 1, 2019.

  1. Jimpanse1

    Jimpanse1

    Joined:
    Sep 29, 2016
    Messages:
    42
    Resources:
    1
    Maps:
    1
    Resources:
    1
    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))
     
  2. Wrda

    Wrda

    Joined:
    Nov 18, 2012
    Messages:
    1,235
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    You can't use local variables inside unit group actions.
    Why do you even need local variables in the first place?
     
  3. KILLCIDE

    KILLCIDE

    Administrator

    Joined:
    Jul 22, 2015
    Messages:
    3,501
    Resources:
    20
    Models:
    2
    Icons:
    10
    Spells:
    7
    Tutorials:
    1
    Resources:
    20
    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.
     
  4. Wrda

    Wrda

    Joined:
    Nov 18, 2012
    Messages:
    1,235
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    Well, I said use, not create. But yes.
    In this context it's useless to create them inside the loop.
     
  5. MyPad

    MyPad

    Spell Reviewer

    Joined:
    May 9, 2014
    Messages:
    1,338
    Resources:
    7
    Models:
    1
    Icons:
    2
    Spells:
    3
    JASS:
    1
    Resources:
    7
    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.
     
  6. Jimpanse1

    Jimpanse1

    Joined:
    Sep 29, 2016
    Messages:
    42
    Resources:
    1
    Maps:
    1
    Resources:
    1
    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!
     
  7. Wrda

    Wrda

    Joined:
    Nov 18, 2012
    Messages:
    1,235
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    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
     
  8. Dr Super Good

    Dr Super Good

    Spell Reviewer

    Joined:
    Jan 18, 2005
    Messages:
    25,837
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    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: Jun 3, 2019