Snippet QueueStack

Nestharus

o-o
Reaction score
84
graveyard this please, didn't work for what I wanted it to work for, so rather useless. Coming up with something else instead

The QueueStack

JASS:

library QueueStack /* v2.0.0.0
*******************************************************************
*
*   Imagine a list where every position on it acts like a stack, where
*   those stacks point to other lists that have more stacks.
*
*******************************************************************
*   module QueueStack
*******************************************************************
*   static method allocate takes nothing returns thistype
*       Returns the head for the entire object.
*
*   method deallocate takes nothing returns nothing
*       Destroys the entire structure given the head
*
*   method add takes nothing returns thistype
*       Adds a cell to the cell
*
*   method start takes nothing returns thistype
*       Creates a new looper for the QueueStack.
*
*   method end takes nothing returns nothing
*       Destroys a looper for a QueueStack. Only used when not looping
*       through the entire QueueStack. The looper is automatically destroyed
*       if the entire QueueStack is looped through. This could be useful for value
*       searches where looping through the rest of the QueueStack is pointles.
*
*   method operator get takes nothing returns thistype
*       Retrieves the next value in the QueueStack given a looper.
*
*       Example:
*           function Test takes QueueStack q returns nothing
*               local QueueStack looper = q.start()     //create a new looper
*               local QueueStack node
*
*               loop
*                   set node = looper.get       //get the next node
*                   exitwhen node == 0          //exitwhen the node is null
*
*                   //code
*                   call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, I2S(o))
*               endloop
*           endfunction
*
*******************************************************************/
    module QueueStack
        private static integer array nn         //next node
        private static integer array nf         //first node
        
        private static integer array np         //next pointer (right)
        private static integer array lp         //last pointer (right)
        
        private static integer array nr         //next row (pointer only)
        private static integer array lr         //last row (pointer only)
        
        private static integer ic = 0           //instance count
        private static integer array rc         //recycler
        
        debug private static boolean array a    //is allocated
        debug private static boolean array h    //is head
        
        debug private static boolean array sp   //structure pointer
        
        debug private static integer array ns   //next stack
    
        //can only add rows to current object
        static method allocate takes nothing returns thistype
            local thistype n
            
            //allocate head
            if (rc[0] == 0) then
                set n = ic + 1
                set ic = n
            else
                set n = rc[0]
                set rc[0] = rc[n]
            endif
            debug set a[n] = true
            debug set h[n] = true
            
            set np[n] = 0        //next column is 0
            set nr[n] = 0        //next row is 0
            set nn[n] = 0
            set nf[n] = n
            
            return n
        endmethod
        
        method add takes nothing returns thistype
            local thistype n = 0
            local thistype p
            
            debug if (a[this] and not sp[this]) then
                set this = nf[this]
            
                //allocate node
                if (rc[0] == 0) then
                    set n = ic + 1
                    set ic = n
                else
                    set n = rc[0]
                    set rc[0] = rc[n]
                endif
                debug set a[n] = true
                
                //allocate pointer
                if (rc[0] == 0) then
                    set p = ic + 1
                    set ic = p
                else
                    set p = rc[0]
                    set rc[0] = rc[p]
                endif
                debug set a[p] = true
                debug set sp[p] = true
                set nr[p] = 0       //next row is 0
                set np[p] = 0       //next column is 0
                set nf[n] = p
                
                if (np[this] == 0) then
                    //if nothing to the right, expand
                    set nf[p] = nf[this]
                    set np[this] = p
                    set lr[this] = p
                    set nn[p] = 0
                    set p = nf[p]
                    set nn[n] = nn[p]
                    set nn[p] = n
                else
                    //otherwise, add
                    set nr[lr[this]] = p
                    set lr[this] = p
                    set nf[p] = p
                    set nn[n] = 0
                    set nn[p] = n
                endif
                
                return n
            debug else
                debug if (a[this]) then
                    debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "QUEUE STACK ERROR: ATTEMPTED TO MANIPULATE STRUCTURE NODE")
                debug else
                    debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "QUEUE STACK ERROR: ATTEMPTED TO MANIPULATE NULL NODE")
                debug endif
            debug endif
            
            debug return 0
        endmethod
        
        method deallocate takes nothing returns nothing
            local thistype array r              //row pointer
            local thistype array s              //column node
            local thistype p = this             //pointer
            
            local thistype n = p                //node
            
            local integer c = 0                 //column
            local integer i = 0                 //row
            
            debug if (h[p]) then
                debug set h[p] = false
                debug set a[n] = false
                set rc[p] = rc[0]
                set rc[0] = p
                loop
                    if (np[p] == 0) then
                        //if there is nothing to the right, then go down
                        loop
                            //go left until can go down or all the way left
                            exitwhen nr[p] != 0 or c == 0
                            set c = c - 1
                            set p = r[c]
                        endloop
                        
                        set p = nr[p]
                        set r[c] = p
                        set n = nn[p]
                        set s[p] = n
                    else
                        //go right
                        set c = c + 1   //go to next column
                        set p = np[p]
                        set r[c] = p    //update next column
                        set n = nn[n]
                        set s[p] = n
                    endif
                    
                    exitwhen p == 0
                    
                    debug set a[p] = false
                    debug set a[n] = false
                    
                    //destroy
                    set rc[p] = rc[0]
                    set rc[0] = p
                    set rc[n] = rc[0]
                    set rc[0] = n
                endloop
            debug else
                debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "QUEUE STACK ERROR: ATTEMPT TO DESTROY NON HEAD " + I2S(n))
            debug endif
        endmethod
        
        //looper
        private static thistype il = 0      //loop instance count
        private static thistype array rl    //loop recycler
        
        private thistype r_l                //row pointer
        private static thistype array s_l   //column node
        private thistype p_l                //pointer
        private thistype n_l                //node
        private thistype c_l                //column
        private thistype i_l                //row
        debug private boolean o_l           //is loop open
        
        method start takes nothing returns thistype
            local thistype l = 0
            
            debug if (h[this]) then
                if (rl[0] == 0) then
                    set il = il + 1
                    set l = il
                else
                    set l = rl[0]
                    set rl[0] = rl[l]
                endif
                
                set l.c_l = 0
                set l.i_l = 0
                set l.p_l = this
                set l.n_l = this
                debug set l.o_l = true
                
                return l
            debug else
                debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "QUEUE STACK ERROR: ATTEMPT TO LOOP NON HEAD " + I2S(this))
            debug endif
            debug return 0
        endmethod
        
        method operator get takes nothing returns thistype
            debug if (o_l) then
                if (np[p_l] == 0) then
                    //if there is nothing to the right, then go down
                    loop
                        //go left until can go down or all the way left
                        exitwhen nr[p_l] != 0 or c_l == 0
                        set rl[c_l] = rl[0]
                        set rl[0] = c_l
                        set c_l = c_l.c_l
                        set p_l = c_l.r_l
                    endloop
                    
                    set p_l = nr[p_l]
                    set c_l.r_l = p_l
                    set n_l = nn[p_l]
                    set s_l[p_l] = n_l
                else
                    //go right
                    if (rl[0] == 0) then
                        set il = il + 1
                        set il.c_l = c_l
                        set c_l = il
                        set c_l = c_l
                    else
                        set rl[0].c_l = c_l
                        set c_l = rl[0]
                        set rl[0] = rl[c_l]
                    endif
                    
                    set p_l = np[p_l]
                    set c_l.r_l = p_l
                    set n_l = nn[n_l]
                    set s_l[p_l] = n_l
                endif
                
                if (p_l == 0) then
                    set rl[this] = rl[0]
                    set rl[0] = this
                    debug set o_l = false
                endif
                
                return n_l
            debug else
                debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "QUEUE STACK LOOP ERROR: LOOP NOT OPEN")
            debug endif
            debug return 0
        endmethod
        
        method end takes nothing returns nothing
            local thistype c = c_l
            debug if (o_l) then
                debug set o_l = false
                set rl[this] = rl[0]
                set rl[0] = this
                loop
                    exitwhen c == 0
                    set rl[c] = rl[0]
                    set rl[0] = c
                    set c = c.c_l
                endloop
            debug else
                debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "QUEUE STACK LOOP ERROR: LOOP NOT OPEN")
            debug endif
        endmethod
    endmodule
