https://github.com/Unity-Technologies/uGUI/tree/2018.4
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; internal class ObjectPool<T> where T: new() { private readonly Stack<T> m_Stack = new Stack<T>(); private readonly UnityAction<T> m_ActionOnGet; private readonly UnityAction<T> m_ActionOnRelease; public int countAll { get; private set; } public int countActive { get { return countAll - countInactive; } } public int countInactive { get { return m_Stack.Count; } } public ObjectPool(UnityAction<T> actionOnGet, UnityAction<T> actionOnRelease) { m_ActionOnGet = actionOnGet; m_ActionOnRelease = actionOnRelease; } public T Get() { T element; if (m_Stack.Count== 0) { element = new T(); countAll++; } else { element = m_Stack.Pop(); } if (m_ActionOnGet != null) { m_ActionOnGet(element); } return element; } public void Release(T element) { if (m_Stack.Count > 0 && ReferenceEquals(m_Stack.Peek(), element)) { Debug.LogError("Internal error. Trying to destroy object that is already released to pool."); } if (m_ActionOnRelease != null) { m_ActionOnRelease(element); } m_Stack.Push(element); } }
internal static class ListPool<T> { private static readonly ObjectPool<List<T>> s_ListPool = new ObjectPool<List<T>>(null, Clear); static void Clear(List<T> l) { l.Clear(); } public static List<T> Get() { return s_ListPool.Get(); } public static void Release(List<T> toRelease) { s_ListPool.Release(toRelease); } }
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class IndexedSet<T> : IList<T> { //This is a container that gives: // - Unique items // - Fast random removal // - Fast unique inclusion to the end // - Sequential access //Downsides: // - Uses more memory // - Ordering is not persistent // - Not Serialization Friendly. //We use a Dictionary to speed up list lookup, this makes it cheaper to guarantee no duplicates (set) //When removing we move the last item to the removed item position, this way we only need to update the index cache of a single item. (fast removal) //Order of the elements is not guaranteed. A removal will change the order of the items. readonly List<T> m_List = new List<T>(); Dictionary<T, int> m_Dictionary = new Dictionary<T, int>(); public void Add(T item) { m_List.Add(item); m_Dictionary.Add(item, m_List.Count - 1); } public bool AddUnique(T item) { if (m_Dictionary.ContainsKey(item)) return false; m_List.Add(item); m_Dictionary.Add(item, m_List.Count - 1); return true; } public bool Remove(T item) { int index = -1; if (!m_Dictionary.TryGetValue(item, out index)) return false; RemoveAt(index); return true; } public IEnumerator<T> GetEnumerator() { throw new System.NotImplementedException(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public void Clear() { m_List.Clear(); m_Dictionary.Clear(); } public bool Contains(T item) { return m_Dictionary.ContainsKey(item); } public void CopyTo(T[] array, int arrayIndex) { m_List.CopyTo(array, arrayIndex); } public int Count { get { return m_List.Count; } } public bool IsReadOnly { get { return false; } } public int IndexOf(T item) { int index = -1; m_Dictionary.TryGetValue(item, out index); return index; } public void Insert(int index, T item) { //We could support this, but the semantics would be weird. Order is not guaranteed.. throw new NotSupportedException("Random Insertion is semantically invalid, since this structure does not guarantee ordering."); } public void RemoveAt(int index) { T item = m_List[index]; m_Dictionary.Remove(item); if (index == m_List.Count - 1) m_List.RemoveAt(index); else { int replaceItemIndex = m_List.Count - 1; T replaceItem = m_List[replaceItemIndex]; m_List[index] = replaceItem; m_Dictionary[replaceItem] = index; m_List.RemoveAt(replaceItemIndex); } } public T this[int index] { get { return m_List[index]; } set { T item = m_List[index]; m_Dictionary.Remove(item); m_List[index] = value; m_Dictionary.Add(item, index); } } public void RemoveAll(Predicate<T> match) { //I guess this could be optmized by instead of removing the items from the list immediatly, //We move them to the end, and then remove all in one go. //But I don‘t think this is going to be the bottleneck, so leaving as is for now. int i = 0; while (i < m_List.Count) { T item = m_List[i]; if (match(item)) Remove(item); else i++; } } //Sorts the internal list, this makes the exposed index accessor sorted as well. //But note that any insertion or deletion, can unorder the collection again. public void Sort(Comparison<T> sortLayoutFunction) { //There might be better ways to sort and keep the dictionary index up to date. m_List.Sort(sortLayoutFunction); //Rebuild the dictionary index. for (int i = 0; i < m_List.Count; ++i) { T item = m_List[i]; m_Dictionary[item] = i; } } }
原文:https://www.cnblogs.com/revoid/p/13666180.html