[+] TEngineServer

[+] TEngineServer
This commit is contained in:
ALEXTANG
2023-07-13 17:17:26 +08:00
parent a69f53592e
commit 0c8f3a5f92
790 changed files with 52737 additions and 2533 deletions

View File

@@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
namespace TEngine.Core
{
public sealed class CoroutineLockQueue : IDisposable
{
public long Key { get; private set; }
public CoroutineLockQueueType CoroutineLockQueueType { get; private set; }
private readonly Queue<WaitCoroutineLock> _waitCoroutineLocks = new Queue<WaitCoroutineLock>();
public static CoroutineLockQueue Create(long key, int time, CoroutineLockQueueType coroutineLockQueueType)
{
var coroutineLockQueue = Pool<CoroutineLockQueue>.Rent();
coroutineLockQueue.Key = key;
coroutineLockQueue.CoroutineLockQueueType = coroutineLockQueueType;
return coroutineLockQueue;
}
public void Dispose()
{
Key = 0;
CoroutineLockQueueType = null;
Pool<CoroutineLockQueue>.Return(this);
}
public async FTask<WaitCoroutineLock> Lock(string tag, int time)
{
#if TENGINE_DEVELOP
if (_waitCoroutineLocks.Count >= 100)
{
// 当等待队列超过100个、表示这个协程锁可能有问题、打印一个警告方便排查错误
Log.Warning($"too much waitCoroutineLock CoroutineLockQueueType:{CoroutineLockQueueType.Name} Key:{Key} Count: {_waitCoroutineLocks.Count} ");
}
#endif
var waitCoroutineLock = WaitCoroutineLock.Create(this, tag, time);
_waitCoroutineLocks.Enqueue(waitCoroutineLock);
return await waitCoroutineLock.Tcs;
}
public void Release()
{
if (_waitCoroutineLocks.Count == 0)
{
CoroutineLockQueueType.Remove(Key);
return;
}
while (_waitCoroutineLocks.TryDequeue(out var waitCoroutineLock))
{
if (waitCoroutineLock.IsDisposed)
{
continue;
}
waitCoroutineLock.SetResult();
break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8f07b80619d455d4499aefbc3eab9f65
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
namespace TEngine.Core
{
public sealed class CoroutineLockQueueType
{
public readonly string Name;
private readonly Dictionary<long, CoroutineLockQueue> _coroutineLockQueues = new Dictionary<long, CoroutineLockQueue>();
private CoroutineLockQueueType() { }
public CoroutineLockQueueType(string name)
{
Name = name;
}
public async FTask<WaitCoroutineLock> Lock(long key, string tag = null, int time = 10000)
{
if (_coroutineLockQueues.TryGetValue(key, out var coroutineLockQueue))
{
return await coroutineLockQueue.Lock(tag,time);
}
coroutineLockQueue = CoroutineLockQueue.Create(key, time, this);
_coroutineLockQueues.Add(key, coroutineLockQueue);
return WaitCoroutineLock.Create(coroutineLockQueue, tag, time);
}
public void Remove(long key)
{
if (_coroutineLockQueues.Remove(key, out var coroutineLockQueue))
{
coroutineLockQueue.Dispose();
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2067a4304a800324bbe9c547eefac9fa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,93 @@
using System;
using TEngine.Core;
namespace TEngine.Core
{
public struct CoroutineLockTimeout
{
public long LockId;
public WaitCoroutineLock WaitCoroutineLock;
}
public sealed class OnCoroutineLockTimeout : EventSystem<CoroutineLockTimeout>
{
public override void Handler(CoroutineLockTimeout self)
{
if (self.LockId != self.WaitCoroutineLock.LockId)
{
return;
}
var coroutineLockQueue = self.WaitCoroutineLock.CoroutineLockQueue;
var coroutineLockQueueType = coroutineLockQueue.CoroutineLockQueueType;
var key = coroutineLockQueue.Key;
Log.Error($"coroutine lock timeout CoroutineLockQueueType:{coroutineLockQueueType.Name} Key:{key} Tag:{self.WaitCoroutineLock.Tag}");
}
}
public sealed class WaitCoroutineLock : IDisposable
{
private long _timerId;
public bool IsDisposed => LockId == 0;
public string Tag { get; private set; }
public long LockId { get; private set; }
public FTask<WaitCoroutineLock> Tcs { get; private set; }
public CoroutineLockQueue CoroutineLockQueue{ get; private set; }
public static WaitCoroutineLock Create(CoroutineLockQueue coroutineLockQueue, string tag, int timeOut)
{
var lockId = IdFactory.NextRunTimeId();
var waitCoroutineLock = Pool<WaitCoroutineLock>.Rent();
waitCoroutineLock.Tag = tag;
waitCoroutineLock.LockId = lockId;
waitCoroutineLock.CoroutineLockQueue = coroutineLockQueue;
waitCoroutineLock.Tcs = FTask<WaitCoroutineLock>.Create();
waitCoroutineLock._timerId = TimerScheduler.Instance.Core.OnceTimer(timeOut, new CoroutineLockTimeout()
{
LockId = lockId, WaitCoroutineLock = waitCoroutineLock
});
return waitCoroutineLock;
}
public void Dispose()
{
if (IsDisposed)
{
Log.Error("WaitCoroutineLock is Dispose");
return;
}
Release(CoroutineLockQueue);
LockId = 0;
Tcs = null;
Tag = null;
CoroutineLockQueue = null;
if (_timerId != 0)
{
TimerScheduler.Instance.Core.RemoveByRef(ref _timerId);
}
Pool<WaitCoroutineLock>.Return(this);
}
private static void Release(CoroutineLockQueue coroutineLockQueue)
{
// 放到下一帧执行释放锁、如果不这样、会导致逻辑的顺序不正常
ThreadSynchronizationContext.Main.Post(coroutineLockQueue.Release);
}
public void SetResult()
{
if (Tcs == null)
{
throw new NullReferenceException("SetResult tcs is null");
}
Tcs.SetResult(this);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1ee0d61ec53909c4695fe2ecc97f42bd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: