• 🏆 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!

QueueStack

Level 31
Joined
Jul 10, 2007
Messages
6,306
Graveyard this, it doesn't do what it sets out to do. It works 100%, but it's useless, need to code a ListStack to get it working right

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
                endif
                debug set a = true
                debug set sp = true
                set nr = 0       //next row is 0
                set np = 0       //next column is 0
                set nf[n] = p
                
                if (np[this] == 0) then
                    //if nothing to the right, expand
                    set nf = nf[this]
                    set np[this] = p
                    set lr[this] = p
                    set nn = 0
                    set p = nf
                    set nn[n] = nn
                    set nn = n
                else
                    //otherwise, add
                    set nr[lr[this]] = p
                    set lr[this] = p
                    set nf = p
                    set nn[n] = 0
                    set nn = 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) then
                debug set h = false
                debug set a[n] = false
                set rc = rc[0]
                set rc[0] = p
                loop
                    if (np == 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 != 0 or c == 0
                            set c = c - 1
                            set p = r[c]
                        endloop
                        
                        set p = nr
                        set r[c] = p
                        set n = nn
                        set s = n
                    else
                        //go right
                        set c = c + 1   //go to next column
                        set p = np
                        set r[c] = p    //update next column
                        set n = nn[n]
                        set s = n
                    endif
                    
                    exitwhen p == 0
                    
                    debug set a = false
                    debug set a[n] = false
                    
                    //destroy
                    set rc = 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
 
Last edited:
Top