Static Global Singleton ArrayList Wrapper (Sharing)

I found this incredibly useful. It also demonstrates several Unity work-flow ideas I just learned about.

Because the following class is static, it can be called from any script (No referencing needed. It is in the ‘global’ scope), like this:

StaticArrayListWrapper.Add(5);
StaticArrayListWrapper.Add(5);
StaticArrayListWrapper.Add(10);
StaticArrayListWrapper.Add(12);
Debug.Log(StaticArrayListWrapper.toString);

Add also checks to see if an item is already in the array, so the above outputs “5, 10, 12”;

Assuming there isn’t a better way to do this, perhaps Mr. AngryAnt would be willing to share this on his blog :?: 8)

using System.Collections;

/// <description>
///	    This class is a wrapped ArrayList and C# Singleton as described here: 
///	    [url]http://msdn.microsoft.com/en-us/library/ff650316.aspx[/url]
/// </description>
// Sealed: means this class cannot be instantiated, which would risk a second 
//      instance
public sealed class StaticArrayListWrapper
{
    // Singleton: Read-only means it is only set once, on class init.
    // Static: means it can be accessed by other static members
    private static readonly ArrayList _arrayList = new ArrayList();

    // Private constructor makes this class static
    private StaticArrayListWrapper() { }


    #region Public Properties
    /// <description>
    ///	Returns a string representation of this (the array)
    /// </description>
    public static string toString
    {
        get
        {
            string output = "";
            float item;
            for (int i = 0; i < _arrayList.Count; i++)
            {
                item = (float)_arrayList[i];

                if (i == 0)
                {
                    output += item;
                }
                else
                {
                    output += ", " + item;
                }
            }

            return output;
        }
    }

    #endregion


    #region Wrapped ArrayList Members
    /// <description>
    /// 	Returns the number of items in this (the array). Readonly.
    /// </description>
    public static int Count
    {
        get
        {
            return _arrayList.Count;
        }
    }

    /// <description>
    /// 	Makes this a float type indexed array
    /// </description>
    public static float this[int index]
    {
        get
        {
            return (float)_arrayList[index];
        }

        set
        {
            _arrayList[index] = (float)value;
        }
    }


    /// <description>
    /// 	Returns true if this (array) contains the given item.
    /// </description>
    public static bool Contains(float item)
    {
        return _arrayList.Contains(item);
    }


    /// <description>
    /// 	Adds an item to this (the array)
    /// </description>
    public static void Add(float item)
    {
        // Make sure the item isn't added twice.
        if (!Contains(item))
        {
            _arrayList.Add(item);
        }
    }


    /// <description>
    /// 	Removes an item from this (the array)
    /// </description>
    public static void Remove(float item)
    {
        // Check if there is anything to do.
        if (Contains(item))
        {
            // Store the parent game object
            _arrayList.Remove(item);
        }
    }


    /// <description>
    /// 	Makes this (the array) iterable
    /// </description>
    public static System.Collections.IEnumerator GetEnumerator()
    {
        for (int i = 0; i < _arrayList.Count; i++)
        {
            yield return _arrayList[i];
        }
    }

    #endregion
}

I am using it to register (store) Rects when I make my GUI so I can test all registered Rects to see if the mouse is over the GUI or I should let my Camera Script run. This is why I make sure all entries are unique. You could remove that check quite easily though.

I am using a similar idea to create a config/constants script. It has a main static class which contains other static classes for organization. So I can access a constant from anywhere like this:

Constants.Display.SOME_CONSTANT

In this example, Constants is the main class and the name of the *.cs file and DIsplay is a Public Static sub-class inside, which has a Public Static property SOME_CONSTANT

This really made some things easy to deal with. I hope it helps those in the community that haven’t discovered this yet.

I am still new to Unity, so if this is a bad idea for any reason, please let me know!

Cheers,

Hiccup: This doesn’t work because it is used for instances (this keyword):

public static Rect this[int index]...

I can iterate like so:

for (int i = 0; i < StaticArrayListWrapper.Count; i++)
{
    ...
}

but I can’t use StaticArrayListWrapper
It is late here in Singapore, but I found this example to study tomorrow:
IEnumerator Example (Static Collection) : IEnumerator « Class Interface « C# / C Sharp
I’ll post what I end up doing. I could just add a method to handle getting an item at an index, but I want to see if I can make it a real IEnumerator.
At least I’m learning a lot about C#!

Well there is no way to create a static indexer in C#, but the above class works if you replace the indexer with a static method:

    public static int item(int index)
    {
        return (int)_arrayList[index];
    }

So instead of using:

StaticArrayListWrapper[0];

I have to use:

StaticArrayListWrapper.item(0);

Not a big deal.

Funny enough, I found a better home for my static array used to keep track of my GUI rects. It will be a property in a class, which means I can use a static property to make a proper indexer. There is a good discussion on this here:
http://www.gamedev.net/community/forums/topic.asp?topic_id=373597