Files
RedHotRoast-ios/Assets/Scripts/ToolKit/GLoaderPool.cs
T

157 lines
4.5 KiB
C#
Raw Normal View History

using System.Collections.Generic;
using UnityEngine;
using FairyGUI;
namespace RedHotRoast
{
public class GLoaderPool
{
private static GLoaderPool _instance;
public static GLoaderPool Instance => _instance ??= new GLoaderPool();
private readonly Queue<GLoader> pool = new Queue<GLoader>();
private readonly LinkedList<GLoader> inUseLoaders = new LinkedList<GLoader>(); // 维护活跃顺序(LRU
private int maxCount = 10; // 最大池子数量
private int _width = 0;
private int _height = 0;
private bool _autoDisposeTexture = true; // 是否自动释放贴图
private GLoaderPool() { }
/// <summary>
/// 初始化 Loader 池
/// </summary>
public void Init(GComponent parentObj, int maxPoolCount, int width, int height, bool autoDisposeTexture = true)
{
maxCount = maxPoolCount;
_width = width;
_height = height;
_autoDisposeTexture = autoDisposeTexture;
DisposeAll();
// 预创建 loader
for (int i = 0; i < maxCount; i++)
{
var loader = CreateLoader();
pool.Enqueue(loader);
}
}
private GLoader CreateLoader()
{
var loader = new GLoader
{
fill = FillType.ScaleMatchWidth,
align = AlignType.Center,
verticalAlign = VertAlignType.Top,
visible = false
};
loader.SetSize(_width, _height);
return loader;
}
/// <summary>
/// 从池中获取 Loader
/// </summary>
public GLoader GetLoader()
{
GLoader loader = null;
// 如果池子里有,直接取
if (pool.Count > 0)
{
loader = pool.Dequeue();
}
else if (inUseLoaders.Count >= maxCount)
{
// 如果池满了,回收最久未使用的一个(LRU)
loader = inUseLoaders.First.Value;
inUseLoaders.RemoveFirst();
RecycleLoader(loader);
Debug.Log($"[LRU回收] 回收并复用一个 Loader");
}
else
{
// 未达到上限,新建
loader = CreateLoader();
}
// 标记为使用中,放到链表末尾(最近使用)
inUseLoaders.AddLast(loader);
loader.visible = true;
return loader;
}
/// <summary>
/// 归还 Loader
/// </summary>
public void ReturnLoader(GLoader loader)
{
if (loader == null) return;
if (inUseLoaders.Contains(loader))
{
inUseLoaders.Remove(loader);
RecycleLoader(loader);
pool.Enqueue(loader);
}
else
{
Debug.LogWarning("尝试归还未分配的 GLoader");
}
}
/// <summary>
/// 回收 loader 的资源
/// </summary>
private void RecycleLoader(GLoader loader)
{
if (_autoDisposeTexture && loader.texture != null)
{
loader.texture.Dispose();
}
loader.url = null;
loader.texture = null;
loader.visible = false;
}
/// <summary>
/// 更新 Loader 的使用顺序(需要主动调用,避免 LRU 误判)
/// </summary>
public void TouchLoader(GLoader loader)
{
if (loader == null || !inUseLoaders.Contains(loader)) return;
inUseLoaders.Remove(loader);
inUseLoaders.AddLast(loader); // 移到链表末尾,标记为最新使用
}
public bool IsFromPool(GLoader loader)
{
return inUseLoaders.Contains(loader) || pool.Contains(loader);
}
public int GetPoolCount() => pool.Count;
public int GetInUseCount() => inUseLoaders.Count;
/// <summary>
/// 清理全部
/// </summary>
public void DisposeAll()
{
foreach (var loader in pool)
{
loader?.Dispose();
}
foreach (var loader in inUseLoaders)
{
loader?.Dispose();
}
pool.Clear();
inUseLoaders.Clear();
}
}
}