• 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.

Recycle Indexes

Level 5
Joined
Sep 13, 2007
Messages
33
Everything in the "Read Me". Please ask questions and report bugs in this thread only. Version 1.6.

Read Me:
Code:
This system can be easily used to store values on an variable. To each value an integer will be assigned, the integer will
represent the value's location (array) on the variable. By giving the array to the system you could restore the value's data.
What's special about this system is that it recycles arrays constantly, so the only way you could reach the limit is that if
you are doing something wrong, as you would rarely reach 8191 arrays if you'll recycle properly.

The system is divided to indexes. Each index has type and name that defines it. The type will determined what kind of
variables you could attach to the system. The name will change the functions' name in the index. In order to create new index
you'll need to put an action following the syntax in the bottom in the recycleIndexes library. The syntax is:

//! runtextmacro recycleIndexes("<Type>","<Name>","<Null>")

Type - The type of the values stored on the index. There is no limit to this option, all types can be used and you can assign 
       to different indexes the same type.
Name - This will affect the functions' names when used. The functions' names syntax is fucntionName<Name>. So, for example if
       you create an index with the name "Test" your functions would be: functionNameTest (functionName changes from function 
       to function obviously). You can't give two different indexes the same name, and you can't use symbols in your name.
Null - This one is simple. If the index'es type is integer or real, you put here 0, else, you put null. This is made to make
       sure WE will not syntax you, when trying to set handles to 0 or integers to null.
       
Now you need to understand how to use the system. The system is made out of 5 functions, that's it.

SetValue<Name> - This function takes the value you want to store (type depends on the index) and returns an integer. The 
                 integer returned is the location (array) of the value in the index.
GetValue<Name> - Takes an integer and a boolean and returns a value (type depend on the index). The value returned will be the
                 value stored in the array given. If you give true as the boolean, the array will be cleaned, and later it 
                 could be recycled.
GetArray<Name> - Takes a value and returns the array that points to it in the index. If the same value is stored twice on the
                 same index with different arrays the one with the smaller array will always be returned.
GetIndexMax<Name> - Returns the biggest array used by the index.
GetNextArray<Mame> - Returns the next array that will be used in the index.

How to import the system:

    A) Make sure you have NewGen, this system can't work in regular WE it, requires NewGen pack.
    B) Copy the Recycle Indexes trigger to your map.
    
Pros:
- This is a very user friendly system. It is easy to use, flexible and, all the information you called possibly need can be
  refered to easily.
- This is a safe system, it is hard to do mistakes while using it, and if you ever do some mistake, the system will warn you
  if you have debug mode on.


Cons
- The pointers to the values are integers, which are less comfortable than strings.
- Limit of 8191 arrays per index, but this limit is unrealisitc as you'll almost never reach this limit. Also, you may have
  as many indexes as you wish.
- Jass system only, GUIers can't use this system in any way.
- There are a few problems when using integers or reals, the biggest one regards recycling. The easy solution would be 
  creating more indexes instead of recycling.

That is it. There is an example trigger posted that shows how you can use each one of the functions.

This system have been tested many times, however, if you spot bugs / problems / leaks please let me know! All questions are
welcomed as well.

v1.6 - Example Trigger rewritten.

v1.5 - Function GetArray added!
     - Example trigger updated.

v1.4 - Small code fix.

v1.3 - Example trigger improved.
     - Recycling works better now.

v1.2 - Read Me updated.
     - A few code changes.
     - Big changes to the comments.

v1.1 - GetNextArray added.
     - Comments were updated.
     - Read Me was re-written.
     - A few minor code changes.
     
v1.0 - Initial release of the system.

Code:
JASS:
library recycleIndexes

//! textmacro recycleIndexes takes type, name, null

globals
    private $type$ array index$name$ // The variable that holds all the values on it.
    private integer array recycle$name$ // All arrays that can be recycled are stored here.
    private integer recycleMax$name$ = 0 // Stores the number of arrays that can be recycled.
    private integer indexMax$name$ = 0 // Biggest array on index currently.
    private boolean new$name$ = true // Will determine if a new array needs to be created, or if we can recycle.
