123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- using XGame.Framework.Asyncs;
- using System.Collections.Generic;
- namespace XGame.Framework.Asset
- {
- /// <summary>
- /// 加载任务的异步操作池
- /// </summary>
- internal sealed class AssetAsyncPool
- {
- /// <summary>
- /// 未使用的Agents
- /// </summary>
- Stack<IAssetAsyncAgent> FreeAgents { set; get; }
- /// <summary>
- /// 使用中的Agents
- /// </summary>
- //LinkedList<IAssetAsyncAgent> WorkingAgents { set; get; }
- Dictionary<IAssetAsync, IAssetAsyncAgent> WorkingAgents { set; get; }
- /// <summary>
- /// 等待处理的Async
- /// </summary>
- LinkedList<IAssetAsync> WaitingAsyncs { set; get; }
- /// <summary>
- /// 存储所有未完成的Async,方便查找
- /// </summary>
- Dictionary<string, IAssetAsync> AssetAsyncMap { set; get; }
- /// <summary>
- /// 是否被暂停。
- /// </summary>
- public bool Paused { set; get; }
- /// <summary>
- /// agent的数量上限
- /// </summary>
- public int AgentLimit { set; get; }
- /// <summary>
- /// 构造函数。
- /// </summary>
- public AssetAsyncPool()
- {
- FreeAgents = new Stack<IAssetAsyncAgent>();
- WorkingAgents = new Dictionary<IAssetAsync, IAssetAsyncAgent>();
- WaitingAsyncs = new LinkedList<IAssetAsync>();
- AssetAsyncMap = new Dictionary<string, IAssetAsync>();
- Paused = false;
- AgentLimit = 0;
- }
- /// <summary>
- /// 获取代理总数量。
- /// 包括使用中和未使用的代理,不一定等于AgentLimit
- /// </summary>
- public int TotalAgentCount => (FreeAgentCount + WorkingAgentCount);
- /// <summary>
- /// 获取可用代理数量。
- /// 仅返回缓存池中未使用的代理数量
- /// </summary>
- public int FreeAgentCount => FreeAgents.Count;
- /// <summary>
- /// 获取工作中代理数量。
- /// </summary>
- public int WorkingAgentCount => WorkingAgents.Count;
- /// <summary>
- /// 获取等待Async数量。
- /// </summary>
- public int WaitingAsyncCount => WaitingAsyncs.Count;
- /// <summary>
- /// 获取未完成的Async
- /// </summary>
- /// <param name="addressableName"></param>
- /// <returns></returns>
- public IAssetAsync GetAssetAsync(string addressableName)
- {
- AssetAsyncMap.TryGetValue(addressableName, out IAssetAsync assetAsync);
- return assetAsync;
- }
- /// <summary>
- /// 是否包含指定的Async
- /// </summary>
- /// <param name="path"></param>
- /// <returns></returns>
- public bool ContainsAssetAsync(string addressableName)
- {
- return AssetAsyncMap.ContainsKey(addressableName);
- }
- /// <summary>
- /// 获取未使用的Agent
- /// 可能从缓存里取,也可能是新建的Agent
- /// </summary>
- /// <returns></returns>
- private IAssetAsyncAgent GetFreeAgent()
- {
- if (FreeAgents.Count > 0)
- {
- return FreeAgents.Pop();
- }
- if (TotalAgentCount < AgentLimit)
- {
- var agent = new AssetAsyncAgent();
- return agent;
- }
- return null;
- }
- /// <summary>
- /// 增加AssetAsync。
- /// </summary>
- /// <param name="assetAsync"></param>
- public void AddAsync(IAssetAsync assetAsync)
- {
- if (AssetAsyncMap.ContainsKey(assetAsync.AddressableName))
- {
- //AssetsLog.Debug("Asset Add Async Repeat. Name:{0}", assetAsync.AddressableName);
- return;
- }
- AssetAsyncMap.Add(assetAsync.AddressableName, assetAsync);
- LinkedListNode<IAssetAsync> current = WaitingAsyncs.Last;
- if (current != null)
- {
- WaitingAsyncs.AddAfter(current, assetAsync);
- }
- else
- {
- WaitingAsyncs.AddFirst(assetAsync);
- }
- ProcessWaitingAsync();
- }
- ///// <summary>
- ///// 移除任务。
- ///// </summary>
- ///// <param name="serialId">要移除任务的序列编号。</param>
- ///// <returns>被移除的任务。</returns>
- //public bool RemoveAsync(int serialId)
- //{
- // foreach (IAssetAsync waitingAsync in WaitingAsyncs)
- // {
- // if (waitingAsync.SerialId == serialId)
- // {
- // WaitingAsyncs.Remove(waitingAsync);
- // return true;
- // }
- // }
- // foreach (IAssetAsyncAgent workingAgent in WorkingAgents)
- // {
- // if (workingAgent.Task.SerialId == serialId)
- // {
- // workingAgent.Stop();
- // m_FreeAgents.Push(workingAgent);
- // WorkingAgents.Remove(workingAgent);
- // return true;
- // }
- // }
- // return false;
- //}
- private void ProcessWaitingAsync()
- {
- LinkedListNode<IAssetAsync> current = WaitingAsyncs.First;
- IAssetAsyncAgent agent;
- while (current != null && (agent = GetFreeAgent()) != null)
- {
- LinkedListNode<IAssetAsync> next = current.Next;
- AgentStatus status = agent.Start(current.Value);
- if (status == AgentStatus.CanResume)
- {//设置监听
- current.Value.On(OnAsyncCompleted);
- WorkingAgents.Add(current.Value, agent);
- }
- else
- {
- agent.Stop();
- FreeAgents.Push(agent);
- if (status == AgentStatus.Done || status == AgentStatus.UnknownError)
- {
- AssetAsyncMap.Remove(current.Value.AddressableName);
- }
- }
- if (status != AgentStatus.HasToWait)
- {
- WaitingAsyncs.Remove(current);
- }
- current = next;
- }
- }
- void OnAsyncCompleted(IAsync aAsync)
- {
- IAssetAsync assetAsync = aAsync as IAssetAsync;
- if (assetAsync != null)
- {
- if (WorkingAgents.TryGetValue(assetAsync, out IAssetAsyncAgent agent))
- {
- agent.Stop();
- WorkingAgents.Remove(assetAsync);
- FreeAgents.Push(agent);
- }
- AssetAsyncMap.Remove(assetAsync.AddressableName);
- }
- ProcessWaitingAsync();
- }
- /// <summary>
- /// 移除所有任务。
- /// </summary>
- public void Clear()
- {
- WaitingAsyncs.Clear();
- AssetAsyncMap.Clear();
- foreach (var it in WorkingAgents)
- {
- it.Value.Stop();
- FreeAgents.Push(it.Value);
- }
- WorkingAgents.Clear();
- }
- public void Dispose()
- {
- WaitingAsyncs.Clear();
- while (FreeAgentCount > 0)
- {
- FreeAgents.Pop().Dispose();
- }
- foreach (var it in WorkingAgents)
- {
- it.Value.Dispose();
- }
- WorkingAgents.Clear();
- AssetAsyncMap.Clear();
- }
- }
- }
|