using System; using System.Collections; using System.Collections.Generic; namespace Obi { /** * Custom IList implementation that allows access to the underlying raw array, for efficient C++ interop. Also * includes some auxiliar methods that make it easier and faster to send data back and forth between C# and C++, as * well as deal with accesing the contents of the list directly without a copy. */ public class ObiList : IList { private T[] data = new T[16]; private int count = 0; #region Implementation of IEnumerable public IEnumerator GetEnumerator() { for (int i = 0; i < count;++i) yield return data[i]; } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } #endregion #region Implementation of ICollection public void Add(T item) { EnsureCapacity(count + 1); data[count++] = item; } public void Clear() { count = 0; } public bool Contains(T item) { for (int i = 0; i < count; ++i) if (data[i].Equals(item)) return true; return false; } public void CopyTo(T[] array, int arrayIndex) { if (array == null) throw new ArgumentNullException(); if (array.Length-arrayIndex < count) throw new ArgumentException(); Array.Copy(data,0,array,arrayIndex,count); } public bool Remove(T item) { bool found = false; for (int i = 0; i < count; ++i) { // Look for the element, and mark it as found. if (!found && data[i].Equals(item)) found = true; //If we found the element and are not at the last element, displace the element 1 position backwards. if (found && i < count-1) { data[i] = data[i+1]; } } // If we found and removed the element, reduce the element count by 1. if (found) count--; return found; } public int Count { get { return count; } } public bool IsReadOnly { get { return false; } } #endregion #region Implementation of IList public int IndexOf(T item) { return Array.IndexOf(data,item); } public void Insert(int index, T item) { if (index < 0 || index > count) throw new ArgumentOutOfRangeException(); EnsureCapacity(++count); for (int i = count-1; i > index; ++i) { data[i] = data[i-1]; } data[index] = item; } public void RemoveAt(int index) { for (int i = index; i < count; ++i) { if (i < count-1) { data[i] = data[i+1]; } } count--; } public T this[int index] { get { return data[index]; } set { data[index] = value; } } #endregion #region Added stuff public T[] Data{ get{return data;} } /** * Ensures a minimal capacity of count elements, then sets the new count. Useful when passing the backing array to C++ * for being filled with new data. */ public void SetCount(int count){ EnsureCapacity(count); this.count = count; } public void EnsureCapacity(int capacity){ if (capacity >= data.Length) Array.Resize(ref data,capacity*2); } #endregion } }