Procházet zdrojové kódy

实现ETTask的GetCancelToken

tanghai před 1 rokem
rodič
revize
386ae741f6

+ 0 - 63
Unity/Packages/cn.etetet.core/Runtime/ETTask/AsyncETTaskCompletedMethodBuilder.cs

@@ -1,63 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Security;
-
-namespace ET
-{
-    public struct AsyncETTaskCompletedMethodBuilder
-    {
-        // 1. Static Create method.
-        [DebuggerHidden]
-        public static AsyncETTaskCompletedMethodBuilder Create()
-        {
-            AsyncETTaskCompletedMethodBuilder builder = new();
-            return builder;
-        }
-
-        // 2. TaskLike Task property(void)
-        public ETTaskCompleted Task => default;
-
-        // 3. SetException
-        [DebuggerHidden]
-        public void SetException(Exception e)
-        {
-            ETTask.ExceptionHandler.Invoke(e);
-        }
-
-        // 4. SetResult
-        [DebuggerHidden]
-        public void SetResult()
-        {
-            // do nothing
-        }
-
-        // 5. AwaitOnCompleted
-        [DebuggerHidden]
-        public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine
-        {
-            //awaiter.OnCompleted(stateMachine.MoveNext);
-        }
-
-        // 6. AwaitUnsafeOnCompleted
-        [DebuggerHidden]
-        [SecuritySafeCritical]
-        public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine
-        {
-            //awaiter.UnsafeOnCompleted(stateMachine.MoveNext);
-        }
-
-        // 7. Start
-        [DebuggerHidden]
-        public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
-        {
-            //stateMachine.MoveNext();
-        }
-
-        // 8. SetStateMachine
-        [DebuggerHidden]
-        public void SetStateMachine(IAsyncStateMachine stateMachine)
-        {
-        }
-    }
-}

+ 0 - 11
Unity/Packages/cn.etetet.core/Runtime/ETTask/AsyncETTaskCompletedMethodBuilder.cs.meta

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

+ 29 - 1
Unity/Packages/cn.etetet.core/Runtime/ETTask/AsyncETTaskMethodBuilder.cs

@@ -49,7 +49,7 @@ namespace ET
 
         // 5. AwaitOnCompleted
         [DebuggerHidden]
