using System; using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices; namespace UTJ.FbxExporter { public class PinnedArray2D : IDisposable, IEnumerable, IEnumerable { public PinnedArray2D(int x, int y) { this.m_data = new T[x, y]; this.m_gch = GCHandle.Alloc(this.m_data, GCHandleType.Pinned); } public PinnedArray2D(T[,] data, bool clone = false) { this.m_data = ((!clone) ? data : ((T[,])data.Clone())); this.m_gch = GCHandle.Alloc(this.m_data, GCHandleType.Pinned); } public int Length { get { return this.m_data.Length; } } public T this[int x, int y] { get { return this.m_data[x, y]; } set { this.m_data[x, y] = value; } } public T[,] Array { get { return this.m_data; } } public IntPtr Pointer { get { return (this.m_data.Length != 0) ? this.m_gch.AddrOfPinnedObject() : IntPtr.Zero; } } public PinnedArray2D Clone() { return new PinnedArray2D((T[,])this.m_data.Clone(), false); } public bool Assign(T[,] source) { if (source != null && this.m_data.Length == source.Length) { System.Array.Copy(source, this.m_data, this.m_data.Length); return true; } return false; } public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (disposing && this.m_gch.IsAllocated) { this.m_gch.Free(); } } public IEnumerator GetEnumerator() { return (IEnumerator)this.m_data.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } public static implicit operator IntPtr(PinnedArray2D v) { return (v != null) ? v.Pointer : IntPtr.Zero; } public static implicit operator T[,](PinnedArray2D v) { return (v != null) ? v.Array : null; } private T[,] m_data; private GCHandle m_gch; } }