• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[Snippet] IndexStack

Please check the script header for description, how to use, requirements, changelogs and more!

JASS:
// --------------------------------------------------------------------------------------------------------------------
//  
//  IndexStack
//  ===========
// 
// 	Version:	1.5.0
// 	Author:		Anachron
// 
// 	Requirements:
// 		Stack [by Anachron] (v. 1.5.0)
// 		(New) Table [by Bribe] (v. 3.1) [url]http://www.hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/[/url]
// 
// 	Description:
// 		IndexStack is a list where the user decides about the indexing.
// 		This indexing will be translated to normal indexing by magic.
// 		There are easy setter/getter methods for advanced use.
// 
// 	History:
// 		1.0.0: Initial Release
// 		1.1.0: Add of split, switch and merge
//      1.2.0: Rearranged methods, allowed same value to be twice in stack
//      1.3.0: Adapter to new API of Stack
//      1.4.0: Adopt API changes of new Stack
//      1.5.0: Adopt FunctionInterface replacement from Stack
// 
// 	API:
// 		based on Stack
//      
//      has(int id)                 --> Check if stack has id
//
//      add(int id, int val)        --> Add a new entry by id and value
//      [id] = val                  --> Same as add(x, y)
//      
//      get(int id)                 --> Return value of entry with id
//      [id]                        --> Same as get(int id)
//      
//      delete(int id)              --> Remove an entry by id
//      [id] = -1                   --> Same as delete(int id)
//      
//      id(int x)                   --> Get id by index
//      index(int x)                --> Get index by id
// 
// ---------------------------------------------------------------------------------------------------------------------------
library IndexStack requires Stack, Table

	module IsIndexStack
		private delegate    Stack	    List		    = 0
		private             Table	    IndexData		= 0
		private             Table	    IdData			= 0
        private             Table       ValueData       = 0
		
		public static method createEx takes integer max returns thistype
			local thistype this = thistype.allocate()
			set .List = Stack.createEx(max)
			set .IndexData = Table.create()
			set .IdData = Table.create()
            set .ValueData = Table.create()
			return this
		endmethod
        
        public static method create takes nothing returns thistype
            return thistype.createEx(STACK_INFINITIVE)
        endmethod
        
        public method index takes integer id returns integer
            if not .IdData.has(id) then
                return STACK_INVALID
            endif
        
            return .IdData[id]
        endmethod
        
        public method id takes integer index returns integer
            if not .IndexData.has(index) then
                return STACK_INVALID
            endif
        
            return .IndexData[index]
        endmethod
        
        public method get takes integer id returns integer
            if not .ValueData.has(id) then
                return STACK_INVALID
            endif
        
            return .ValueData[id]
        endmethod
        
        public method operator [] takes integer id returns integer
            return .get(id)
        endmethod
        
        public method add takes integer id, integer value returns boolean
            local integer index = 0
            debug local boolean print = .List.print
        
            debug set .List.print = false
        
            if .has(id) then
                return false
            endif
            
            call .List.add(id)
            set index = .List.index(id)
            
            set .IndexData[index] = id
            set .IdData[id] = index
            set .ValueData[id] = value
            
            debug if print then
                debug set STACK_MSG = STACK_COLOR + "IndexStack|r[" + STACK_COLOR+ I2S(this) + "|r]: "
                debug set STACK_MSG = STACK_MSG + "Added " + STACK_COLOR + I2S(value) + "|r" + " to [" + STACK_COLOR + I2S(id) + "|r]"
                debug call BJDebugMsg(STACK_MSG)
            debug endif
            
            debug set .List.print = print
            
            return true
        endmethod
        
        public method delete takes integer id returns boolean
            local integer index = .index(id)
            local integer value = .get(id)
            local integer lastIndex = .count -1
            local integer lastId = .id(lastIndex)
            local integer lastValue = .get(lastId)
            debug local boolean print = .List.print
        
            debug set .List.print = false
            
            if not .has(id) then
                return false
            endif
            
            call .List.delete(id)
            set lastIndex = .List.index(lastId)
            
            call .IdData.remove(id)
            call .ValueData.remove(id)
            
            if index != lastIndex then
                set .IndexData[index] = lastId
                set .IdData[lastId] = index
                //set .ValueData[lastId] = lastValue
                debug if print then
                    debug set STACK_MSG = STACK_COLOR + "IndexStack|r[" + STACK_COLOR+ I2S(this) + "|r]: "
                    debug set STACK_MSG = STACK_MSG + "Pushed #" + STACK_COLOR + I2S(lastId) + "|r" + " from [" + STACK_COLOR + I2S(lastIndex) + "|r] " 
                    debug set STACK_MSG = STACK_MSG + "to [" + STACK_COLOR + I2S(index) + "|r]"
                    debug call BJDebugMsg(STACK_MSG)
                debug endif
            else
                call .IndexData.remove(index)
                debug if print then
                    debug set STACK_MSG = STACK_COLOR + "IndexStack|r[" + STACK_COLOR+ I2S(this) + "|r]: "
                    debug set STACK_MSG = STACK_MSG + "Deleted [" + STACK_COLOR + I2S(id) + "|r] = " + STACK_COLOR + I2S(value) + "|r"
                    debug call BJDebugMsg(STACK_MSG)
                debug endif
            endif
            
            debug set .List.print = print
            
            return true
        endmethod
        
        public method operator []= takes integer id, integer value returns nothing
            if value != -1 then
                call .add(id, value)
            else
                call .delete(id)
            endif
        endmethod
        
        public method clear takes nothing returns nothing
            loop
                exitwhen .count <= 0
                
                call .delete(IndexData[.count -1])
            endloop
        endmethod
        
        public method each takes code forEach returns integer
            return .List.each(forEach)
        endmethod
        
        public method merge takes thistype toMerge returns nothing
            local integer id = 0
            local integer val = 0
        
            loop
                exitwhen toMerge.count <= 0
                
                set id = toMerge.id(toMerge.count -1)
                set val = toMerge.get(id)
                
                call .add(id, val)
                call toMerge.delete(id)
            endloop
        endmethod
        
        public method split takes thistype newStack, integer pos returns nothing
            local integer id = 0
            local integer val = 0
        
            loop
                exitwhen .count <= pos
                
                set id = .id(.count -1)
                set val = .get(id)
                
                call newStack.add(id, val)
                call .delete(id)
            endloop
        endmethod
        
        public method switch takes integer leftId, integer rightId returns boolean
            local integer leftValue = .get(leftId)
            local integer rightValue = .get(rightId)
            local integer leftIndex = 0
            local integer rightIndex = 0
            debug local boolean print = .List.print
        
            debug set .List.print = false
            
            if not .has(leftId) or not .has(rightId) then
                return false
            endif
            
            call .List.switch(leftId, rightId)
            
            set leftIndex = .List.index(leftId)
            set rightIndex = .List.index(rightId)
            
            set .IdData[leftId] = leftIndex
            set .IdData[rightId] = rightIndex
            
            debug if print then
                debug set STACK_MSG = STACK_COLOR + "Stack|r[" + STACK_COLOR+ I2S(this) + "|r]: "
                debug set STACK_MSG = STACK_MSG + "Switched [" + STACK_COLOR + I2S(leftId) + "|r] = " + STACK_COLOR + I2S(leftValue)
                debug set STACK_MSG = STACK_MSG + "|r with [" + STACK_COLOR + I2S(rightId) + "|r] = " + STACK_COLOR + I2S(rightValue) + "|r"
                debug call BJDebugMsg(STACK_MSG)
            debug endif
            
            debug set .List.print = true
            
            return true
        endmethod
        
        public method sort takes boolean asc returns nothing
            local integer index = 0
            local integer id = 0
            
            call .List.sort(asc)
            loop
                exitwhen index >= .count
                set id = .List.get(index)
                set .IndexData[index] = id
                set .IdData[id] = index
                set index = index +1
            endloop
        endmethod
	endmodule
	
	struct IndexStack
		implement IsIndexStack
	endstruct

endlibrary
 
Last edited:
So it seems this resource is a linear stack, whereas your Stack resource is a Linked List. I'm not sure if that interpretation is correct, but one thing I'm curious of is why there should be 2 separate resources that are nearly identical? Stack is approved, but I'm not sure this resource is needed since it's only a different implemtation of Stack.
 
Top