quraji
zap
- Reaction score
- 144
HandleGroup
What is it?
This is a library which contains a textmacro. This textmacro allows you to create a new 'group' with any handle you like. Units thought they were special because they were the only ones that got groups. No more! If you want a lightninggroup, so be it. Want a triggergroup? Be my guest.
How do I use it?
Run the text macro, and use the resulting struct type as if it were a new group type (with the supplied functions).
The Code:
JASS:
library HandleGroup
/* by quraji v1.03
This library enables you to create your own group of any handle!
The implemention is very simple. Just run the below textmacro where
you want your new struct.
Ex:
//! runtextmacro CreateHandleGroup("lightning", "Lightning", "private", "8190")
"lightning" is the handle type. This can be any handle type.
"Lightning" is the desired name of that handle (for the methods/functions)
"private" is the scope. This can be "private", "public" or "" for no scope
"8190" is the number of possible struct instances (8190 is the default for vJass)
-You can increase this to any number, at the cost of some performance.
Method Definitions (x is the handle type, and X is the handle name):
method forGroup takes code e returns nothing
This is the equivalent of the ForGroup for units. This uses a function interface instead of code.
e is the function to call for each handle in the group. Pass the name of any function that takes nothing and returns nothing
You may use EnumHandleX or GetEnumHandleX() in e to refer to the enum handle
Ex:
call myhandlegroup.forGroup(myfunc)
method clear takes nothing returns nothing
This clears the handle group, but does not destroy it.
method refresh takes nothing returns nothing
Removes null handles from the group
method getRandomX takes nothing returns x
Returns a random handle from the group
method firstOfGroup takes nothing returns x
This returns the first handle of the group.
method isXInGroup takes x h returns boolean
Returns true if handle h is in the group, else false.
method addX takes x h returns nothing
Add a handle to the group.
method removeX takes x h returns nothing
Remove a handle from the group.
There are also WC3 style function wrappers at the bottom, but I wont list them. (just look..this comment block is big enough already..)
*/
//! textmacro CreateHandleGroup takes handle, name, scope, size
globals
$scope$ $handle$ EnumHandle$name$
endglobals
$scope$ struct $handle$group [$size$]
private $handle$group last = 0
private $handle$group prev = 0
private $handle$group next = 0
private $handle$ h
private integer count = 0
private method unlink takes nothing returns nothing
set this.prev.next = this.next
set this.next.prev = this.prev
set this.last = this
call this.destroy()
endmethod
/* for every handle in the group, call e
use EnumHandleX or GetEnumHandleX to get the handle in the callback function, where X is the handle name
Ex: set l = GetEnumHandleLightning()
set l = EnumHandleLightning
remember that function e must take nothing and return nothing
*/
method forGroup takes enumfunc e returns nothing
local $handle$group hg
if (this.last!=this) then
set hg = this.last
loop
exitwhen (hg==this)
set EnumHandle$name$ = hg.h
call e.execute()
set hg = hg.prev
endloop
endif
endmethod
// clear the handle group
method clear takes nothing returns nothing
local $handle$group hg
local $handle$group temp
if (this.last!=this) then
set hg = this.last
loop
exitwhen (hg==this)
set temp = hg.prev
set hg.last = hg
call hg.destroy()
set hg = temp
endloop
endif
endmethod
method refresh takes nothing returns nothing
local $handle$group hg = this.last
loop
exitwhen (hg==this)
if (hg.h==null) then
call hg.unlink()
set this.count = this.count-1
endif
set hg = hg.prev
endloop
endmethod
// return the first handle of the group
method firstOfGroup takes nothing returns $handle$
return this.next.h
endmethod
method getRandom takes nothing returns $handle$
local integer i = 1
local integer rand = GetRandomInt(1, .count)
local $handle$group hg = this.next
loop
exitwhen (i==rand)
set hg = hg.next
set i = i+1
endloop
return hg.h
endmethod
// return true if the handle exists in the handle group
method isInGroup takes $handle$ h returns boolean
local $handle$group hg
if (h!=null) then
set hg = this.last
loop
exitwhen (hg==this)
if (hg.h==h) then
return true
endif
set hg = hg.prev
endloop
endif
return false
endmethod
method getCount takes nothing returns integer
return this.count
endmethod
// add a handle to the handle group
method add takes $handle$ h returns nothing
local $handle$group hg
if (h!=null and .isInGroup(h)==false) then
set hg = $handle$group.allocate()
set hg.prev = this.last
set hg.prev.next = hg
set this.last = hg
set hg.h = h
set this.count = this.count+1
endif
endmethod
// remove a handle from the group
method remove takes $handle$ h returns nothing
local $handle$group hg
if (h!=null) then
set hg = this.next
loop
exitwhen (hg==this.last)
if (hg.h==h) then
call hg.unlink()
set this.count = this.count-1
exitwhen (true)
endif
set hg = hg.next
endloop
endif
endmethod
static method create takes nothing returns $handle$group
local $handle$group hg = $handle$group.allocate()
set hg.last = hg
return hg
endmethod
private method onDestroy takes nothing returns nothing
local $handle$group hg
local $handle$group temp
if (this.last!=this) then // if the destroyed handle group is a list, depopulate it
set hg = this.last
loop
exitwhen (hg==this)
set temp = hg.prev
call hg.destroy()
set hg = temp
endloop
endif
set this.h = null
endmethod
endstruct
// WC3 style functions
$scope$ function Create$name$Group takes nothing returns $handle$group
return $handle$group.create()
endfunction
$scope$ function Destroy$name$Group takes $handle$group hg returns nothing
call hg.destroy()
endfunction
$scope$ function Refresh$name$Group takes $handle$group hg returns nothing
call hg.refresh()
endfunction
$scope$ function Clear$name$Group takes $handle$group hg returns nothing
call hg.clear()
endfunction
$scope$ function $name$GroupAdd$name$ takes $handle$group hg, $handle$ h returns nothing
call hg.add(h)
endfunction
$scope$ function $name$GroupRemove$name$ takes $handle$group hg, $handle$ h returns nothing
call hg.remove(h)
endfunction
$scope$ function Is$name$In$name$Group takes $handle$group hg, $handle$ h returns boolean
return hg.isInGroup(h)
endfunction
$scope$ function Count$name$sIn$name$Group takes $handle$group hg returns integer
return hg.getCount()
endfunction
$scope$ function FirstOf$name$Group takes $handle$group hg returns $handle$
return hg.firstOfGroup()
endfunction
$scope$ function For$name$Group takes $handle$group hg, enumfunc e returns nothing
call hg.forGroup(e)
endfunction
//! endtextmacro
function interface enumfunc takes nothing returns nothing
endlibrary
You could have done X better.
Please, if something could be better, tell me :thup:
Change Log
v1.03
Changed some method names to make them smaller (easier to type). They're no longer explicit of what they do..but you'll manage.
Also removed an unneeded variable, thanks to J4L for pointing that out.
v1.02
Fixed a few typos. Added missing WC3 style functions. Changed the method naming convention to start with lower case. All these thanks to kenny!
Switched back to function interfaces after I realized they're simpler.
v1.01
I changed .ForGroup to use code instead of a function interface. I'm not sure why it did in the first place anyways.
Changed some method names to make them smaller (easier to type). They're no longer explicit of what they do..but you'll manage.
Also removed an unneeded variable, thanks to J4L for pointing that out.
v1.02
Fixed a few typos. Added missing WC3 style functions. Changed the method naming convention to start with lower case. All these thanks to kenny!
Switched back to function interfaces after I realized they're simpler.
v1.01
I changed .ForGroup to use code instead of a function interface. I'm not sure why it did in the first place anyways.