• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

[snippet] DoubleGroup

Level 6
Joined
Jun 20, 2011
Messages
249
Fully reusable FirstOfGroup loops with highest possible speed.
JASS:
//! zinc
library DoubleGroup{

//  Allows FirstOfGroup loops to run multiple times on the same
//  group.
/**********************************************************************

    API
    
    struct DoubleGroup
//  Manages groups that have a backup group to store removed units through
//  FirstOfGroup loops.
--->
        static method create takes nothing returns DoubleGroup
    //      allocates new DoubleGroup
    
        method destroy takes nothing returns nothing
    //      deallocates the DoubleGroup
    
        readonly group handle
    //      returns the actual unit group
        
        readonly unit FirstOfGroup
    //      Don't read more than 1 per loop, returns a different unit every
    //      time. Will return null when the loop is over, after that it's
    //      fully reusable in the next loop.
    
**********************************************************************/

    integer n=0;
    integer m=0;
    integer r[];
    group   g[];
    
    struct DoubleGroup[]{
        private{
        group   g1;
        group   g2;
        boolean gc;}
        
        method operator handle()->group{
            if(this.gc) return this.g1;
            else        return this.g2;}
        
        private method operator second()->group{
            if(this.gc) return this.g2;
            else        return this.g1;}
            
        method operator FirstOfGroup()->unit{
            unit    u;
            u=FirstOfGroup(this.handle);
            if(null==u) this.gc=!(this.gc);
            else{
                GroupAddUnit(this.second,u);
                GroupRemoveUnit(this.handle,u);}
            return u;}
                
        static method create()->thistype{
            thistype this;
            if(0==r[0]){
                m+=1;
                this=m;}
            else{
                this=r[0];
                r[0]=r[r[0]];}
            if(n>0){
                n-=2;
                this.g1=g[n];
                this.g2=g[n+1];}
            else{
                this.g1=CreateGroup();
                this.g2=CreateGroup();}
            return this;}
            
        method destroy(){
            r[this]=r[0];
            r[0]=this;
            GroupClear(this.g1);
            GroupClear(this.g2);
            g[n]=this.g1;
            g[n+1]=this.g2;
            n+=2;}}}
//! endzinc
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
First of group loop can easily and should be written "by hand", it's not that hard.
Plus, most of the time all you only need is a "static" group, such as GROUP_ENUM of GroupUtils.
You use it with a GroupEnum and null filter, and then use the first of group loop.

And when you need to keep units during time, it's not hard to use this static group with a new group, something like that :

JASS:
unit u
group g = NewGroup()
GroupEnum...(GROUP_ENUM,...,null)
loop
u = FirstOfGroup(GROUP_ENUM)
exitwhen u == null
    // do your stuff here
    GroupAddUnit(g,u)
GroupRemoveUnit(GROUP_ENUM,u)
endloop
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Yes, fixed.

Now, i suppose some tutorial about using such loops is fine, but i don't think it is worth a such resource, as it can be easily inlined.
And even with the best api it would be still more annoying to use than directly the loop.
Also there is no way that it will be faster than a direct loop, just at the best at the same speed, but probably with an ugly api.
 
Level 6
Joined
Jun 20, 2011
Messages
249
I forgot to mention that this doesn't cut up for speed after some tests i did, kill this thead.
As for the aesthetics, yea i guess it's very weird, i'll look into that if i plan to later on code on another language (zinc is dead for me now)
 
Top