endlibrary


Demo
JASS:

//! textmacro CREATE_ROW takes ROW_NUM
    local thistype r$ROW_NUM$_1 = r$ROW_NUM$.add()
    local thistype r$ROW_NUM$_2 = r$ROW_NUM$.add()
    local thistype r$ROW_NUM$_3 = r$ROW_NUM$.add()
    local thistype r$ROW_NUM$_4 = r$ROW_NUM$.add()
    local thistype r$ROW_NUM$_5 = r$ROW_NUM$.add()
//! endtextmacro

//! textmacro INI_ROW takes ROW_NUM
    set r$ROW_NUM$_1.v = ($ROW_NUM$)*5+1
    set r$ROW_NUM$_2.v = ($ROW_NUM$)*5+2
    set r$ROW_NUM$_3.v = ($ROW_NUM$)*5+3
    set r$ROW_NUM$_4.v = ($ROW_NUM$)*5+4
    set r$ROW_NUM$_5.v = ($ROW_NUM$)*5+5
    set r$ROW_NUM$_1.id = 0
    set r$ROW_NUM$_2.id = 1
    set r$ROW_NUM$_3.id = 1
    set r$ROW_NUM$_4.id = 1
    set r$ROW_NUM$_5.id = 1
//! endtextmacro

struct ttt extends array
    implement QueueStack
    integer v
    integer id
    
    //loop with module
    private method test takes nothing returns nothing
        local thistype looper = start()
        local thistype node
        local integer i = 0
        local integer a = 0
        local string s = ""
        loop
            set node = looper.get
            exitwhen node == 0
            
            if (node.id > i) then
                set i = node.id
                set s = s + "\n"
                set a = i
                loop
                    exitwhen a == 0
                    set s = s + "    "
                    set a = a - 1
                endloop
            elseif (node.id < i) then
                set s = s + "\n"
                set i = node.id
            endif
            
            set s = s + I2S(node.v) + ","
        endloop
        set s = s + "\n-------------------------------"
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, s)
    endmethod
    
    private static method run takes nothing returns nothing
        local thistype this = allocate()
        local thistype r1 = add()
        local thistype r2 = add()
        local thistype r3 = add()
        local thistype r4 = add()
        local thistype r5 = add()
        //! runtextmacro CREATE_ROW("1")
        //! runtextmacro CREATE_ROW("2")
        //! runtextmacro CREATE_ROW("3")
        //! runtextmacro CREATE_ROW("4")
        //! runtextmacro CREATE_ROW("5")
        
        //! runtextmacro INI_ROW("1")
        //! runtextmacro INI_ROW("2")
        //! runtextmacro INI_ROW("3")
        //! runtextmacro INI_ROW("4")
        //! runtextmacro INI_ROW("5")
        
        set r1.v = 1
        set r2.v = 2
        set r3.v = 3
        set r4.v = 4
        set r5.v = 5
        set r1.id = 1
        set r2.id = 1
        set r3.id = 1
        set r4.id = 1
        set r5.id = 1
        
        call test()
        call deallocate()
        
        call DestroyTimer(GetExpiredTimer())
    endmethod
    
    private static method onInit takes nothing returns nothing
        call TimerStart(CreateTimer(), 0, false, function thistype.run)
    endmethod
endstruct
 

Nestharus

o-o
Reaction score
84
Again, as the thing implies, it's more for super optimal save/load codes. I probably wouldn't use the snippet itself, but the loop algorithm and the structure comes in handy when trying to code the stuff, so referring to those code is helpful. Actually, when I was initially coding Encoder 2.0.0.0, I had this identical algorithm for looping, but a QueueQueue data structure ;|. Kind of coded it out as a library to refer to ;P.

This is the best data structure for the most optimal save/load codes possible =), so I'm sure that other people can refer to it too ;p.
 

Nestharus

o-o
Reaction score
84
Updated to 2.0.0.0

Yea, no pointers in this one and no macros, you have to use a looper. The loop is too complicated and hard to understand : |.

A properly working QueueStack is infinitely more complex to design than a QueueQueue
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top