TimerComponent.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. using System.Collections.Generic;
  2. using System.Threading;
  3. using System.Threading.Tasks;
  4. using Model;
  5. namespace Hotfix
  6. {
  7. public class Timer
  8. {
  9. public long Id { get; set; }
  10. public long Time { get; set; }
  11. public TaskCompletionSource<bool> tcs;
  12. }
  13. [EntityEvent(EntityEventId.TimerComponent)]
  14. public class TimerComponent: Component, IUpdate
  15. {
  16. private readonly Dictionary<long, Timer> timers = new Dictionary<long, Timer>();
  17. /// <summary>
  18. /// key: time, value: timer id
  19. /// </summary>
  20. private readonly MultiMap<long, long> timeId = new MultiMap<long, long>();
  21. private readonly Queue<long> timeoutTimer = new Queue<long>();
  22. public void Update()
  23. {
  24. long timeNow = TimeHelper.Now();
  25. foreach (long time in this.timeId.Keys)
  26. {
  27. if (time > timeNow)
  28. {
  29. break;
  30. }
  31. this.timeoutTimer.Enqueue(time);
  32. }
  33. while (this.timeoutTimer.Count > 0)
  34. {
  35. long key = this.timeoutTimer.Dequeue();
  36. long[] timeOutId = this.timeId.GetAll(key);
  37. foreach (long id in timeOutId)
  38. {
  39. Timer timer;
  40. if (!this.timers.TryGetValue(id, out timer))
  41. {
  42. continue;
  43. }
  44. this.Remove(id);
  45. timer.tcs.SetResult(true);
  46. }
  47. }
  48. }
  49. private void Remove(long id)
  50. {
  51. Timer timer;
  52. if (!this.timers.TryGetValue(id, out timer))
  53. {
  54. return;
  55. }
  56. this.timers.Remove(id);
  57. this.timeId.Remove(timer.Time, timer.Id);
  58. }
  59. public Task WaitTillAsync(long tillTime, CancellationToken cancellationToken)
  60. {
  61. TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
  62. Timer timer = new Timer { Id = IdGenerater.GenerateId(), Time = tillTime, tcs = tcs };
  63. this.timers[timer.Id] = timer;
  64. this.timeId.Add(timer.Time, timer.Id);
  65. cancellationToken.Register(() => { this.Remove(timer.Id); });
  66. return tcs.Task;
  67. }
  68. public Task WaitTillAsync(long tillTime)
  69. {
  70. TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
  71. Timer timer = new Timer { Id = IdGenerater.GenerateId(), Time = tillTime, tcs = tcs };
  72. this.timers[timer.Id] = timer;
  73. this.timeId.Add(timer.Time, timer.Id);
  74. return tcs.Task;
  75. }
  76. public Task WaitAsync(long time, CancellationToken cancellationToken)
  77. {
  78. TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
  79. Timer timer = new Timer { Id = IdGenerater.GenerateId(), Time = TimeHelper.Now() + time, tcs = tcs };
  80. this.timers[timer.Id] = timer;
  81. this.timeId.Add(timer.Time, timer.Id);
  82. cancellationToken.Register(() => { this.Remove(timer.Id); });
  83. return tcs.Task;
  84. }
  85. public Task WaitAsync(long time)
  86. {
  87. TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
  88. Timer timer = new Timer { Id = IdGenerater.GenerateId(), Time = TimeHelper.Now() + time, tcs = tcs };
  89. this.timers[timer.Id] = timer;
  90. this.timeId.Add(timer.Time, timer.Id);
  91. return tcs.Task;
  92. }
  93. }
  94. }