• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Groups

Level 11
Joined
Apr 29, 2007
Messages
826
This is a basic library which allows you to create groups of nearly everything. Some simple functions like first of group, last of group, for group etc are added.
You do not have any limit at the size of the group, neither at the number of groups, since I'm using a hashtable instead of an array.
JASS:
library_once Groups

    //! textmacro Group takes TYPE, NAME
        
        interface $NAME$Face
            method doOnInit takes nothing returns nothing defaults nothing
            method doOnDestroy takes nothing returns nothing defaults nothing
            method doOnAdd takes nothing returns nothing defaults nothing
            method doOnRemove takes nothing returns nothing defaults nothing
            method doOnForGroup takes nothing returns nothing defaults nothing
            method doOnClear takes nothing returns nothing defaults nothing
        endinterface
        
        struct $NAME$Group extends $NAME$Face
        
            readonly integer $NAME$Count = 0
            readonly static $TYPE$ Enum$NAME$ = null
            readonly static hashtable hash = InitHashtable()
            
            static method create takes nothing returns $NAME$Group
                local $NAME$Group this = $NAME$Group.allocate()
                call .doOnInit()
                return this
            endmethod
            
            method add takes $TYPE$ var returns nothing
                call Save$NAME$Handle(.hash, .$NAME$Count, this, var)
                call SaveInteger(.hash, GetHandleId(var), this, .$NAME$Count)
                set .$NAME$Count = .$NAME$Count+1
                call .doOnAdd()
            endmethod
            
            method remove takes $TYPE$ var returns nothing
                local integer max = LoadInteger(.hash, GetHandleId(var), this)
                local integer i = max
                local $TYPE$ temp
                loop
                    exitwhen i > max
                    set temp = Load$NAME$Handle(.hash, i+1, this)
                    call Save$NAME$Handle(.hash, i, this, temp)
                    call SaveInteger(.hash, GetHandleId(Load$NAME$Handle(.hash, i, this)), this, i)
                    set i = i+1
                endloop
                set .$NAME$Count = .$NAME$Count-1
                call .doOnRemove()
            endmethod
            
            method find takes $TYPE$ var returns integer
                return LoadInteger(.hash, GetHandleId(var), this)
            endmethod
            
            method firstOfGroup takes nothing returns $TYPE$
                return Load$NAME$Handle(.hash, 0, this)
            endmethod
            
            method lastOfGroup takes nothing returns $TYPE$
                return Load$NAME$Handle(.hash, .$NAME$Count, this)
            endmethod
            
            method isInGroup takes $TYPE$ var returns boolean
                local integer i = 0
                loop
                    exitwhen i >= .$NAME$Count
                    if Load$NAME$Handle(.hash, i, this) == var then
                        return true
                    endif
                    set i = i+1
                endloop
                return false
            endmethod
            
            method countInGroup takes nothing returns integer
                return .$NAME$Count
            endmethod
            
            method clear takes nothing returns nothing
                local integer i = 0
                call .doOnClear()
                loop
                    exitwhen i >= .$NAME$Count
                    call FlushChildHashtable(.hash, GetHandleId(Load$NAME$Handle(.hash, i, this)))
                    call FlushChildHashtable(.hash, i)
                    set i = i+1
                endloop
                set .$NAME$Count = 0
            endmethod
            
            method forGroup takes code ex returns nothing
                local integer i = 0
                local trigger t = CreateTrigger()
                loop
                    exitwhen i >= .$NAME$Count
                    set .Enum$NAME$ = Load$NAME$Handle(.hash, i, this)
                    call .doOnForGroup()
                    call TriggerAddAction(t, ex)
                    call TriggerExecute(t)
                    call TriggerClearActions(t)
                    set i = i+1
                endloop
                set .Enum$NAME$ = null
            endmethod
            
            method getRandom takes nothing returns $TYPE$
                return Load$NAME$Handle(.hash, GetRandomInt(0,.$NAME$Count), this)
            endmethod
            
            method onDestroy takes nothing returns nothing
                local integer i = 0
                call .doOnDestroy()
                loop
                    exitwhen i >= .$NAME$Count
                    call FlushChildHashtable(.hash, GetHandleId(Load$NAME$Handle(.hash, i, this)))
                    call FlushChildHashtable(.hash, i)
                    set i = i+1
                endloop
            endmethod
            
        endstruct
        
        function Create$NAME$Group takes nothing returns $NAME$Group
            return $NAME$Group.create()
        endfunction
        
        function Destroy$NAME$Group takes $NAME$Group g returns nothing
            call g.destroy()
        endfunction
        
        function Add$NAME$ToGroup takes $NAME$Group g, $TYPE$ var returns nothing
            call g.add(var)
        endfunction
        
        function Remove$NAME$FromGroup takes $NAME$Group g, $TYPE$ var returns nothing
            call g.remove(var)
        endfunction
        
        function Find$NAME$ takes $NAME$Group g, $TYPE$ var returns integer
            return g.find(var)
        endfunction
        
        function FirstOf$NAME$Group takes $NAME$Group g returns $TYPE$
            return g.firstOfGroup()
        endfunction
        
        function LastOf$NAME$Group takes $NAME$Group g returns $TYPE$
            return g.lastOfGroup()
        endfunction
        
        function Is$NAME$InGroup takes $NAME$Group g, $TYPE$ var returns boolean
            return g.isInGroup(var)
        endfunction
        
        function Count$NAME$sInGroup takes $NAME$Group g returns integer
            return g.countInGroup()
        endfunction
        
        function Clear$NAME$Group takes $NAME$Group g returns nothing
            call g.clear()
        endfunction
        
        function For$NAME$sInGroup takes $NAME$Group g, code ex returns nothing
            call g.forGroup(ex)
        endfunction
        
        function GetRandom$NAME$FromGroup takes $NAME$Group g returns $TYPE$
            return g.getRandom()
        endfunction
        
        function GetEnum$NAME$OfGroup takes nothing returns $TYPE$
            return $NAME$Group.Enum$NAME$
        endfunction
        
    //! endtextmacro
    
        //! runtextmacro Group("texttag", "TextTag")
        //! runtextmacro Group("item", "Item")
        //! runtextmacro Group("effect", "Effect")
        //! runtextmacro Group("timer", "Timer")
    
endlibrary
 
Last edited:
Level 11
Joined
Feb 22, 2006
Messages
752
Yeah, I'm inclined to graveyard this since there's already existing versions of this.

But before I do, I just want to point out a few things (that might help you in the future):

There's no excuse to be using linear searches if you're backing a group with a hashtable.

A linked list would probably have been a better implementation for this rather than an array.

Using function interfaces to run a function is better than running code with TriggerExecute.
 
Top