using System; using System.Collections.Generic; using System.Threading.Tasks; using MrWu.Debug; namespace Server.Core { public class CoroutineLockManager : ICoroutineLockManager { /// /// 协程锁类型队列 /// private readonly Dictionary CoroutineLockQueueTypes = new Dictionary(); /// /// item1 协程锁类型 item2 锁的key item3 锁的层级 /// private readonly Queue<(int, long, int)> nextFrameRun = new Queue<(int, long, int)>(); private CoroutineLockQueueType GetOrAdd(int coroutineLockType) { if (!this.CoroutineLockQueueTypes.TryGetValue(coroutineLockType, out CoroutineLockQueueType coroutineLockQueueType)) { coroutineLockQueueType = new CoroutineLockQueueType(coroutineLockType,this); this.CoroutineLockQueueTypes.Add(coroutineLockType, coroutineLockQueueType); } return coroutineLockQueueType; } private CoroutineLockQueueType Get(int coroutineLockType) { if (!this.CoroutineLockQueueTypes.TryGetValue(coroutineLockType, out CoroutineLockQueueType coroutineLockQueueType)) { coroutineLockQueueType = null; } return coroutineLockQueueType; } public void Update() { while (this.nextFrameRun.Count > 0) { Debug.Log("Update!"); (int coroutineLockType, long key, int count) = this.nextFrameRun.Dequeue(); this.Notify(coroutineLockType, key, count); } } public void RunNextCoroutine(int coroutineLockType,long key,int level) { if (level == 100) { Debug.Warning($"too much coroutine level: {coroutineLockType} {key}"); } Debug.Log("RunNextCoroutine !!!"); this.nextFrameRun.Enqueue((coroutineLockType,key,level)); } private void Notify(int coroutineLockType, long key, int level) { Debug.Log($"Notify {coroutineLockType} {key} {level}"); CoroutineLockQueueType coroutineLockQueueType = Get(coroutineLockType); if (coroutineLockQueueType == null) { Debug.Error("coroutineLockQueueType is null!"); return; } coroutineLockQueueType.Notify(key, level); } #region ICoroutineLockManager /// /// 获取协程锁 /// /// /// /// public async Task Wait(int coroutineLockType, long key, int time = 600000) { CoroutineLockQueueType coroutineLockQueueType = this.GetOrAdd(coroutineLockType); //Debug.Log("CoroutineLockManager Wait"); return await coroutineLockQueueType.Wait(key, time); } #endregion } }