123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- namespace ET
- {
- public static class WaitTypeError
- {
- public const int Success = 0;
- public const int Destroy = 1;
- public const int Cancel = 2;
- public const int Timeout = 3;
- }
-
- public interface IWaitType
- {
- int Error
- {
- get;
- set;
- }
- }
- [FriendOf(typeof(ObjectWait))]
- public static class ObjectWaitSystem
- {
- [ObjectSystem]
- public class ObjectWaitAwakeSystem: AwakeSystem<ObjectWait>
- {
- protected override void Awake(ObjectWait self)
- {
- self.tcss.Clear();
- }
- }
- [ObjectSystem]
- public class ObjectWaitDestroySystem: DestroySystem<ObjectWait>
- {
- protected override void Destroy(ObjectWait self)
- {
- foreach (object v in self.tcss.Values.ToArray())
- {
- ((IDestroyRun) v).SetResult();
- }
- }
- }
- private interface IDestroyRun
- {
- void SetResult();
- }
- private class ResultCallback<K>: IDestroyRun where K : struct, IWaitType
- {
- private ETTask<K> tcs;
- public ResultCallback()
- {
- this.tcs = ETTask<K>.Create(true);
- }
- public bool IsDisposed
- {
- get
- {
- return this.tcs == null;
- }
- }
- public ETTask<K> Task => this.tcs;
- public void SetResult(K k)
- {
- var t = tcs;
- this.tcs = null;
- t.SetResult(k);
- }
- public void SetResult()
- {
- var t = tcs;
- this.tcs = null;
- t.SetResult(new K() { Error = WaitTypeError.Destroy });
- }
- }
-
- public static async ETTask<T> Wait<T>(this ObjectWait self, ETCancellationToken cancellationToken = null) where T : struct, IWaitType
- {
- ResultCallback<T> tcs = new ResultCallback<T>();
- Type type = typeof (T);
- self.tcss.Add(type, tcs);
- void CancelAction()
- {
- self.Notify(new T() { Error = WaitTypeError.Cancel });
- }
- T ret;
- try
- {
- cancellationToken?.Add(CancelAction);
- ret = await tcs.Task;
- }
- finally
- {
- cancellationToken?.Remove(CancelAction);
- }
- return ret;
- }
- public static async ETTask<T> Wait<T>(this ObjectWait self, int timeout, ETCancellationToken cancellationToken = null) where T : struct, IWaitType
- {
- ResultCallback<T> tcs = new ResultCallback<T>();
- async ETTask WaitTimeout()
- {
- await TimerComponent.Instance.WaitAsync(timeout, cancellationToken);
- if (cancellationToken.IsCancel())
- {
- return;
- }
- if (tcs.IsDisposed)
- {
- return;
- }
- self.Notify(new T() { Error = WaitTypeError.Timeout });
- }
-
- WaitTimeout().Coroutine();
-
- self.tcss.Add(typeof (T), tcs);
-
- void CancelAction()
- {
- self.Notify(new T() { Error = WaitTypeError.Cancel });
- }
-
- T ret;
- try
- {
- cancellationToken?.Add(CancelAction);
- ret = await tcs.Task;
- }
- finally
- {
- cancellationToken?.Remove(CancelAction);
- }
- return ret;
- }
- public static void Notify<T>(this ObjectWait self, T obj) where T : struct, IWaitType
- {
- Type type = typeof (T);
- if (!self.tcss.TryGetValue(type, out object tcs))
- {
- return;
- }
- self.tcss.Remove(type);
- ((ResultCallback<T>) tcs).SetResult(obj);
- }
- }
- [ComponentOf]
- public class ObjectWait: Entity, IAwake, IDestroy
- {
- public Dictionary<Type, object> tcss = new Dictionary<Type, object>();
- }
- }
|