| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480 |
- using System;
- using System.Collections.Generic;
- using System.Threading.Tasks;
- using GameFramework;
- using GameFramework.DataTable;
- using GameFramework.Event;
- using GameFramework.Resource;
- using UnityEngine;
- using UnityGameFramework.Runtime;
- namespace UGFExtensions.Await
- {
- public static partial class AwaitableExtensions
- {
- private static readonly Dictionary<int, TaskCompletionSource<UIForm>> s_UIFormTcs =
- new Dictionary<int, TaskCompletionSource<UIForm>>();
- private static readonly Dictionary<int, TaskCompletionSource<Entity>> s_EntityTcs =
- new Dictionary<int, TaskCompletionSource<Entity>>();
- private static readonly Dictionary<string, TaskCompletionSource<bool>> s_DataTableTcs =
- new Dictionary<string, TaskCompletionSource<bool>>();
- private static readonly Dictionary<string, TaskCompletionSource<bool>> s_LoadSceneTcs =
- new Dictionary<string, TaskCompletionSource<bool>>();
- private static readonly Dictionary<string, TaskCompletionSource<bool>> s_UnLoadSceneTcs =
- new Dictionary<string, TaskCompletionSource<bool>>();
- private static readonly HashSet<int> s_WebSerialIDs = new HashSet<int>();
- private static readonly List<WebResult> s_DelayReleaseWebResult = new List<WebResult>();
- private static readonly HashSet<int> s_DownloadSerialIds = new HashSet<int>();
- private static readonly List<DownLoadResult> s_DelayReleaseDownloadResult = new List<DownLoadResult>();
- #if UNITY_EDITOR
- private static bool s_IsSubscribeEvent = false;
- #endif
- /// <summary>
- /// 注册需要的事件 (需再流程入口处调用 防止框架重启导致事件被取消问题)
- /// </summary>
- public static void SubscribeEvent()
- {
- EventComponent eventComponent = UnityGameFramework.Runtime.GameEntry.GetComponent<EventComponent>();
- eventComponent.Subscribe(OpenUIFormSuccessEventArgs.EventId, OnOpenUIFormSuccess);
- eventComponent.Subscribe(OpenUIFormFailureEventArgs.EventId, OnOpenUIFormFailure);
- eventComponent.Subscribe(ShowEntitySuccessEventArgs.EventId, OnShowEntitySuccess);
- eventComponent.Subscribe(ShowEntityFailureEventArgs.EventId, OnShowEntityFailure);
- eventComponent.Subscribe(LoadSceneSuccessEventArgs.EventId, OnLoadSceneSuccess);
- eventComponent.Subscribe(LoadSceneFailureEventArgs.EventId, OnLoadSceneFailure);
- eventComponent.Subscribe(UnloadSceneSuccessEventArgs.EventId, OnUnloadSceneSuccess);
- eventComponent.Subscribe(UnloadSceneFailureEventArgs.EventId, OnUnloadSceneFailure);
- // eventComponent.Subscribe(LoadDataTableSuccessEventArgs.EventId, OnLoadDataTableSuccess);
- // eventComponent.Subscribe(LoadDataTableFailureEventArgs.EventId, OnLoadDataTableFailure);
- eventComponent.Subscribe(WebRequestSuccessEventArgs.EventId, OnWebRequestSuccess);
- eventComponent.Subscribe(WebRequestFailureEventArgs.EventId, OnWebRequestFailure);
- eventComponent.Subscribe(DownloadSuccessEventArgs.EventId, OnDownloadSuccess);
- eventComponent.Subscribe(DownloadFailureEventArgs.EventId, OnDownloadFailure);
- #if UNITY_EDITOR
- s_IsSubscribeEvent = true;
- #endif
- }
- #if UNITY_EDITOR
- private static void TipsSubscribeEvent()
- {
- if (!s_IsSubscribeEvent)
- {
- throw new Exception("Use await/async extensions must to subscribe event!");
- }
- }
- #endif
- /// <summary>
- /// 打开界面(可等待)
- /// </summary>
- public static Task<UIForm> OpenUIFormAsync(this UIComponent uiComponent,string uiFormAssetName, string uiGroupName, int priority, bool pauseCoveredUIForm, object userData)
- {
- #if UNITY_EDITOR
- TipsSubscribeEvent();
- #endif
- int serialId = uiComponent.OpenUIForm(uiFormAssetName, uiGroupName, priority, pauseCoveredUIForm, userData);
- var tcs = new TaskCompletionSource<UIForm>();
- s_UIFormTcs.Add(serialId, tcs);
- return tcs.Task;
- }
- private static void OnOpenUIFormSuccess(object sender, GameEventArgs e)
- {
- OpenUIFormSuccessEventArgs ne = (OpenUIFormSuccessEventArgs)e;
- s_UIFormTcs.TryGetValue(ne.UIForm.SerialId, out TaskCompletionSource<UIForm> tcs);
- if (tcs != null)
- {
- tcs.SetResult(ne.UIForm);
- s_UIFormTcs.Remove(ne.UIForm.SerialId);
- }
- }
- private static void OnOpenUIFormFailure(object sender, GameEventArgs e)
- {
- OpenUIFormFailureEventArgs ne = (OpenUIFormFailureEventArgs)e;
- s_UIFormTcs.TryGetValue(ne.SerialId, out TaskCompletionSource<UIForm> tcs);
- if (tcs != null)
- {
- Debug.LogError(ne.ErrorMessage);
- tcs.SetException(new GameFrameworkException(ne.ErrorMessage));
- s_UIFormTcs.Remove(ne.SerialId);
- }
- }
- /// <summary>
- /// 显示实体(可等待)
- /// </summary>
- public static Task<Entity> ShowEntityAsync(this EntityComponent entityComponent, int entityId,
- Type entityLogicType, string entityAssetName, string entityGroupName, int priority,object userData)
- {
- #if UNITY_EDITOR
- TipsSubscribeEvent();
- #endif
- var tcs = new TaskCompletionSource<Entity>();
- s_EntityTcs.Add(entityId, tcs);
- entityComponent.ShowEntity(entityId, entityLogicType, entityAssetName, entityGroupName, priority, userData);
- return tcs.Task;
- }
- private static void OnShowEntitySuccess(object sender, GameEventArgs e)
- {
- ShowEntitySuccessEventArgs ne = (ShowEntitySuccessEventArgs)e;
- s_EntityTcs.TryGetValue(ne.Entity.Id, out var tcs);
- if (tcs != null)
- {
- tcs.SetResult(ne.Entity);
- s_EntityTcs.Remove(ne.Entity.Id);
- }
- }
- private static void OnShowEntityFailure(object sender, GameEventArgs e)
- {
- ShowEntityFailureEventArgs ne = (ShowEntityFailureEventArgs)e;
- s_EntityTcs.TryGetValue(ne.EntityId, out var tcs);
- if (tcs != null)
- {
- Debug.LogError(ne.ErrorMessage);
- tcs.SetException(new GameFrameworkException(ne.ErrorMessage));
- s_EntityTcs.Remove(ne.EntityId);
- }
- }
- /// <summary>
- /// 加载场景(可等待)
- /// </summary>
- public static async Task<bool> LoadSceneAsync(this SceneComponent sceneComponent, string sceneAssetName)
- {
- #if UNITY_EDITOR
- TipsSubscribeEvent();
- #endif
- var tcs = new TaskCompletionSource<bool>();
- var isUnLoadScene = s_UnLoadSceneTcs.TryGetValue(sceneAssetName, out var unloadSceneTcs);
- if (isUnLoadScene)
- {
- await unloadSceneTcs.Task;
- }
- s_LoadSceneTcs.Add(sceneAssetName, tcs);
- try
- {
- sceneComponent.LoadScene(sceneAssetName);
- }
- catch (Exception e)
- {
- Debug.LogError(e.ToString());
- tcs.SetException(e);
- s_LoadSceneTcs.Remove(sceneAssetName);
- }
- return await tcs.Task;
- }
- private static void OnLoadSceneSuccess(object sender, GameEventArgs e)
- {
- LoadSceneSuccessEventArgs ne = (LoadSceneSuccessEventArgs)e;
- s_LoadSceneTcs.TryGetValue(ne.SceneAssetName, out var tcs);
- if (tcs != null)
- {
- tcs.SetResult(true);
- s_LoadSceneTcs.Remove(ne.SceneAssetName);
- }
- }
- private static void OnLoadSceneFailure(object sender, GameEventArgs e)
- {
- LoadSceneFailureEventArgs ne = (LoadSceneFailureEventArgs)e;
- s_LoadSceneTcs.TryGetValue(ne.SceneAssetName, out var tcs);
- if (tcs != null)
- {
- Debug.LogError(ne.ErrorMessage);
- tcs.SetException(new GameFrameworkException(ne.ErrorMessage));
- s_LoadSceneTcs.Remove(ne.SceneAssetName);
- }
- }
-
- /// <summary>
- /// 卸载场景(可等待)
- /// </summary>
- public static async Task<bool> UnLoadSceneAsync(this SceneComponent sceneComponent, string sceneAssetName)
- {
- #if UNITY_EDITOR
- TipsSubscribeEvent();
- #endif
- var tcs = new TaskCompletionSource<bool>();
- var isLoadSceneTcs = s_LoadSceneTcs.TryGetValue(sceneAssetName, out var loadSceneTcs);
- if (isLoadSceneTcs)
- {
- Debug.Log("Unload loading scene");
- await loadSceneTcs.Task;
- }
- s_UnLoadSceneTcs.Add(sceneAssetName, tcs);
- try
- {
- sceneComponent.UnloadScene(sceneAssetName);
- }
- catch (Exception e)
- {
- Debug.LogError(e.ToString());
- tcs.SetException(e);
- s_UnLoadSceneTcs.Remove(sceneAssetName);
- }
- return await tcs.Task;
- }
- private static void OnUnloadSceneSuccess(object sender, GameEventArgs e)
- {
- UnloadSceneSuccessEventArgs ne = (UnloadSceneSuccessEventArgs)e;
- s_UnLoadSceneTcs.TryGetValue(ne.SceneAssetName, out var tcs);
- if (tcs != null)
- {
- tcs.SetResult(true);
- s_UnLoadSceneTcs.Remove(ne.SceneAssetName);
- }
- }
- private static void OnUnloadSceneFailure(object sender, GameEventArgs e)
- {
- UnloadSceneFailureEventArgs ne = (UnloadSceneFailureEventArgs)e;
- s_UnLoadSceneTcs.TryGetValue(ne.SceneAssetName, out var tcs);
- if (tcs != null)
- {
- Debug.LogError($"Unload scene {ne.SceneAssetName} failure.");
- tcs.SetException(new GameFrameworkException($"Unload scene {ne.SceneAssetName} failure."));
- s_UnLoadSceneTcs.Remove(ne.SceneAssetName);
- }
- }
- /// <summary>
- /// 加载资源(可等待)
- /// </summary>
- public static Task<T> LoadAssetAsync<T>(this ResourceComponent resourceComponent, string assetName)
- where T : UnityEngine.Object
- {
- #if UNITY_EDITOR
- TipsSubscribeEvent();
- #endif
- TaskCompletionSource<T> loadAssetTcs = new TaskCompletionSource<T>();
- resourceComponent.LoadAsset(assetName, typeof(T), new LoadAssetCallbacks(
- (tempAssetName, asset, duration, userdata) =>
- {
- var source = loadAssetTcs;
- loadAssetTcs = null;
- T tAsset = asset as T;
- if (tAsset != null)
- {
- source.SetResult(tAsset);
- }
- else
- {
- Debug.LogError($"Load asset failure load type is {asset.GetType()} but asset type is {typeof(T)}.");
- source.SetException(new GameFrameworkException(
- $"Load asset failure load type is {asset.GetType()} but asset type is {typeof(T)}."));
- }
- },
- (tempAssetName, status, errorMessage, userdata) =>
- {
- Debug.LogError(errorMessage);
- loadAssetTcs.SetException(new GameFrameworkException(errorMessage));
- }
- ));
- return loadAssetTcs.Task;
- }
- /// <summary>
- /// 加载多个资源(可等待)
- /// </summary>
- public static async Task<T[]> LoadAssetsAsync<T>(this ResourceComponent resourceComponent, string[] assetName) where T : UnityEngine.Object
- {
- #if UNITY_EDITOR
- TipsSubscribeEvent();
- #endif
- if (assetName == null)
- {
- return null;
- }
- T[] assets = new T[assetName.Length];
- Task<T>[] tasks = new Task<T>[assets.Length];
- for (int i = 0; i < tasks.Length; i++)
- {
- tasks[i] = resourceComponent.LoadAssetAsync<T>(assetName[i]);
- }
- await Task.WhenAll(tasks);
- for (int i = 0; i < assets.Length; i++)
- {
- assets[i] = tasks[i].Result;
- }
- return assets;
- }
- /// <summary>
- /// 增加Web请求任务(可等待)
- /// </summary>
- public static Task<WebResult> AddWebRequestAsync(this WebRequestComponent webRequestComponent,
- string webRequestUri, WWWForm wwwForm = null, object userdata = null)
- {
- #if UNITY_EDITOR
- TipsSubscribeEvent();
- #endif
- var tsc = new TaskCompletionSource<WebResult>();
- int serialId = webRequestComponent.AddWebRequest(webRequestUri, wwwForm,
- AwaitDataWrap<WebResult>.Create(userdata, tsc));
- s_WebSerialIDs.Add(serialId);
- return tsc.Task;
- }
- /// <summary>
- /// 增加Web请求任务(可等待)
- /// </summary>
- public static Task<WebResult> AddWebRequestAsync(this WebRequestComponent webRequestComponent,
- string webRequestUri, byte[] postData, object userdata = null)
- {
- #if UNITY_EDITOR
- TipsSubscribeEvent();
- #endif
- var tsc = new TaskCompletionSource<WebResult>();
- int serialId = webRequestComponent.AddWebRequest(webRequestUri, postData,
- AwaitDataWrap<WebResult>.Create(userdata, tsc));
- s_WebSerialIDs.Add(serialId);
- return tsc.Task;
- }
- private static void OnWebRequestSuccess(object sender, GameEventArgs e)
- {
- WebRequestSuccessEventArgs ne = (WebRequestSuccessEventArgs)e;
- if (s_WebSerialIDs.Contains(ne.SerialId))
- {
- if (ne.UserData is AwaitDataWrap<WebResult> webRequestUserdata)
- {
- WebResult result = WebResult.Create(ne.GetWebResponseBytes(), false, string.Empty,
- webRequestUserdata.UserData);
- s_DelayReleaseWebResult.Add(result);
- webRequestUserdata.Source.TrySetResult(result);
- ReferencePool.Release(webRequestUserdata);
- }
- s_WebSerialIDs.Remove(ne.SerialId);
- if (s_WebSerialIDs.Count == 0)
- {
- for (int i = 0; i < s_DelayReleaseWebResult.Count; i++)
- {
- ReferencePool.Release(s_DelayReleaseWebResult[i]);
- }
- s_DelayReleaseWebResult.Clear();
- }
- }
- }
- private static void OnWebRequestFailure(object sender, GameEventArgs e)
- {
- WebRequestFailureEventArgs ne = (WebRequestFailureEventArgs)e;
- if (s_WebSerialIDs.Contains(ne.SerialId))
- {
- if (ne.UserData is AwaitDataWrap<WebResult> webRequestUserdata)
- {
- WebResult result = WebResult.Create(null, true, ne.ErrorMessage, webRequestUserdata.UserData);
- webRequestUserdata.Source.TrySetResult(result);
- s_DelayReleaseWebResult.Add(result);
- ReferencePool.Release(webRequestUserdata);
- }
- s_WebSerialIDs.Remove(ne.SerialId);
- if (s_WebSerialIDs.Count == 0)
- {
- for (int i = 0; i < s_DelayReleaseWebResult.Count; i++)
- {
- ReferencePool.Release(s_DelayReleaseWebResult[i]);
- }
- s_DelayReleaseWebResult.Clear();
- }
- }
- }
- /// <summary>
- /// 增加下载任务(可等待)
- /// </summary>
- public static Task<DownLoadResult> AddDownloadAsync(this DownloadComponent downloadComponent,
- string downloadPath,
- string downloadUri,
- object userdata = null)
- {
- #if UNITY_EDITOR
- TipsSubscribeEvent();
- #endif
- var tcs = new TaskCompletionSource<DownLoadResult>();
- int serialId = downloadComponent.AddDownload(downloadPath, downloadUri,
- AwaitDataWrap<DownLoadResult>.Create(userdata, tcs));
- s_DownloadSerialIds.Add(serialId);
- return tcs.Task;
- }
- private static void OnDownloadSuccess(object sender, GameEventArgs e)
- {
- DownloadSuccessEventArgs ne = (DownloadSuccessEventArgs)e;
- if (s_DownloadSerialIds.Contains(ne.SerialId))
- {
- if (ne.UserData is AwaitDataWrap<DownLoadResult> awaitDataWrap)
- {
- DownLoadResult result = DownLoadResult.Create(false, string.Empty, awaitDataWrap.UserData);
- s_DelayReleaseDownloadResult.Add(result);
- awaitDataWrap.Source.TrySetResult(result);
- ReferencePool.Release(awaitDataWrap);
- }
- s_DownloadSerialIds.Remove(ne.SerialId);
- if (s_DownloadSerialIds.Count == 0)
- {
- for (int i = 0; i < s_DelayReleaseDownloadResult.Count; i++)
- {
- ReferencePool.Release(s_DelayReleaseDownloadResult[i]);
- }
- s_DelayReleaseDownloadResult.Clear();
- }
- }
- }
- private static void OnDownloadFailure(object sender, GameEventArgs e)
- {
- DownloadFailureEventArgs ne = (DownloadFailureEventArgs)e;
- if (s_DownloadSerialIds.Contains(ne.SerialId))
- {
- if (ne.UserData is AwaitDataWrap<DownLoadResult> awaitDataWrap)
- {
- DownLoadResult result = DownLoadResult.Create(true, ne.ErrorMessage, awaitDataWrap.UserData);
- s_DelayReleaseDownloadResult.Add(result);
- awaitDataWrap.Source.TrySetResult(result);
- ReferencePool.Release(awaitDataWrap);
- }
- s_DownloadSerialIds.Remove(ne.SerialId);
- if (s_DownloadSerialIds.Count == 0)
- {
- for (int i = 0; i < s_DelayReleaseDownloadResult.Count; i++)
- {
- ReferencePool.Release(s_DelayReleaseDownloadResult[i]);
- }
- s_DelayReleaseDownloadResult.Clear();
- }
- }
- }
- }
- }
|