FguiModule.GLoader.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. using FairyGUI;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using XGame.Framework.Asyncs;
  5. namespace XGame.Framework.FGUI
  6. {
  7. /// <summary>
  8. /// 修复图集合批 参考链接:https://zhuanlan.zhihu.com/p/689636245
  9. /// </summary>
  10. internal partial class FguiModule : IGloaderHandle
  11. {
  12. public class LoadedAsset
  13. {
  14. public string addressable;
  15. public Sprite sprite;
  16. public NTexture nTexture;
  17. }
  18. /// <summary>
  19. /// 已加载过的资源
  20. /// </summary>
  21. private Dictionary<string, LoadedAsset> _loadedAssetsMap = new Dictionary<string, LoadedAsset>();
  22. /// <summary>
  23. /// key:sprite.texture
  24. /// value:NTexture 用作Sprite的root
  25. /// </summary>
  26. private Dictionary<Texture, NTexture> _textureRootMap = new Dictionary<Texture, NTexture>();
  27. IAsync IGloaderHandle.LoadNTexture(string addressableName)
  28. {
  29. if (_loadedAssetsMap.ContainsKey(addressableName))
  30. { // 已经加载完
  31. var asyncGroup = new AsyncGroup();
  32. asyncGroup.End();
  33. return asyncGroup;
  34. }
  35. //TODO 需要识别Sprite还是Texture
  36. var loadAsync = _assetModule.LoadAsync<Sprite>(addressableName);
  37. loadAsync.On(_ =>
  38. {
  39. var result = loadAsync.Result;
  40. if (result == null)
  41. {
  42. Log.Debug($"IGloaderHandle.LoadNTexture failed. addressable:{addressableName}");
  43. return;
  44. }
  45. if (CreateNTexture(addressableName, result) == false)
  46. { //已经有其他loader加载完成
  47. _assetModule.Recycle(result);
  48. }
  49. });
  50. return loadAsync;
  51. }
  52. NTexture IGloaderHandle.GetNTexture(string addressableName)
  53. {
  54. if (_loadedAssetsMap.TryGetValue(addressableName, out var asset))
  55. {
  56. return asset.nTexture;
  57. }
  58. // 可能是加载失败,也可能是没有加载过
  59. Log.Debug($"找不到NTexture,确认IGloaderHandle.LoadNTexture是否已经加载成功. Name:{addressableName}");
  60. return default;
  61. }
  62. private bool CreateNTexture(string addressable, Sprite sprite)
  63. {
  64. if (_loadedAssetsMap.ContainsKey(addressable))
  65. { // 已经有其他loader加载完成
  66. return false;
  67. }
  68. if (!_textureRootMap.TryGetValue(sprite.texture, out var root))
  69. {
  70. _textureRootMap[sprite.texture] = root = new NTexture(sprite.texture);
  71. root.destroyMethod = DestroyMethod.None;
  72. }
  73. Rect region = sprite.textureRect;
  74. region.y = sprite.texture.height - region.yMax;
  75. var nTexture = new NTexture(root, region, false);
  76. //注册release事件,Gloader在Dispose时,只会触发 NGraphics.Dispose() => _texture.ReleaseRef();
  77. nTexture.onRelease += OnReleaseNTexture;
  78. nTexture.destroyMethod = DestroyMethod.None;
  79. _loadedAssetsMap.Add(addressable, new LoadedAsset()
  80. {
  81. addressable = addressable,
  82. sprite = sprite,
  83. nTexture = nTexture,
  84. });
  85. return true;
  86. }
  87. private bool TryGetLoadedAsset(NTexture nTexture, out LoadedAsset asset)
  88. {
  89. foreach (var item in _loadedAssetsMap)
  90. {
  91. if (item.Value.nTexture == nTexture)
  92. {
  93. asset = item.Value;
  94. return true;
  95. }
  96. }
  97. asset = default;
  98. return false;
  99. }
  100. private void OnReleaseNTexture(NTexture nTexture)
  101. {
  102. if (TryGetLoadedAsset(nTexture, out var asset))
  103. {
  104. //Log.Debug($"OnReleaseNTexture Addressable:{asset.addressable}");
  105. _loadedAssetsMap.Remove(asset.addressable);
  106. if (nTexture.root.refCount <= 0)
  107. {
  108. _textureRootMap.Remove(asset.sprite.texture);
  109. }
  110. _assetModule.Recycle(asset.sprite);
  111. }
  112. }
  113. /// <summary>
  114. /// 清空所有Gloader加载的资源
  115. /// </summary>
  116. /// <param name="assetModule"></param>
  117. public void ClearGloaderAssets()
  118. {
  119. foreach (var item in _loadedAssetsMap)
  120. {
  121. _assetModule.Recycle(item.Value.sprite);
  122. }
  123. _loadedAssetsMap.Clear();
  124. _textureRootMap.Clear();
  125. }
  126. }
  127. }