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();
}
}
}