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 pool = new Queue(); private readonly LinkedList inUseLoaders = new LinkedList(); // 维护活跃顺序(LRU) private int maxCount = 10; // 最大池子数量 private int _width = 0; private int _height = 0; private bool _autoDisposeTexture = true; // 是否自动释放贴图 private GLoaderPool() { } /// /// 初始化 Loader 池 /// 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; } /// /// 从池中获取 Loader /// 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; } /// /// 归还 Loader /// 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"); } } /// /// 回收 loader 的资源 /// private void RecycleLoader(GLoader loader) { if (_autoDisposeTexture && loader.texture != null) { loader.texture.Dispose(); } loader.url = null; loader.texture = null; loader.visible = false; } /// /// 更新 Loader 的使用顺序(需要主动调用,避免 LRU 误判) /// 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; /// /// 清理全部 /// public void DisposeAll() { foreach (var loader in pool) { loader?.Dispose(); } foreach (var loader in inUseLoaders) { loader?.Dispose(); } pool.Clear(); inUseLoaders.Clear(); } } }