2026-04-22 11:13:16 +08:00
|
|
|
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;
|
2026-04-27 11:20:13 +08:00
|
|
|
namespace RedHotRoast
|
2026-04-22 11:13:16 +08:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|