Files
RedHotRoast-ios/Assets/Scripts/ModuleUI/Alubum/AlubumUI.cs
T

494 lines
19 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using DG.Tweening;
using FairyGUI;
using FGUI.LG_albums;
using UnityEngine;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace RedHotRoast
{
public class AlubumUI : BaseUI
{
private AlubumUICtrl ctrl;
private AlubumModel model;
private com_albums ui;
private long[] UpDatatime;
public AlubumUI(AlubumUICtrl ctrl) : base(ctrl)
{
uiName = UIConst.AlubumUI;
this.ctrl = ctrl;
}
protected override void SetUIInfo(UIInfo uiInfo)
{
uiInfo.packageName = "LG_albums";
uiInfo.assetName = "com_albums";
uiInfo.layerType = UILayerType.Popup;
uiInfo.isNeedOpenAnim = false;
uiInfo.isNeedCloseAnim = false;
uiInfo.isNeedUIMask = true;
}
//初始化页面逻辑
private void InitView(object a = null)
{
UpDatatime = new long[LevelData.Count];
ImageName = new string[LevelData.Count];
ui.list_albums.itemRenderer = RendererList;
ui.list_albums.numItems = LevelData.Count;
InitScroll();
}
private void SetItemData(object obj = null)
{
UpDatatime[(int)obj] = 0;
ui.list_albums.RefreshVirtualList();
}
#region
protected override void OnInit()
{
GLoaderPool.Instance.Init(null, 24, 312, 310);
}
protected override void OnClose()
{
foreach (var t in loader_list)
if (t != null && !t.isDisposed && t.texture != null)
{
t.texture.Dispose();
t.texture = null;
}
// 1. 解除 UI 对 Loader 的引用
for (var i = 0; i < ui.list_albums.numChildren; i++)
{
var item = ui.list_albums.GetChildAt(i) as item_albums;
if (item != null && item.com_loader.loader != null) item.com_loader.loader = null; // 清掉 GLoader 引用
}
activeLoaders.Clear();
_fileIsExist.Clear();
GLoaderPool.Instance.DisposeAll();
TextureHelper.ClearMaterialPool();
// 强制卸载未使用的资源
Resources.UnloadUnusedAssets();
MemoryManager.CleanMemoryMonitor();
}
protected override void OnBind()
{
ui = baseUI as com_albums;
}
private List<LevelUnlock> LevelData;
private readonly List<GLoader> loader_list = new();
public SmartInvoker invoker;
protected override void OnOpenBefore(object args)
{
invoker = new SmartInvoker(() =>
{
for (int i = 0; i < UpDatatime.Length; i++)
{
UpDatatime[i] = 0;
// ImageName[i] = "";
}
ui.list_albums.RefreshVirtualList();
}, TimeSpan.FromSeconds(0.2f));
LevelData = ConfigSystem.GetConfig<LevelUnlock>();
ui.list_albums.SetVirtual();
ui.btn_close1.SetClick(() => { CtrlCloseUI(); });
InitView();
}
private const int MaxVisibleCount = 18; // 一屏显示18个
private const int PreloadCount = 3; // 上下各预加载一屏
private readonly Dictionary<int, GLoader> activeLoaders = new();
private readonly Dictionary<int, bool> _fileIsExist = new();
private Throttle _throttle;
private void InitScroll()
{
// ui.list_albums.scrollPane.onScroll.Add(OnScrollUpdate);
ui.list_albums.scrollPane.onScrollEnd.Add(OnScrollEndCB); // 保留结束时的整理
OnScrollEnd();
}
private void OnScrollEndCB()
{
// UpdateVisibleAndPreload();
OnScrollEnd();
// Debug.Log("更新一次");
}
private void UpdateVisibleAndPreload()
{
// Debug.Log("[UpdateVisibleAndPreload]--------111111--------- ");
// if (LevelData == null || LevelData.Count == 0) return;
// var firstVisibleIndex = ui.list_albums.GetFirstChildInView();
// var lastVisibleIndex = Mathf.Min(firstVisibleIndex + MaxVisibleCount - 1, ui.list_albums.numItems - 1);
// var startIndex = Mathf.Max(0, firstVisibleIndex - PreloadCount);
// var endIndex = Mathf.Min(ui.list_albums.numItems - 1, lastVisibleIndex + PreloadCount);
// // 回收超出范围 loader
// var keysToRemove = new List<int>();
// foreach (var kv in activeLoaders)
// {
// var idx = kv.Key;
// if (idx < startIndex || idx > endIndex)
// {
// GLoaderPool.Instance.ReturnLoader(kv.Value);
// var oldItem = ui.list_albums.GetChildAt(idx) as item_albums;
// if (oldItem != null) oldItem.com_loader.loader = null;
// keysToRemove.Add(idx);
// }
// }
// foreach (var k in keysToRemove) activeLoaders.Remove(k);
// // 分配 loader 并加载图片
// for (var i = startIndex; i <= endIndex; i++)
// {
// if (activeLoaders.ContainsKey(i)) continue;
// var item = ui.list_albums.GetChildAt(i) as item_albums;
// if (item == null) continue;
// if (item.com_loader.loader != null && !item.com_loader.loader.isDisposed)
// GLoaderPool.Instance.ReturnLoader(item.com_loader.loader);
// var loader = GLoaderPool.Instance.GetLoader();
// item.com_loader.loader = loader;
// item.com_loader.AddChild(loader);
// loader.SetSize(item.com_loader.loader.width, item.com_loader.loader.height);
// _fileIsExist.TryGetValue(i, out var value);
// if (!value)
// {
// var localPath = Path.Combine(TextureHelper.getResPath(), LevelData[i].Name + ".jpg");
// if (File.Exists(localPath))
// {
// _fileIsExist[i] = true;
// Debug.Log($"[SetImgLoader] 本地存在,直接加载 {LevelData[i].Name}");
// CrazyAsyKit.StartCoroutine(TextureHelper.LoadTexture(LevelData[i].Name, loader, null,
// "LevelAlbums/"));
// }
// else
// {
// _fileIsExist[i] = false;
// }
// }
// else
// {
// CrazyAsyKit.StartCoroutine(TextureHelper.LoadTexture(LevelData[i].Name, loader, null,
// "LevelAlbums/"));
// }
// activeLoaders[i] = loader;
// }
// Debug.Log($"[ScrollUpdate] active loaders={activeLoaders.Count}, pool={GLoaderPool.Instance.GetPoolCount()}, inUse={GLoaderPool.Instance.GetInUseCount()}");
}
private void OnScrollEnd()
{
invoker.Invoke();
// for (int i = 0; i < UpDatatime.Length; i++)
// {
// UpDatatime[i] = 0;
// // ImageName[i] = "";
// }
// DOVirtual.DelayedCall(0.1f, () =>
// {
// ui.list_albums.RefreshVirtualList();
// });
// if (LevelData == null || LevelData.Count == 0) return;
// var firstVisibleIndex = ui.list_albums.GetFirstChildInView();
// var lastVisibleIndex = Mathf.Min(firstVisibleIndex + MaxVisibleCount - 1, ui.list_albums.numItems - 1);
// var startIndex = Mathf.Max(0, firstVisibleIndex - PreloadCount);
// var endIndex = Mathf.Min(ui.list_albums.numItems - 1, lastVisibleIndex + PreloadCount);
// // Debug.Log($"[ScrollEnd] start index={startIndex} end index={endIndex}");
// var tasks = new List<(GLoader loader, string fileName, Action<NTexture> callback, string folder)>();
// // 分配 loader 并加载图片
// for (var i = startIndex; i <= endIndex; i++)
// {
// _fileIsExist.TryGetValue(i, out var value);
// if (value) continue;
// if (GameHelper.GetLevel() < i + 1) continue;
// var item = ui.list_albums.GetChildAt(i) as item_albums;
// if (item == null) continue;
// if (item.com_loader.loader != null && !item.com_loader.loader.isDisposed)
// GLoaderPool.Instance.ReturnLoader(item.com_loader.loader);
// var loader = GLoaderPool.Instance.GetLoader();
// item.com_loader.loader = loader;
// item.com_loader.AddChild(loader);
// loader.SetSize(item.com_loader.loader.width, item.com_loader.loader.height);
// var idx = i;
// tasks.Add((loader, LevelData[i].Name, NTexture =>
// {
// if (NTexture != null) _fileIsExist[idx] = true;
// }, "LevelAlbums/"));
// activeLoaders[i] = loader;
// }
// if (tasks.Count > 0) TextureHelper.SetImgLoaders(tasks);
}
private string[] ImageName;
private void RendererList(int index, GObject obj)
{
// Debug.Log("Render list" );
// Debug.Log(JsonConvert.SerializeObject(LevelData[index]));
item_albums item = (item_albums)obj;
item.text_num.text = (index + 1).ToString();
if (index < GameHelper.GetCommonModel().MultiModal - 1)
{
item.type_.selectedIndex = 0;
if (GameHelper.GetLevel() > index + 1)
{
item.SetClick(() => { uiCtrlDispatcher.Dispatch(UICtrlMsg.AlbumDetailUI_Open, index); });
}
else
{
item.SetClick(() => { GameHelper.ShowTips("lv_unlock", true); });
}
}
else
{
Levelunlock levelunlock_ = DataMgr.LevelUnlockListNew.Value.FirstOrDefault(x => x.level_ == index + 1);
if (levelunlock_ != null)
{
item.type_.selectedIndex = levelunlock_.type;
}
else item.type_.selectedIndex = 0;
if (GameHelper.GetLevel() > index + 1)
{
item.SetClick(() => { uiCtrlDispatcher.Dispatch(UICtrlMsg.AlbumDetailUI_Open, index); });
}
else
{
item.SetClick(() => { GameHelper.ShowTips("lv_unlock", true); });
}
}
if (GameHelper.GetNowTime() < UpDatatime[index] + 1) return;
UpDatatime[index] = GameHelper.GetNowTime();
// if (!activeLoaders.ContainsValue(item.com_loader.loader)) activeLoaders[index] = item.com_loader.loader;
if (!loader_list.Contains(item.com_loader.GetChild("loader") as GLoader))
loader_list.Add(item.com_loader.GetChild("loader") as GLoader);
if (index < GameHelper.GetCommonModel().MultiModal - 1)
{
if (GameHelper.GetLevel() > index + 1)
{
item.isUnlock.selectedIndex = 1;
if (item.com_loader.loader.texture == null ||
item.com_loader.loader.texture.nativeTexture.name != LevelData[index].Name)
{
// item.isUnlock.selectedIndex = 0;
// if (item.com_loader.loader.texture != null)
// {
// item.com_loader.loader.texture.Dispose(); // 释放 GPU 资源
// item.com_loader.loader.texture = null; // 断开引用
// }
TextureHelper.SetImgLoader(item.com_loader.GetChild("loader") as GLoader, LevelData[index].Name,
(a) => { Debug.Log(item.com_loader.loader.texture.nativeTexture.name); }, "LevelAlbums/", FolderNames.AlbumName);
ImageName[index] = LevelData[index].Name;
}
item.touchable = true;
}
else
{
item.isUnlock.selectedIndex = 0;
// item.touchable = false;
}
}
else
{
Levelunlock levelunlock_ = DataMgr.LevelUnlockListNew.Value.FirstOrDefault(x => x.level_ == index + 1);
if (GameHelper.GetLevel() > index + 1)
{
if (levelunlock_ != null)
{
item.isUnlock.selectedIndex = 1;
if (item.com_loader.loader.texture == null || item.com_loader.loader.texture.nativeTexture.name != ImageName[index])
{
if (levelunlock_.type == 0)
{
if (levelunlock_.config_index >= ConfigSystem.GetConfig<FreeImageLibrary>().Count) levelunlock_.config_index = ConfigSystem.GetConfig<FreeImageLibrary>().Count - 1;
FreeImageLibrary _leveldata = ConfigSystem.GetConfig<FreeImageLibrary>()[levelunlock_.config_index];
TextureHelper.SetImgLoader(item.com_loader.GetChild("loader") as GLoader, _leveldata.Name, null, "LevelAlbums/", FolderNames.AlbumName);
ImageName[index] = LevelData[index].Name;
}
else if (levelunlock_.type == 1)
{
if (levelunlock_.config_index >= ConfigSystem.GetConfig<ADImageLibrary>().Count) levelunlock_.config_index = ConfigSystem.GetConfig<ADImageLibrary>().Count - 1;
ADImageLibrary _leveldata = ConfigSystem.GetConfig<ADImageLibrary>()[levelunlock_.config_index];
TextureHelper.SetImgLoader(item.com_loader.GetChild("loader") as GLoader, _leveldata.Name, null, "LevelAlbums/", FolderNames.AlbumName);
ImageName[index] = LevelData[index].Name;
}
else if (levelunlock_.type == 2)
{
if (levelunlock_.config_index >= ConfigSystem.GetConfig<SpecialImageLibrary>().Count) levelunlock_.config_index = ConfigSystem.GetConfig<SpecialImageLibrary>().Count - 1;
SpecialImageLibrary _leveldata = ConfigSystem.GetConfig<SpecialImageLibrary>()[levelunlock_.config_index];
TextureHelper.SetImgLoader(item.com_loader.GetChild("loader") as GLoader, _leveldata.Name, null, "LevelAlbums/", FolderNames.AlbumName);
ImageName[index] = LevelData[index].Name;
}
else if (levelunlock_.type == 3)
{
if (levelunlock_.config_index >= ConfigSystem.GetConfig<VIPImageLibrary>().Count) levelunlock_.config_index = ConfigSystem.GetConfig<VIPImageLibrary>().Count - 1;
VIPImageLibrary _leveldata = ConfigSystem.GetConfig<VIPImageLibrary>()[levelunlock_.config_index];
TextureHelper.SetImgLoader(item.com_loader.GetChild("loader") as GLoader, _leveldata.Name, null, "LevelAlbums/", FolderNames.AlbumName);
ImageName[index] = LevelData[index].Name;
}
}
}
else
{
item.isUnlock.selectedIndex = 1;
if (item.com_loader.loader.texture == null || item.com_loader.loader.texture.nativeTexture.name != LevelData[index].Name)
{
TextureHelper.SetImgLoader(item.com_loader.GetChild("loader") as GLoader, LevelData[index].Name, null, "LevelAlbums/", FolderNames.AlbumName);
ImageName[index] = LevelData[index].Name;
}
}
}
else
{
// item.touchable = false;
item.isUnlock.selectedIndex = 0;
}
}
}
protected override void OnOpen(object args)
{
}
protected override void OnHide()
{
}
protected override void OnDisplay(object args)
{
}
#endregion
#region
protected override void AddListener()
{
GameDispatcher.Instance.AddListener(GameMsg.UnlockAlbums, SetItemData);
}
protected override void RemoveListener()
{
GameDispatcher.Instance.RemoveListener(GameMsg.UnlockAlbums, SetItemData);
}
#endregion
}
public class SmartInvoker
{
private readonly Action _action;
private readonly TimeSpan _delay;
private DateTime _lastImmediateInvoke = DateTime.MinValue;
private CancellationTokenSource _cts = null;
private readonly object _lock = new object();
private bool _hasPending = false;
public SmartInvoker(Action action, TimeSpan delay)
{
_action = action;
_delay = delay;
}
public void Invoke()
{
lock (_lock)
{
var now = DateTime.UtcNow;
var timeSinceLast = now - _lastImmediateInvoke;
if (timeSinceLast >= _delay)
{
_lastImmediateInvoke = now;
_action();
Debug.Log("diaoyongyiciiiiiiiiiiiiiii");
}
else
{
_hasPending = true;
_cts?.Cancel();
_cts = new CancellationTokenSource();
var token = _cts.Token;
Task.Delay(_delay, token).ContinueWith(t =>
{
if (!t.IsCanceled)
{
lock (_lock)
{
if (_hasPending)
{
_lastImmediateInvoke = DateTime.UtcNow;
_hasPending = false;
_action();
Debug.Log("diaoyongyiciiiiiiiiiiiiiii");
}
}
}
}, TaskScheduler.Default);
}
}
}
}
}