-        public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine
+        public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : class, IETTask, INotifyCompletion where TStateMachine : IAsyncStateMachine
         {
             this.iStateMachineWrap ??= StateMachineWrap<TStateMachine>.Fetch(ref stateMachine);
             awaiter.OnCompleted(this.iStateMachineWrap.MoveNext);
@@ -62,6 +62,20 @@ namespace ET
         {
             this.iStateMachineWrap ??= StateMachineWrap<TStateMachine>.Fetch(ref stateMachine);
             awaiter.UnsafeOnCompleted(this.iStateMachineWrap.MoveNext);
+
+            if (awaiter is not IETTask task)
+            {
+                return;
+            }
+
+            if (this.tcs.TaskType == TaskType.WithToken)
+            {
+                ETCancellationToken cancellationToken = this.tcs.Object as ETCancellationToken;
+                task.SetCancelToken(cancellationToken);
+                return;
+            }
+            
+            this.tcs.Object = task;
         }
 
         // 7. Start
@@ -135,6 +149,20 @@ namespace ET
         {
             this.iStateMachineWrap ??= StateMachineWrap<TStateMachine>.Fetch(ref stateMachine);
             awaiter.UnsafeOnCompleted(this.iStateMachineWrap.MoveNext);
+            
+            if (awaiter is not IETTask task)
+            {
+                return;
+            }
+            
+            if (this.tcs.TaskType == TaskType.WithToken)
+            {
+                ETCancellationToken cancellationToken = this.tcs.Object as ETCancellationToken;
+                task.SetCancelToken(cancellationToken);
+                return;
+            }
+            
+            this.tcs.Object = task;
         }
 
         // 7. Start

+ 2 - 2
Unity/Packages/cn.etetet.core/Runtime/ETTask/AsyncETVoidMethodBuilder.cs

@@ -46,7 +46,7 @@ namespace ET
 
         // 5. AwaitOnCompleted
         [DebuggerHidden]
-        public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine
+        public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : IETTask, INotifyCompletion where TStateMachine : IAsyncStateMachine
         {
             this.iStateMachineWrap ??= StateMachineWrap<TStateMachine>.Fetch(ref stateMachine);
             awaiter.OnCompleted(this.iStateMachineWrap.MoveNext);
@@ -55,7 +55,7 @@ namespace ET
         // 6. AwaitUnsafeOnCompleted
         [DebuggerHidden]
         [SecuritySafeCritical]
-        public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine
+        public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : IETTask, ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine
         {
             this.iStateMachineWrap ??= StateMachineWrap<TStateMachine>.Fetch(ref stateMachine);
             awaiter.UnsafeOnCompleted(this.iStateMachineWrap.MoveNext);

+ 80 - 6
Unity/Packages/cn.etetet.core/Runtime/ETTask/ETTask.cs

@@ -7,18 +7,59 @@ using System.Runtime.ExceptionServices;
 
 namespace ET
 {
+    internal static class IETTaskExtension
+    {
+        internal static void SetCancelToken(this IETTask task, ETCancellationToken cancellationToken)
+        {
+            while (true)
+            {
+                if (task == null)
+                {
+                    return;
+                }
+                if (task.TaskType == TaskType.TokenTask)
+                {
+                    (task as ETTask<ETCancellationToken>).SetResult(cancellationToken);
+                    break;
+                }
+
+                // cancellationToken传下去
+                task.TaskType = TaskType.WithToken;
+                object child = task.Object;
+                task.Object = cancellationToken;
+                task = child as IETTask;
+            }
+        }
+    }
+    
+    public enum TaskType: byte
+    {
+        Common,
+        WithToken,
+        TokenTask,
+    }
+    
+    public interface IETTask
+    {
+        public TaskType TaskType { get; set; }
+        public object Object { get; set; }
+    }
+    
     [AsyncMethodBuilder(typeof (ETAsyncTaskMethodBuilder))]
-    public class ETTask: ICriticalNotifyCompletion
+    public class ETTask: ICriticalNotifyCompletion, IETTask
     {
         [StaticField]
         public static Action<Exception> ExceptionHandler;
+
+        [StaticField]
+        private static ETTask completedTask;
         
         [StaticField]
-        public static ETTaskCompleted CompletedTask
+        public static ETTask CompletedTask
         {
             get
             {
-                return new ETTaskCompleted();
+                return completedTask ??= new ETTask() { state = AwaiterStatus.Succeeded };
             }
         }
 
@@ -30,6 +71,7 @@ namespace ET
         /// 假如开启了池,await之后不能再操作ETTask,否则可能操作到再次从池中分配出来的ETTask,产生灾难性的后果
         /// SetResult的时候请现将tcs置空,避免多次对同一个ETTask SetResult
         /// </summary>
+        [DebuggerHidden]
         public static ETTask Create(bool fromPool = false)
         {
             if (!fromPool)
@@ -43,6 +85,7 @@ namespace ET
             return task;
         }
 
+        [DebuggerHidden]
         private void Recycle()
         {
             if (!this.fromPool)
@@ -52,6 +95,8 @@ namespace ET
             
             this.state = AwaiterStatus.Pending;
             this.callback = null;
+            this.Object = null;
+            this.TaskType = TaskType.Common;
             // 太多了
             if (queue.Count > 1000)
             {
@@ -64,8 +109,10 @@ namespace ET
         private AwaiterStatus state;
         private object callback; // Action or ExceptionDispatchInfo
 
+        [DebuggerHidden]
         private ETTask()
         {
+            this.TaskType = TaskType.Common;
         }
         
         [DebuggerHidden]
@@ -77,6 +124,14 @@ namespace ET
         [DebuggerHidden]
         public void Coroutine()
         {
+            this.SetCancelToken(null);
+            InnerCoroutine().Coroutine();
+        }
+        
+        [DebuggerHidden]
+        public void Coroutine(ETCancellationToken cancellationToken)
+        {
+            this.SetCancelToken(cancellationToken);
             InnerCoroutine().Coroutine();
         }
 
@@ -163,10 +218,13 @@ namespace ET
             this.callback = ExceptionDispatchInfo.Capture(e);
             c?.Invoke();
         }
+
+        public TaskType TaskType { get; set; }
+        public object Object { get; set; }
     }
 
     [AsyncMethodBuilder(typeof (ETAsyncTaskMethodBuilder<>))]
-    public class ETTask<T>: ICriticalNotifyCompletion
+    public class ETTask<T>: ICriticalNotifyCompletion, IETTask
     {
         [StaticField]
         private static readonly ConcurrentQueue<ETTask<T>> queue = new();
@@ -176,6 +234,7 @@ namespace ET
         /// 假如开启了池,await之后不能再操作ETTask,否则可能操作到再次从池中分配出来的ETTask,产生灾难性的后果
         /// SetResult的时候请现将tcs置空,避免多次对同一个ETTask SetResult
         /// </summary>
+        [DebuggerHidden]
         public static ETTask<T> Create(bool fromPool = false)
         {
             if (!fromPool)
@@ -190,6 +249,7 @@ namespace ET
             return task;
         }
         
+        [DebuggerHidden]
         private void Recycle()
         {
             if (!this.fromPool)
@@ -199,6 +259,8 @@ namespace ET
             this.callback = null;
             this.value = default;
             this.state = AwaiterStatus.Pending;
+            this.Object = null;
+            this.TaskType = TaskType.Common;
             // 太多了
             if (queue.Count > 1000)
             {
@@ -212,8 +274,10 @@ namespace ET
         private T value;
         private object callback; // Action or ExceptionDispatchInfo
 
+        [DebuggerHidden]
         private ETTask()
         {
+            this.TaskType = TaskType.Common;
         }
 
         [DebuggerHidden]
@@ -225,6 +289,14 @@ namespace ET
         [DebuggerHidden]
         public void Coroutine()
         {
+            this.SetCancelToken(null);
+            InnerCoroutine().Coroutine();
+        }
+        
+        [DebuggerHidden]
+        public void Coroutine(ETCancellationToken cancellationToken)
+        {
+            this.SetCancelToken(cancellationToken);
             InnerCoroutine().Coroutine();
         }
 
@@ -253,8 +325,7 @@ namespace ET
                     throw new NotSupportedException("ETask does not allow call GetResult directly when task not completed. Please use 'await'.");
             }
         }
-
-
+        
         public bool IsCompleted
         {
             [DebuggerHidden]
@@ -313,5 +384,8 @@ namespace ET
             this.callback = ExceptionDispatchInfo.Capture(e);
             c?.Invoke();
         }
+
+        public TaskType TaskType { get; set; }
+        public object Object { get; set; }
     }
 }

+ 0 - 34
Unity/Packages/cn.etetet.core/Runtime/ETTask/ETTaskCompleted.cs

@@ -1,34 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-
-namespace ET
-{
-    [AsyncMethodBuilder(typeof (AsyncETTaskCompletedMethodBuilder))]
-    public struct ETTaskCompleted: ICriticalNotifyCompletion
-    {
-        [DebuggerHidden]
-        public ETTaskCompleted GetAwaiter()
-        {
-            return this;
-        }
-
-        [DebuggerHidden]
-        public bool IsCompleted => true;
-
-        [DebuggerHidden]
-        public void GetResult()
-        {
-        }
-
-        [DebuggerHidden]
-        public void OnCompleted(Action continuation)
-        {
-        }
-
-        [DebuggerHidden]
-        public void UnsafeOnCompleted(Action continuation)
-        {
-        }
-    }
-}

+ 0 - 11
Unity/Packages/cn.etetet.core/Runtime/ETTask/ETTaskCompleted.cs.meta

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

+ 7 - 0
Unity/Packages/cn.etetet.core/Runtime/ETTask/ETTaskHelper.cs

@@ -5,6 +5,13 @@ namespace ET
 {
     public static class ETTaskHelper
     {
+        public static async ETTask<ETCancellationToken> GetCancelToken()
+        {
+            ETTask<ETCancellationToken> tcs = ETTask<ETCancellationToken>.Create(true);
+            tcs.TaskType = TaskType.TokenTask;
+            return await tcs;
+        }
+        
         public static bool IsCancel(this ETCancellationToken self)
         {
             if (self == null)

+ 1 - 1
Unity/Packages/cn.etetet.core/Runtime/ETTask/IAwaiter.cs

@@ -4,7 +4,7 @@
     {
         /// <summary>The operation has not yet completed.</summary>
         Pending = 0,
-
+        
         /// <summary>The operation completed successfully.</summary>
         Succeeded = 1,
 

+ 2 - 1
Unity/Packages/cn.etetet.core/Scripts/Hotfix/Share/Message/SessionSystem.cs

@@ -43,7 +43,7 @@ namespace ET
             action.SetResult(response);
         }
         
-        public static async ETTask<IResponse> Call(this Session self, IRequest request, ETCancellationToken cancellationToken)
+        public static async ETTask<IResponse> Call(this Session self, IRequest request)
         {
             int rpcId = ++self.RpcId;
             RpcInfo rpcInfo = new(request.GetType());
@@ -66,6 +66,7 @@ namespace ET
             }
 
             IResponse ret;
+            ETCancellationToken cancellationToken = await ETTaskHelper.GetCancelToken();
             try
             {
                 cancellationToken?.Add(CancelAction);

+ 6 - 3
Unity/Packages/cn.etetet.core/Scripts/Hotfix/Share/ObjectWait/ObjectWaitSystem.cs

@@ -23,7 +23,7 @@ namespace ET
             }
         }
         
-        public static async ETTask<T> Wait<T>(this ObjectWait self, ETCancellationToken cancellationToken = null) where T : struct, IWaitType
+        public static async ETTask<T> Wait<T>(this ObjectWait self) where T : struct, IWaitType
         {
             ResultCallback<T> tcs = new ResultCallback<T>();
             Type type = typeof (T);
@@ -35,6 +35,7 @@ namespace ET
             }
 
             T ret;
+            ETCancellationToken cancellationToken = await ETTaskHelper.GetCancelToken();
             try
             {
                 cancellationToken?.Add(CancelAction);
@@ -47,12 +48,13 @@ namespace ET
             return ret;
         }
 
-        public static async ETTask<T> Wait<T>(this ObjectWait self, int timeout, ETCancellationToken cancellationToken = null) where T : struct, IWaitType
+        public static async ETTask<T> Wait<T>(this ObjectWait self, int timeout) where T : struct, IWaitType
         {
             ResultCallback<T> tcs = new ResultCallback<T>();
             async ETTask WaitTimeout()
             {
-                await self.Root().GetComponent<TimerComponent>().WaitAsync(timeout, cancellationToken);
+                await self.Root().GetComponent<TimerComponent>().WaitAsync(timeout);
+                ETCancellationToken cancellationToken = await ETTaskHelper.GetCancelToken();
                 if (cancellationToken.IsCancel())
                 {
                     return;
@@ -74,6 +76,7 @@ namespace ET
             }
             
             T ret;
+            ETCancellationToken cancellationToken = await ETTaskHelper.GetCancelToken();
             try
             {
                 cancellationToken?.Add(CancelAction);

+ 6 - 4
Unity/Packages/cn.etetet.core/Scripts/Hotfix/Share/Timer/TimerComponentSystem.cs

@@ -137,7 +137,7 @@ namespace ET
             return true;
         }
 
-        public static async ETTask WaitTillAsync(this TimerComponent self, long tillTime, ETCancellationToken cancellationToken = null)
+        public static async ETTask WaitTillAsync(this TimerComponent self, long tillTime)
         {
             long timeNow = self.GetNow();
             if (timeNow >= tillTime)
@@ -158,6 +158,7 @@ namespace ET
                 }
             }
 
+            ETCancellationToken cancellationToken = await ETTaskHelper.GetCancelToken();
             try
             {
                 cancellationToken?.Add(CancelAction);
@@ -169,12 +170,12 @@ namespace ET
             }
         }
 
-        public static async ETTask WaitFrameAsync(this TimerComponent self, ETCancellationToken cancellationToken = null)
+        public static async ETTask WaitFrameAsync(this TimerComponent self)
         {
-            await self.WaitAsync(1, cancellationToken);
+            await self.WaitAsync(1);
         }
 
-        public static async ETTask WaitAsync(this TimerComponent self, long time, ETCancellationToken cancellationToken = null)
+        public static async ETTask WaitAsync(this TimerComponent self, long time)
         {
             if (time == 0)
             {
@@ -196,6 +197,7 @@ namespace ET
                 }
             }
 
+            ETCancellationToken cancellationToken = await ETTaskHelper.GetCancelToken();
             try
             {
                 cancellationToken?.Add(CancelAction);

+ 7 - 0
Unity/Packages/cn.etetet.excel/Config/UnitConfigCategory.bytes.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 2c19832f797c4a54b9f1aa520b01da94
+TextScriptImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 1 - 0
Unity/Packages/cn.etetet.proto/DotNet~/Init.cs

@@ -12,6 +12,7 @@ namespace ET
             }
             catch (Exception e)
             {
+                Log.Console(e.ToString());
                 Console.WriteLine(e.ToString());
             }
             Console.WriteLine("proto2cs ok!");

+ 3 - 2
Unity/Packages/cn.etetet.statesync/Scripts/Hotfix/Client/Main/Move/MoveHelper.cs

@@ -7,7 +7,7 @@ namespace ET.Client
     public static partial class MoveHelper
     {
         // 可以多次调用,多次调用的话会取消上一次的协程
-        public static async ETTask<int> MoveToAsync(this Unit unit, float3 targetPos, ETCancellationToken cancellationToken = null)
+        public static async ETTask<int> MoveToAsync(this Unit unit, float3 targetPos)
         {
             C2M_PathfindingResult msg = C2M_PathfindingResult.Create();
             msg.Position = targetPos;
@@ -19,7 +19,8 @@ namespace ET.Client
             objectWait.Notify(new Wait_UnitStop() { Error = WaitTypeError.Cancel });
             
             // 一直等到unit发送stop
-            Wait_UnitStop waitUnitStop = await objectWait.Wait<Wait_UnitStop>(cancellationToken);
+            Wait_UnitStop waitUnitStop = await objectWait.Wait<Wait_UnitStop>();
+            ETCancellationToken cancellationToken = await ETTaskHelper.GetCancelToken();
             if (cancellationToken.IsCancel())
             {
                 return WaitTypeError.Cancel;