endglobals

// Returns the currently biggest array used.
function GetIndexMax$name$ takes nothing returns integer
    return indexMax$name$ - 1
endfunction

// Returns the next array that will be used. Differently from GetIndexMax, this function takes recycling into consideration.
function GetNextArray$name$ takes nothing returns integer 
    if recycle$name$[0] == 0 then
        return indexMax$name$
    endif
    return recycle$name$[0]
endfunction

// Takes an array and returns the value it points to. If the function will take true it will clean the array so it could be
// recycled later.
function GetValue$name$ takes integer loc, boolean remove returns $type$
    local integer c = 0
    local $type$ temp = $null$

    if index$name$[loc] == $null$ then // The array isn't used.
        debug call BJDebugMsg("Index isn't used!")
        return $null$
    endif
    
    if remove then // Should the array be cleared?
        if loc < indexMax$name$ then // Do we need to do it in the hard way?
            set temp = index$name$[loc]
            set index$name$[loc] = $null$
            set new$name$ = false
            set recycle$name$[recycleMax$name$] = loc
            set recycleMax$name$ = recycleMax$name$ + 1
            return temp
        elseif loc == indexMax$name$ then // We can do it the easy way!
            set indexMax$name$ = indexMax$name$ - 1
            return index$name$[loc]
        else // Index doesn't exist!
            debug call BJDebugMsg("Index isn't used!")
        endif
    endif

    return index$name$[loc]
endfunction

// Takes a value and returns the array pointing to it.
function SetValue$name$ takes $type$ value returns integer
    if new$name$ then // Use a new index, or recycle an old one?
        set index$name$[indexMax$name$] = value
        set indexMax$name$ = indexMax$name$ + 1
        
        if indexMax$name$ == 8192 then // Limit reached!
            debug call BJDebugMsg("8191 indexes used, limit reached")
        elseif indexMax$name$ == 8193 then // Limit passed!
            debug call BJDebugMsg("Too many values attached! Recycle!")
        endif
        
        return indexMax$name$ - 1
    else // We can recycle an old array.
        set recycleMax$name$ = recycleMax$name$ - 1
        set index$name$[recycle$name$[recycleMax$name$]] = value
        
        if recycleMax$name$ == 0 then // We recycled everything we can.
            set new$name$ = true
        endif
        
        return recycle$name$[recycleMax$name$]
    endif
    
    return 0
endfunction

// Takes a value and returns the array it is stored in.
function GetArray$name$ takes $type$ value returns integer
    local integer c = 0
    local integer j = GetIndexMax$name$()
    call BJDebugMsg("-.-")
    
    loop
        exitwhen c > j
        if index$name$[c] == value then
            return c
        endif
        set c = c + 1
    endloop
    
    debug call BJDebugMsg("Value isn't stored on this index!")
    return 0
endfunction
//! endtextmacro

//! runtextmacro recycleIndexes("unit","Pet","null")
//! runtextmacro recycleIndexes("unit","Caster","null")
endlibrary
 

Attachments

  • RI.jpg
    RI.jpg
    39.8 KB · Views: 227
  • Recycle Indexes v1.6.w3x
    31 KB · Views: 82
Last edited:
Level 11
Joined
Feb 18, 2004
Messages
394
You have the least useful implementation of a recycle stack I have ever seen.

#0: http://en.wikipedia.org/wiki/Array You seem to use the word "array" to refer to an index in the one array of data you have per instance of the text macro, index$name$. (Which is ironically called an index in your code.)

#1: function GetValue$name$ takes integer loc, boolean remove returns $type$
Why is there a remove function within the get function? That makes no sense.

#2: function SetValue$name$ takes $type$ value returns integer
Why do you have an allocator that sets a value, but no function to set an already allocated value?

#3: function GetArray$name$ takes $type$ value returns integer
What possible purpose could that function serve in a well written script?

#4: exitwhen c > j
Why do you use a local here, when you could use the value indexMax$name$ - 1 directly in the exitwhen statement?

#5: Why don't you just use the recycling allocation system already in vJASS? You should probably look at structs.
 
Top