TimerComponent.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. using System.Collections.Generic;
  2. using System.Threading;
  3. using System.Threading.Tasks;
  4. namespace Base
  5. {
  6. public class Timer
  7. {
  8. public long Id { get; set; }
  9. public long Time { get; set; }
  10. public TaskCompletionSource<bool> tcs;
  11. }
  12. [ObjectEvent]
  13. public class TimerComponentEvent : ObjectEvent<TimerComponent>, IUpdate, IAwake<TimeComponent>
  14. {
  15. public void Update()
  16. {
  17. TimerComponent component = this.GetValue();
  18. component.Update();
  19. }
  20. public void Awake(TimeComponent p1)
  21. {
  22. this.GetValue().TimeComponent = p1;
  23. }
  24. }
  25. public static class TimerComponentExtension
  26. {
  27. public static void Update(this TimerComponent component)
  28. {
  29. long timeNow = component.TimeComponent.Now();
  30. foreach (long time in component.timeId.Keys)
  31. {
  32. if (time > timeNow)
  33. {
  34. break;
  35. }
  36. component.timeoutTimer.Enqueue(time);
  37. }
  38. while (component.timeoutTimer.Count > 0)
  39. {
  40. long key = component.timeoutTimer.Dequeue();
  41. long[] timeOutId = component.timeId.GetAll(key);
  42. foreach (long id in timeOutId)
  43. {
  44. Timer timer;
  45. if (!component.timers.TryGetValue(id, out timer))
  46. {
  47. continue;
  48. }
  49. component.Remove(id);
  50. timer.tcs.SetResult(true);
  51. }
  52. }
  53. }
  54. }
  55. public class TimerComponent: Component
  56. {
  57. public readonly Dictionary<long, Timer> timers = new Dictionary<long, Timer>();
  58. /// <summary>
  59. /// key: time, value: timer id
  60. /// </summary>
  61. public readonly MultiMap<long, long> timeId = new MultiMap<long, long>();
  62. public readonly Queue<long> timeoutTimer = new Queue<long>();
  63. public TimeComponent TimeComponent { get; set; }
  64. public void Remove(long id)
  65. {
  66. Timer timer;
  67. if (!this.timers.TryGetValue(id, out timer))
  68. {
  69. return;
  70. }
  71. this.timers.Remove(id);
  72. this.timeId.Remove(timer.Time, timer.Id);
  73. }
  74. public Task WaitTillAsync(long tillTime, CancellationToken cancellationToken)
  75. {
  76. TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
  77. Timer timer = new Timer { Id = IdGenerater.GenerateId(), Time = tillTime, tcs = tcs };
  78. this.timers[timer.Id] = timer;
  79. this.timeId.Add(timer.Time, timer.Id);
  80. cancellationToken.Register(() =>
  81. {
  82. this.Remove(timer.Id);
  83. });
  84. return tcs.Task;
  85. }
  86. public Task WaitTillAsync(long tillTime)
  87. {
  88. TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
  89. Timer timer = new Timer { Id = IdGenerater.GenerateId(), Time = tillTime, tcs = tcs };
  90. this.timers[timer.Id] = timer;
  91. this.timeId.Add(timer.Time, timer.Id);
  92. return tcs.Task;
  93. }
  94. public Task WaitAsync(long time, CancellationToken cancellationToken)
  95. {
  96. TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
  97. Timer timer = new Timer
  98. {
  99. Id = IdGenerater.GenerateId(),
  100. Time = TimeHelper.ClientNow() + time,
  101. tcs = tcs
  102. };
  103. this.timers[timer.Id] = timer;
  104. this.timeId.Add(timer.Time, timer.Id);
  105. cancellationToken.Register(() =>
  106. {
  107. this.Remove(timer.Id);
  108. });
  109. return tcs.Task;
  110. }
  111. public Task WaitAsync(long time)
  112. {
  113. TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
  114. Timer timer = new Timer
  115. {
  116. Id = IdGenerater.GenerateId(),
  117. Time = TimeHelper.ClientNow() + time,
  118. tcs = tcs
  119. };
  120. this.timers[timer.Id] = timer;
  121. this.timeId.Add(timer.Time, timer.Id);
  122. return tcs.Task;
  123. }
  124. }
  125. }