Newer
Older
CGTrack / Assets / Oculus / AudioManager / Scripts / Utils / FastList.cs
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;

public class FastList<T> {

    /// <summary>
    /// Comparison function should return -1 if left is less than right, 1 if left is greater than right, and 0 if they match.
    /// </summary>
    public delegate int CompareFunc(T left, T right);


    public T[]      array = null;
    public int      size = 0;

    public FastList () {
    }

    public FastList(int size) {
        if (size > 0) {
            this.size = 0;
            array = new T[size];
        }
        else {
            this.size = 0;
        }
    }

    public int Count {
        get { return size;}
        set { }
    }

    public T this[int i] {
        get { return array[i];}
        set { array[i] = value;}
    }

    //Add item to end of list.
    public void Add(T item) {
        if (array == null || size == array.Length) {
            Allocate();
        }
        array[size] = item;
        size++;
    }

	//Add item to end of list if it is unique.
	public void AddUnique( T item ) {
		if ( array == null || size == array.Length ) {
			Allocate();
		}
		if ( !Contains( item ) ) {
			array[size] = item;
			size++;
		}
	}

	//Add items to the end of the list
	public void AddRange( IEnumerable<T> items ) {
		foreach ( T item in items ) {
			Add( item );
		}
	}

	//Insert item at specified index
	public void Insert(int index, T item) {
        if (array == null || size == array.Length) {
            Allocate();
        }
        if (index < size) {
            //move things back 1
            for (int i = size; i > index; i--) {
                array[i] = array[i-1];
            }
            array[index] = item;
            size++;
        }
        else Add(item);
    }

    //Removes specified item and keeps everything else in order
    public bool Remove(T item) {
        if (array != null) {
            for (int i = 0; i < size; i++) {
                if (item.Equals(array[i])) { //found it, push everything up
                    size--;
                    for (int j = i; j < size; j++) {
                        array[j] = array[j+1];
                    }
                    array[size] = default(T);
                    return true;
                }
            }
        }
        return false;
    }

    //Removes item at specified index while keeping everything else in order
    //O(n)
    public void RemoveAt(int index) {
        if (array != null && size > 0 && index < size) {
            size--;
            for (int i = index; i < size; i++) {
                array[i] = array[i+1];
            }
            array[size] = default(T);
        }
    }

    //Removes the specified item from the list and replaces with last item. Return true if removed, false if not found.
    public bool RemoveFast(T item) {
        if (array != null) {
            for (int i = 0; i < size; i++) {
				if ( item.Equals( array[i] )) { //found
                    //Move last item here
                    if (i < (size - 1)) {
                        T lastItem = array[size-1];
                        array[size-1] = default(T);
                        array[i] = lastItem;
                    } else {
                        array[i] = default(T);
                    }
                    size--;
                    return true;
                }
            }
        }
        return false;
    }

    //Removes item at specified index and replace with last item.
    public void RemoveAtFast(int index) {
        if (array != null && index < size && index >= 0) {
            //last element
            if (index == size - 1) {
                array[index] = default(T);
            }
            else {
                T lastItem = array[size - 1];
                array[index] = lastItem;
                array[size - 1] = default(T);
            }
            size--;

        }
    }

    //Return whether an item is contained within the list
    //O(n)
    public bool Contains(T item) {
        if (array == null || size <= 0 ) return false;
        for (int i = 0; i < size; i++) {
            if (array[i].Equals(item)) { return true;}
        }
        return false;
    }

    //Returns index of specified item, or -1 if not found.
    //O(n)
    public int IndexOf(T item) {
        if (size <= 0 || array == null) { return -1;}
        for (int i = 0; i < size; i++) {
            if (item.Equals(array[i])) { return i;}
        }
        return -1;
    }

    public T Pop() {
        if (array != null && size > 0) {
            T lastItem = array[size-1];
            array[size-1] = default(T);
            size--;
            return lastItem;
        }

        return default(T);
    }

    public T[] ToArray() {
        Trim();
        return array;
    }

    public void Sort (CompareFunc comparer) {
        int start = 0;
        int end = size - 1;
        bool changed = true;

        while (changed) {
            changed = false;

            for (int i = start; i < end; i++) {

                if (comparer(array[i], array[i + 1]) > 0) {
                    T temp = array[i];
                    array[i] = array[i+1];
                    array[i+1] = temp;
                    changed = true;
                }
                else if (!changed) {
                    start = (i==0) ? 0 : i-1;
                }
            }
        }
    }

    public void InsertionSort(CompareFunc comparer) {
        for (int i = 1; i < size; i++) {
            T curr = array[i];
            int j = i;
            while (j > 0 && comparer(array[j - 1], curr) > 0) {
                array[j] = array[j-1];
                j--;
            }
            array[j] = curr;
        }
    }

    public IEnumerator<T> GetEnumerator() {
        if (array != null) {
            for (int i = 0; i < size; i++) {
                yield return array[i];
            }
        }
    }

    public T Find(Predicate<T> match) {
        if (match != null) {
            if (array != null) {
                for (int i = 0; i < size; i++) {
                    if (match(array[i])) { return array[i];}
                }
            }
        }
        return default(T);
    }
    
    //Allocate more space to internal array. 
    void Allocate() {
        T[] newArray;
        if (array == null) {
            newArray = new T[32];
        }
        else {
            newArray = new T[Mathf.Max(array.Length << 1, 32)];
        }
        if (array != null && size > 0) {
            array.CopyTo(newArray, 0);
        }

        array = newArray;
    }


    void Trim() {
        if (size > 0) {
            T[] newArray = new T[size];
            for (int i = 0; i < size; i++) {
                newArray[i] = array[i];
            }
            array = newArray;
        }
        else {
            array = null;
        }
    }

    //Set size to 0, does not delete array from memory
    public void Clear() {
        size = 0;
    }

    //Delete array from memory
    public void Release() {
        Clear();
        array = null;
    }



}