Dynamic arrays

From ZDoom Wiki
Jump to navigation Jump to search
Note: This feature is for ZScript only.

Dynamic arrays are resizable versions of regular arrays, with built-in functions to allow easy management.

The types available are:

  • Double
  • Int
  • String
  • Pointer (e.g. Actor)
  • Class Types (e.g. Class<Actor>)

Dynamic arrays can be defined as a class member, or inside a function:

class example
{
    Array<type> myArray;
    
    void exampleFunction() 
    {
        Array<type> myArray2;
    }
}

Note: Class types have a small syntax requirement in order to work.

// Notice the gap in between the two closing angle brackets. This is needed.
Array<Class<Actor> > myArray;

Functions

  • int Size ()
Returns the size of the array.
  • void Copy (Array<type> other)
Replaces the array's contents with the contents of the specified other array.
  • void Move (Array<type> other)
Replaces the calling array's data with the other's data, clearing other's content in the process. This is faster than Copy, perfect for use with temporary arrays.
  • void Append (Array<type> other)
Copies other's data and put it at the end of the calling array's data.
  • int Find (<type> item)
Searches for a particular item of the array's type and returns the index of that item. If the item is not found in the array, returns Size(), so if you want to check if a specific object is present in the array, the check will need to look as follows:
if (arrayname.Find(item) != arrayname.Size())
  • int Push (<type> item)
Appends item to the end of the array and expands it by one.
  • vararg uint PushV (<type> item, ...)
(Note: this function is available to integer and string arrays only.)
Appends an arbitrary number of elements, comma delimited, to the end of the array, expanding it by the number of elements appended. In case of integer arrays, attempting to append floating-point values converts them to integers by rounding them down.
The function returns the index of the last element in the array.
  • bool Pop ()
Removes the item at the end of the array and decreases its size by one.
  • void Delete (uint index, int deletecount = 1)
Removes a range of entries from the array.
  • void Insert (uint index, <type> item)
Inserts an item at the specified index. Implicitly performs a resize to accommodate.
  • void ShrinkToFit ()
Shrinks the total array size to the last non-empty member's location.
  • void Grow (uint amount)
Increases the size of the array by the amount specified, expanding from the end.
  • void Resize (uint amount)
Grows or shrinks the array to the exact amount. Eliminates all content within the removed containers.
  • int Reserve (uint amount)
Allocates 'amount' new entries and returns the index of the first one.
  • int Max ()
Returns how many entries are allocated, also counting those which are currently not in use. Caution must be used here since this can return a number greater than the array's actual size itself.
  • void Clear ()
Shrinks the array to 0 and destroys all contents.

Null checking

All that needs to be done is a call to see if the element exists.

Array<Thinker> thinkers;

// ...some code which assigns thinkers to the array...
// Always make sure the thinker size is substantial. Otherwise it'll throw an error.

if (thinkers.Size() > 0)
{
    // There is no need for casting of any kind. Just check it directly.

    if (!thinkers[element])
    {
         Console.Printf("Detected a null element");
    }
}

Examples

This version of the Zombieman will spawn explosive barrels every 70 tics while it's alive. The barrels are put into a dynamic array. Once the monster is killed, all those barrels will explode:

class BarrelZombie : Zombieman
{
	array <Actor> barrels;

	override void Tick()
	{
		super.Tick();
		if (health > 0 && !isFrozen() && GetAge() % 70 == 0)
		{
			let bar = Spawn('ExplosiveBarrel', pos, ALLOW_REPLACE);
			if (bar)
			{
				barrels.Push(bar);
			}
		}
	}

	override void Die(Actor source, Actor inflictor, int dmgflags, Name MeansOfDeath)
	{
		for (int i = 0; i < barrels.Size(); i++)
		{
			let bar = barrels[i];
			if (bar && bar.health > 0)
			{
				bar.DamageMobj(self, self, bar.health, 'normal');
			}
		}
		super.Die(source, inflictor, dmgflags, MeansOfDeath);
	}
}