using System; using System.Collections.Generic; using UnityEngine; namespace TyphoonUI { /// /// 池 /// public class ScrollCellPool { private static int _poolCounter = 0; //池ID计数 public int PoolID { get; } //池ID private Func CreateFunc { set; get; } //创建代理 private Transform Container { get; set; } //挂载节点 private Stack _idles = new Stack(); //空闲对象 private List _poolObjects = new List(); //所有池对象 public List PoolObjects => _poolObjects; public ScrollCellPool(Func createFunc, Transform cellContainer, int preload = -1) { PoolID = _poolCounter += 1; CreateFunc = createFunc; Container = cellContainer; //预加载 if (preload > 0) { Preload(preload); } } private ScrollCellPoolObject CreatePoolObject() { var newCell = CreateFunc.Invoke(); var poolObj = new ScrollCellPoolObject(); poolObj.Cell = newCell; poolObj.PoolID = PoolID; _poolObjects.Add(poolObj); newCell.Root.SetParent(Container); newCell.Root.localPosition = Vector3.zero; newCell.Root.localScale = Vector3.one; newCell.Root.localEulerAngles = Vector3.zero; newCell.OnCellInitialize(); newCell.SetVisible(false); return poolObj; } private ScrollCellPoolObject GetPoolObject() { if (_idles.Count > 0) { var result = _idles.Pop(); result.BeforeGet(); return result; } var newOne = CreatePoolObject(); newOne.BeforeGet(); return newOne; } private void Preload(int count) { var add = count - _poolObjects.Count; if (add <= 0) { return; } var objs = new List(); for (int i = 0; i < add; i++) { objs.Add(GetPoolObject()); } foreach (var obj in objs) { Recycle(obj); } objs.Clear(); } public IScrollCell GetCell(int index) { var obj = GetPoolObject(); obj.CellIndex = index; return obj.Cell; } //回收无效元素 public void RecycleInvalid(int startIndex, int endIndex, HashSet validIndex) { foreach (var poolObject in _poolObjects) { if (!poolObject.IsBusy) { continue; } if (poolObject.CellIndex < startIndex || poolObject.CellIndex > endIndex) { Recycle(poolObject); } else { validIndex?.Add(poolObject.CellIndex); } } } //回收所有 public void RecycleAll() { foreach (var poolObject in _poolObjects) { if (poolObject.IsBusy) { Recycle(poolObject); } } } //回收池对象 private void Recycle(ScrollCellPoolObject poolObject) { poolObject.IsBusy = false; poolObject.BeforeRecycle(); _idles.Push(poolObject); } //释放 public void Release() { CreateFunc = null; foreach (var poolObject in _poolObjects) { poolObject.Release(); } _idles.Clear(); _poolObjects.Clear(); } } }