377 lines
12 KiB
C#
377 lines
12 KiB
C#
using asap.core;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.AddressableAssets;
|
|
using UnityEngine.U2D;
|
|
using UnityEngine.UI;
|
|
using UniRx;
|
|
using System.Threading.Tasks;
|
|
using game;
|
|
using UnityEngine.ResourceManagement.AsyncOperations;
|
|
|
|
public class GetSpriteEvent
|
|
{
|
|
public string spriteName;
|
|
public string panelName;
|
|
public Sprite sprite;
|
|
public GetSpriteEvent()
|
|
{
|
|
|
|
}
|
|
public GetSpriteEvent(string spriteName, string panelName = "")
|
|
{
|
|
this.spriteName = spriteName;
|
|
this.panelName = panelName;
|
|
}
|
|
}
|
|
|
|
public interface IShowImageData
|
|
{
|
|
public string spriteName { set; get; }
|
|
|
|
public Image image { set; get; }
|
|
|
|
public void SetImage(Sprite sprite);
|
|
}
|
|
|
|
public interface IUIService
|
|
{
|
|
Task LoadAtlas();
|
|
Task SetImageSprite(Image image, string spriteName, string panelName = "");
|
|
/// <summary>
|
|
/// 同一个 image 组件 重复赋值,使用此方法
|
|
/// </summary>
|
|
/// <param name="imageData"></param>
|
|
/// <param name="panelName"></param>
|
|
/// <returns></returns>
|
|
Task SetImageSprite(IShowImageData imageData, string panelName = "");
|
|
void ReleaseSpriteDic(string dicName);
|
|
Task SetHeadImage(Image image, string spriteName);
|
|
Sprite GetSprite(string spriteName, string panelName = "");
|
|
}
|
|
public class AtlasReference
|
|
{
|
|
public AsyncOperationHandle<SpriteAtlas> handle;
|
|
public SpriteAtlas spriteAtlas;
|
|
public int referenceCount;
|
|
}
|
|
public class UIService : IUIService
|
|
{
|
|
private Dictionary<string, Dictionary<string, Sprite>> _spriteDict = new Dictionary<string, Dictionary<string, Sprite>>();
|
|
Dictionary<string, AtlasReference> atlasReference = new Dictionary<string, AtlasReference>();
|
|
SpriteAtlas atlasDic;
|
|
string preloadAtlasName = "UIResAtlas";
|
|
string defaultAvatar;
|
|
public async Task LoadAtlas()
|
|
{
|
|
cfg.Tables table = GContext.container.Resolve<cfg.Tables>();
|
|
|
|
var tbAvatar = table.TbUserAvatar.GetOrDefault(table.TbGlobalConfig.InitAvatar);
|
|
if (tbAvatar != null)
|
|
{
|
|
defaultAvatar = tbAvatar.Avatar;
|
|
}
|
|
else
|
|
{
|
|
defaultAvatar = table.TbUserAvatar.DataMap[0].Avatar;
|
|
}
|
|
|
|
if (atlasDic != null)
|
|
{
|
|
Addressables.Release(atlasDic);
|
|
}
|
|
var atlas = await Addressables.LoadAssetAsync<SpriteAtlas>(preloadAtlasName).Task;
|
|
if (atlas != null)
|
|
{
|
|
atlasDic = atlas;
|
|
}
|
|
GContext.OnEvent<GetSpriteEvent>().Subscribe(OnGetSprite);
|
|
GetAvatarDataEvent getAvatarDataEvent = new GetAvatarDataEvent();
|
|
getAvatarDataEvent.url = GContext.container.Resolve<IUserService>().AvatarUrl;
|
|
GContext.Publish(getAvatarDataEvent);
|
|
}
|
|
/// <summary>
|
|
/// 设置头像 存在网图
|
|
/// </summary>
|
|
/// <param name="icon_head">Image 组件</param>
|
|
/// <param name="url">头像网址 或者本地名称</param>
|
|
public async Task SetHeadImage(Image icon_head, string url)
|
|
{
|
|
if (icon_head == null)
|
|
{
|
|
Debug.LogError("SetHeadImage icon_head null");
|
|
return;
|
|
}
|
|
if (string.IsNullOrEmpty(url))
|
|
{
|
|
url = defaultAvatar;
|
|
}
|
|
if (icon_head != null && url.Contains("http"))
|
|
{
|
|
icon_head.sprite = GetSprite(defaultAvatar);
|
|
}
|
|
|
|
GetAvatarDataEvent getAvatarDataEvent = new GetAvatarDataEvent();
|
|
getAvatarDataEvent.url = url;
|
|
GContext.Publish(getAvatarDataEvent);
|
|
var sprite = await getAvatarDataEvent.taskCompletionSource.Task;
|
|
if (icon_head != null && sprite != null)
|
|
{
|
|
icon_head.sprite = sprite;
|
|
}
|
|
}
|
|
void OnGetSprite(GetSpriteEvent getSpriteEvent)
|
|
{
|
|
if (!string.IsNullOrEmpty(getSpriteEvent.spriteName))
|
|
{
|
|
getSpriteEvent.sprite = GetSprite(getSpriteEvent.spriteName, getSpriteEvent.panelName);
|
|
}
|
|
}
|
|
|
|
public void ReleaseSpriteDic(string dicName)
|
|
{
|
|
if (string.IsNullOrEmpty(dicName) || !_spriteDict.TryGetValue(dicName, out var value))
|
|
{
|
|
return;
|
|
}
|
|
foreach (var item in value)
|
|
{
|
|
string[] spriteNames = item.Key.Split('_');
|
|
if (spriteNames.Length > 1 && spriteNames[0] == "separate")
|
|
{
|
|
Addressables.Release(item.Value);
|
|
}
|
|
else if (spriteNames.Length > 2 && spriteNames[0] == "atlas")
|
|
{
|
|
if (atlasReference.TryGetValue(spriteNames[1], out var AR))
|
|
{
|
|
AR.referenceCount--;
|
|
if (AR.referenceCount == 0)
|
|
{
|
|
AR.spriteAtlas = null;
|
|
Addressables.Release(AR.handle);
|
|
atlasReference.Remove(spriteNames[1]);
|
|
Debug.Log($"ReleaseAtlas {spriteNames[1]} ===> Panel {dicName}");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
value.Clear();
|
|
_spriteDict.Remove(dicName);
|
|
}
|
|
|
|
public async Task SetImageSprite(Image image, string spriteName, string panelName = "")
|
|
{
|
|
if (image == null)
|
|
{
|
|
Debug.LogError($"image null spriteName {spriteName}");
|
|
return;
|
|
}
|
|
ShowImageData imageData = new ShowImageData(image, spriteName);
|
|
await SetImageSprite(imageData, panelName);
|
|
}
|
|
public async Task SetImageSprite(IShowImageData imageData, string panelName = "")
|
|
{
|
|
if (imageData == null || imageData.image == null)
|
|
{
|
|
Debug.LogError($"image null spriteName {imageData?.spriteName}");
|
|
return;
|
|
}
|
|
if (string.IsNullOrEmpty(panelName))
|
|
{
|
|
panelName = BasePanel.PanelName;
|
|
}
|
|
if (!string.IsNullOrEmpty(imageData.spriteName))
|
|
{
|
|
try
|
|
{
|
|
await SetSprite(imageData, panelName);
|
|
}
|
|
catch (System.Exception e)
|
|
{
|
|
Debug.LogError($"SetImageSprite error: {e.Message}");
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 获取默认图集里面的图片
|
|
/// </summary>
|
|
/// <param name="spriteName"></param>
|
|
/// <param name="panelName"></param>
|
|
/// <returns></returns>
|
|
public Sprite GetSprite(string spriteName, string panelName = "")
|
|
{
|
|
if (string.IsNullOrEmpty(panelName))
|
|
{
|
|
panelName = BasePanel.PanelName;
|
|
}
|
|
Sprite value;
|
|
if (_spriteDict.TryGetValue(panelName, out var sprites))
|
|
{
|
|
if (sprites.TryGetValue(spriteName, out value))
|
|
{
|
|
return value;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sprites = new Dictionary<string, Sprite>();
|
|
_spriteDict.Add(panelName, sprites);
|
|
}
|
|
|
|
value = atlasDic?.GetSprite(spriteName);
|
|
if (value != null)
|
|
{
|
|
sprites[spriteName] = value;
|
|
return value;
|
|
}
|
|
GameDebug.LogWarning("spriteName===>" + spriteName + " panelName===>" + panelName);
|
|
return null;
|
|
}
|
|
async Task SetSprite(IShowImageData imageData, string panelName)
|
|
{
|
|
string spriteName = imageData.spriteName;
|
|
string[] spriteNames = spriteName.Split('_');
|
|
if (spriteNames.Length > 1 && spriteNames[0] == "separate" && spriteNames[1] == "icon")
|
|
{
|
|
panelName = "icon";
|
|
}
|
|
if (string.IsNullOrEmpty(panelName))
|
|
{
|
|
panelName = "HomePanel";
|
|
}
|
|
Sprite value;
|
|
if (_spriteDict.TryGetValue(panelName, out var sprites))
|
|
{
|
|
if (sprites.TryGetValue(spriteName, out value))
|
|
{
|
|
imageData.SetImage(value);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sprites = new Dictionary<string, Sprite>();
|
|
_spriteDict.Add(panelName, sprites);
|
|
}
|
|
|
|
|
|
if (spriteNames.Length > 1 && spriteNames[0] == "separate")
|
|
{
|
|
await LoadSprite(imageData, sprites);
|
|
return;
|
|
}
|
|
else if (spriteNames.Length > 2 && spriteNames[0] == "atlas")
|
|
{
|
|
LoadSpriteAtlas(imageData, spriteNames[1], sprites);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
value = atlasDic?.GetSprite(spriteName);
|
|
if (value != null)
|
|
{
|
|
sprites[spriteName] = value;
|
|
imageData.SetImage(value);
|
|
return;
|
|
}
|
|
Debug.LogWarning("spriteName===>" + spriteName + " panelName===>" + panelName);
|
|
}
|
|
}
|
|
async Task LoadSprite(IShowImageData imageData, Dictionary<string, Sprite> sprites)
|
|
{
|
|
string spriteName = imageData.spriteName;
|
|
var sprite = await Addressables.LoadAssetAsync<Sprite>(spriteName).Task;
|
|
if (sprite != null)
|
|
{
|
|
sprites[spriteName] = sprite;
|
|
|
|
imageData.SetImage(sprite);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("spriteName===>" + spriteName);
|
|
}
|
|
}
|
|
void LoadSpriteAtlas(IShowImageData imageData, string sName, Dictionary<string, Sprite> sprites)
|
|
{
|
|
if (!atlasReference.TryGetValue(sName, out var AR))
|
|
{
|
|
Debug.Log("ReleaseAtlas Load Start ===>" + sName);
|
|
AR = new AtlasReference();
|
|
atlasReference.Add(sName, AR);
|
|
AR.handle = Addressables.LoadAssetAsync<SpriteAtlas>("UIResAtlas_" + sName);
|
|
AR.handle.Completed += (handle) =>
|
|
{
|
|
if (handle.Status == AsyncOperationStatus.Succeeded)
|
|
{
|
|
if (AR.spriteAtlas == null)
|
|
{
|
|
AR.spriteAtlas = handle.Result;
|
|
}
|
|
Debug.Log("ReleaseAtlas Load Succeeded ===>" + sName);
|
|
SetSpriteSpriteName(imageData, AR, sprites);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("ReleaseAtlas Load Failed ===>" + sName);
|
|
Addressables.Release(AR.handle);
|
|
atlasReference.Remove(sName);
|
|
}
|
|
};
|
|
}
|
|
else
|
|
{
|
|
if (AR.spriteAtlas != null)
|
|
{
|
|
SetSpriteSpriteName(imageData, AR, sprites);
|
|
}
|
|
else
|
|
{
|
|
AR.handle.Completed += (handle) =>
|
|
{
|
|
if (handle.Status == AsyncOperationStatus.Succeeded)
|
|
{
|
|
if (AR.spriteAtlas == null)
|
|
{
|
|
AR.spriteAtlas = handle.Result;
|
|
}
|
|
SetSpriteSpriteName(imageData, AR, sprites);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("ReleaseAtlas Completed Failed ===>" + sName);
|
|
|
|
}
|
|
};
|
|
}
|
|
}
|
|
}
|
|
void SetSpriteSpriteName(IShowImageData imageData, AtlasReference AR, Dictionary<string, Sprite> sprites)
|
|
{
|
|
string spriteName = imageData.spriteName;
|
|
if (imageData.image != null)
|
|
{
|
|
if (!sprites.ContainsKey(spriteName))
|
|
{
|
|
var value = AR.spriteAtlas.GetSprite(spriteName);
|
|
if (value != null)
|
|
{
|
|
sprites[spriteName] = value;
|
|
AR.referenceCount++;
|
|
|
|
imageData.SetImage(sprites[spriteName]);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("spriteName===>" + spriteName + " spriteAtlas===>" + AR.spriteAtlas.name);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
imageData.SetImage(sprites[spriteName]);
|
|
}
|
|
}
|
|
}
|
|
}
|