FoG loops are only meant to be used when the group is done with the units it contains, as the group is empty afterward. The next thing to consider is that having a "null" filter requires the least work from the game engine as it doesn't need to open up a new thread per unit it evaluates.
99% of the time what I see is a group being used for quick "is that unit in range, and if so do actions" and then the group is obsolete. A single unit group can be used for each of these tasks, unless you need to nest a FoG loop within another one. Then you use a second permanent unit group for that second enumeration.
If you are part of the minority who will do things with that unit group and not just use it for those quick enums, then ForGroup or a unit array should be used for iterating. A unit array will be faster if more than 1 or 2 units need to be iterated over.
FirstOfGroup (and unit arrays) allows you to access local variables; ForGroup and the filterfunc passed to GroupEnum/ requires they all be globals.
i do smth like this if there is no DoT or smth like that:
call Groupenumunitsinrange(g,x,y,range,some global filter)
and in this filterfunc do
function filter takes nothing retuns boolean
local\or global unit = GetFilterUnit()
if UnitAlive(unit) and not IsUnitType(unit,unitmagicimmune) then
some actions
//if need to add this unit in special group(for index for example) then
add unit in group
return return true
if not need then just
endif
return false
endfunction
and later if need do smth with group with units i do if only one action need without reverse groups then do FoG if not, then do ForGroup()
in another side, i just do all needed actions in filter function.
and works perfect, mb its not really good way, but i think its a fastest method qoz only one loop with enum units action. thats why i asked. in another way, i have no open source of wc3 for look whats happens there in real in that functions, i can only imagine, that this forgroup its the same loop emulation with virtual functions like FoG in wc3 engine and mb with some delays between actions with every units for sync every action in this loop instead of just loop wich do everythin without any delays(i mean in 1-2 ns or smth like that) and thats why need everytime to destroy group after that, and enumirate its same loop with check every units in area or rect wich returns true in conditions.
and its looks smth like:
function forgroup takes group g func a return => create thread(code) for group(g)
thread g():
loop
unit enumunit[x] = unit in group(g)/simulate as firstofgroup(g) = get max handle of units in group g...
do actions....
x ++
if x > maxX then
endloop
endif
finish thread.
and enumunits its smth the same for me but with conditions.
is unit in range\rect then return true. and etc
so if thats true, then we can use loop with indexed units like unit[1] unit[2] and etc without firstofgroup...like
groupenumunitsinrange function
set unit u = GetFilterUnit()
if .... then
set unit[x] = u
set x = x + 1
set maxX = x
return true
endif
return false
and after use loops with indexed units in array
loop
exitwhen x > maxX
if unit[x] blabla then
some actions
endif
set x = x + 1
endloop
Last edited: