MailBoxComponentSystem.cs 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using System;
  2. using ETModel;
  3. namespace ETHotfix
  4. {
  5. [ObjectSystem]
  6. public class MailBoxComponentAwakeSystem : AwakeSystem<MailBoxComponent>
  7. {
  8. public override void Awake(MailBoxComponent self)
  9. {
  10. self.MailboxType = MailboxType.MessageDispatcher;
  11. self.Queue.Clear();
  12. }
  13. }
  14. [ObjectSystem]
  15. public class MailBoxComponentAwake1System : AwakeSystem<MailBoxComponent, string>
  16. {
  17. public override void Awake(MailBoxComponent self, string mailboxType)
  18. {
  19. self.MailboxType = mailboxType;
  20. self.Queue.Clear();
  21. }
  22. }
  23. [ObjectSystem]
  24. public class MailBoxComponentStartSystem : StartSystem<MailBoxComponent>
  25. {
  26. public override void Start(MailBoxComponent self)
  27. {
  28. self.HandleAsync().NoAwait();
  29. }
  30. }
  31. /// <summary>
  32. /// 挂上这个组件表示该Entity是一个Actor, 接收的消息将会队列处理
  33. /// </summary>
  34. public static class MailBoxComponentHelper
  35. {
  36. public static async ETTask AddLocation(this MailBoxComponent self)
  37. {
  38. await Game.Scene.GetComponent<LocationProxyComponent>().Add(self.Entity.Id, self.Entity.InstanceId);
  39. }
  40. public static async ETTask RemoveLocation(this MailBoxComponent self)
  41. {
  42. await Game.Scene.GetComponent<LocationProxyComponent>().Remove(self.Entity.Id);
  43. }
  44. public static void Add(this MailBoxComponent self, ActorMessageInfo info)
  45. {
  46. self.Queue.Enqueue(info);
  47. if (self.Tcs == null)
  48. {
  49. return;
  50. }
  51. var t = self.Tcs;
  52. self.Tcs = null;
  53. t.SetResult(self.Queue.Dequeue());
  54. }
  55. private static ETTask<ActorMessageInfo> GetAsync(this MailBoxComponent self)
  56. {
  57. if (self.Queue.Count > 0)
  58. {
  59. return ETTask.FromResult(self.Queue.Dequeue());
  60. }
  61. self.Tcs = new ETTaskCompletionSource<ActorMessageInfo>();
  62. return self.Tcs.Task;
  63. }
  64. public static async ETVoid HandleAsync(this MailBoxComponent self)
  65. {
  66. MailboxDispatcherComponent mailboxDispatcherComponent = Game.Scene.GetComponent<MailboxDispatcherComponent>();
  67. long instanceId = self.InstanceId;
  68. while (true)
  69. {
  70. if (self.InstanceId != instanceId)
  71. {
  72. return;
  73. }
  74. try
  75. {
  76. ActorMessageInfo info = await self.GetAsync();
  77. // 返回null表示actor已经删除,协程要终止
  78. if (info.Message == null)
  79. {
  80. return;
  81. }
  82. // 根据这个mailbox类型分发给相应的处理
  83. await mailboxDispatcherComponent.Handle(self, info);
  84. }
  85. catch (Exception e)
  86. {
  87. Log.Error(e);
  88. }
  89. }
  90. }
  91. }
  92. }