- Joined
- Aug 7, 2009
- Messages
- 1,403
So according to TriggerHappy's benchmarks a swapped FirstOfGroup enumeration is still faster than ForGroup, almost all the time. I'm gonna need this in the future for changing my aura snippet so I figured I'd post it here.
This is nothing fancy or complicated, just a simple interface for using swapped groups without much trouble.
I'm posting a test map with the requirements and the demo code too.
1.0
This is nothing fancy or complicated, just a simple interface for using swapped groups without much trouble.
I'm posting a test map with the requirements and the demo code too.
JASS:
library SwappedGroup/*
***************************************************************************************
*
* Swapped Group v1.2.1
*
* by Luorax
*
***************************************************************************************
*
* */ uses /*
* */ GroupUtils /* [URL]http://www.wc3c.net/showthread.php?t=104464[/URL]
*
***************************************************************************************
*
* DESCRIPTION
* >> SwappedGroup provides a lightweight interface for managing swapped
* unit groups.
*
* >> A swapped group is useful when using FirstOfGroup group enumerations
* on groups that need to keep their content after the enumeration, since
* all the units will be moved into a 'shadow group' (a secondary group in
* the background), and they'll be swapped after the enumeration.
*
* METHOD LIST
* >> struct SwappedGroup
* > public static method create takes nothing returns
* - creates a new SwappedGroup instance (2 groups)
* and returns with it.
*
* > public static method fromGroup takes group g returns thistype
* - creates a new SwappedGroup instance, moves the units in 'g'
* to the group of the instance and returns with the instance.
*
* - Empties the group passed!
*
* > public method destroy takes nothing returns nothing
* - Releases the two groups and deallocates the instance.
*
* > public method addUnit takes unit u returns nothing
* - Add a unit to the current group.
*
* > public method removeUnit takes unit u returns nothing
* - Removes a unit from the current group.
*
* > public method contains takes unit u returns boolean
* - Returns true if the group contains u, false otherwise.
*
* > public method clear takes nothing returns nothing
* - Clears the current group.
*
* > public method refresh takes nothing returns nothing
* - Refreshes the group, cleaning it from all the ghost
* (removed from game) units that could screw over the
* enumeration. Please note that this comes with a
* group swap in the background.
*
* > public method getNext takes nothing returns unit
* - If the group is not empty, returns the first unit
* of the group and adds it to the shadow group.
* - If the group is empty, returns 'null' and swaps the
* groups.
*
* OPERATORS
* >> public method operator group takes nothing returns group
* - Returns the current group.
* - The value returned is different after each enumeration.
* - It's only for compatibility with other resources (that
* expect regular groups), so try to use the methods above
* when possible.
* - NEVER under any circumstances use DestroyGroup or
* ReleaseGroup on these groups!
*
* MODULES
* >> SGEnumBegin
* > Imports a new stataic method: enumerate.
* > enumerate has one parameter: enumGroup (SwappedGroup)
* > enumerate has one local variable: enumUnit (unit)
*
* > the module imports the specification of the method and
* opens the loop, which is to be closed by "SGEnumEnd".
*
* > enumUnit and enumGroup can be used in the loop to iterate
* over the group. Their values are not to be modified!
*
* >> SGEnumEnd
* > Closes the loop opened by "SGEnumBegin".
* > Also responsible for doing the group swap.
*
* CREDITS
* > Rising_Dusk for GroupUtils.
*
*************************************************************************************/
globals
private group array Groups
private integer array BaseIndex
private integer array CurrentIndex
private integer array NextIndex
private unit TempUnit
private integer TempIndex
endglobals
struct SwappedGroup
/*
* Internal methods
*/
private static method refreshCallback takes nothing returns nothing
call GroupAddUnit(Groups[NextIndex[TempIndex]],GetEnumUnit())
endmethod
/*
* Operators
*/
public method operator group takes nothing returns group
return Groups[CurrentIndex[this]]
endmethod
/*
* Public methods
*/
public static method create takes nothing returns thistype
local thistype this=thistype.allocate()
set BaseIndex[this]=((this-1)*2)
set CurrentIndex[this]=BaseIndex[this]
set Groups[BaseIndex[this]]=NewGroup()
set Groups[BaseIndex[this]+1]=NewGroup()
set NextIndex[BaseIndex[this]]=BaseIndex[this]+1
set NextIndex[BaseIndex[this]+1]=BaseIndex[this]
return this
endmethod
public static method fromGroup takes group g returns thistype
local thistype this=thistype.create()
local unit u
loop
set u=FirstOfGroup(g)
exitwhen u==null
call GroupRemoveUnit(g,u)
call GroupAddUnit(Groups[CurrentIndex[this]],u)
endloop
return this
endmethod
public method destroy takes nothing returns nothing
call ReleaseGroup(Groups[BaseIndex[this]])
call ReleaseGroup(Groups[BaseIndex[this]+1])
call this.deallocate()
endmethod
public method add takes unit u returns nothing
call GroupAddUnit(Groups[CurrentIndex[this]],u)
endmethod
public method remove takes unit u returns nothing
call GroupRemoveUnit(Groups[CurrentIndex[this]],u)
endmethod
public method contains takes unit u returns boolean
return IsUnitInGroup(u,Groups[CurrentIndex[this]])
endmethod
public method clear takes nothing returns nothing
call GroupClear(Groups[CurrentIndex[this]])
endmethod
public method refresh takes nothing returns nothing
set TempIndex=CurrentIndex[this]
call GroupClear(Groups[NextIndex[TempIndex]])
call ForGroup(Groups[TempIndex],function thistype.refreshCallback)
call GroupClear(Groups[TempIndex])
set CurrentIndex[this]=NextIndex[TempIndex]
endmethod
public method getNext takes nothing returns unit
set TempIndex=CurrentIndex[this]
set TempUnit=FirstOfGroup(Groups[TempIndex])
if (TempUnit!=null) then
call GroupRemoveUnit(Groups[TempIndex],TempUnit)
call GroupAddUnit(Groups[NextIndex[TempIndex]],TempUnit)
else
set CurrentIndex[this]=NextIndex[TempIndex]
endif
return TempUnit
endmethod
endstruct
module SGEnumBegin
public static method enumerate takes SwappedGroup enumGroup returns nothing
local unit enumUnit
set TempIndex=CurrentIndex[enumGroup]
loop
set enumUnit=FirstOfGroup(Groups[TempIndex])
exitwhen enumUnit==null
call GroupRemoveUnit(Groups[TempIndex],enumUnit)
call GroupAddUnit(Groups[NextIndex[TempIndex]],enumUnit)
endmodule
module SGEnumEnd
endloop
set CurrentIndex[enumGroup]=NextIndex[TempIndex]
endmethod
endmodule
endlibrary
JASS:
struct TestModule extends array
private static SwappedGroup g1
private static SwappedGroup g2
implement SGEnumBegin
call BJDebugMsg("- "+GetHeroProperName(enumUnit))
implement SGEnumEnd
private static method test takes nothing returns nothing
call ClearTextMessages()
call BJDebugMsg("Units in g1:")
call thistype.enumerate(g1)
call BJDebugMsg("\nUnits in g2:")
call thistype.enumerate(g2)
endmethod
private static method refresh takes nothing returns nothing
call g1.refresh()
call g2.refresh()
endmethod
private static method onInit takes nothing returns nothing
local unit u=CreateUnit(Player(0),'Hpal',0.,0.,0.)
set thistype.g1=SwappedGroup.create()
set thistype.g2=SwappedGroup.create()
call thistype.g1.add(u)
call thistype.g2.add(u)
set u=CreateUnit(Player(0),'Hamg',0.,0.,0.)
call thistype.g2.add(u)
set u=CreateUnit(Player(0),'Hmkg',0.,0.,0.)
call thistype.g2.add(u)
set u=CreateUnit(Player(0),'Hblm',0.,0.,0)
call thistype.g2.add(u)
call TimerStart(CreateTimer(),1.,true,function thistype.test)
call TimerStart(CreateTimer(),10.5,true,function thistype.refresh)
endmethod
endstruct
1.0
- Initial release
- Added new modules to support "direct" enumerations.
- Alloc is no longer required.
- Added two new methods: "refresh", "contains".
- Group indexes are now stored in a temporary global variable, nearly halving the number of array reads in module based enumerations.
- "addUnit" renamed to "add".
- "removeUnit" renamed to "remove".
- New operator: "group".
Attachments
Last edited: