ActorComponentSystem.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading.Tasks;
  4. using Model;
  5. namespace Hotfix
  6. {
  7. [ObjectEvent]
  8. public class ActorComponentSystem : ObjectSystem<ActorComponent>, IAwake, IAwake<IEntityActorHandler>, ILoad
  9. {
  10. public void Awake()
  11. {
  12. this.Get().Awake();
  13. }
  14. public void Awake(IEntityActorHandler iEntityActorHandler)
  15. {
  16. this.Get().Awake(iEntityActorHandler);
  17. }
  18. public void Load()
  19. {
  20. this.Get().Load();
  21. }
  22. }
  23. /// <summary>
  24. /// 挂上这个组件表示该Entity是一个Actor, 它会将Entity位置注册到Location Server, 接收的消息将会队列处理
  25. /// </summary>
  26. public static class ActorComponentEx
  27. {
  28. public static void Awake(this ActorComponent self)
  29. {
  30. self.entityActorHandler = new CommonEntityActorHandler();
  31. self.queue = new Queue<ActorMessageInfo>();
  32. self.actorId = self.Parent.Id;
  33. Game.Scene.GetComponent<ActorManagerComponent>().Add(self.Parent);
  34. self.HandleAsync();
  35. }
  36. public static void Awake(this ActorComponent self, IEntityActorHandler iEntityActorHandler)
  37. {
  38. self.entityActorHandler = iEntityActorHandler;
  39. self.queue = new Queue<ActorMessageInfo>();
  40. self.actorId = self.Parent.Id;
  41. Game.Scene.GetComponent<ActorManagerComponent>().Add(self.Parent);
  42. self.HandleAsync();
  43. }
  44. // 热更新要重新创建接口,以便接口也能实现热更新
  45. public static void Load(this ActorComponent self)
  46. {
  47. self.entityActorHandler = (IEntityActorHandler) HotfixHelper.Create(self.entityActorHandler);
  48. }
  49. public static async Task AddLocation(this ActorComponent self)
  50. {
  51. await Game.Scene.GetComponent<LocationProxyComponent>().Add(self.actorId);
  52. }
  53. public static async Task RemoveLocation(this ActorComponent self)
  54. {
  55. await Game.Scene.GetComponent<LocationProxyComponent>().Remove(self.actorId);
  56. }
  57. public static void Add(this ActorComponent self, ActorMessageInfo info)
  58. {
  59. self.queue.Enqueue(info);
  60. if (self.tcs == null)
  61. {
  62. return;
  63. }
  64. var t = self.tcs;
  65. self.tcs = null;
  66. t.SetResult(self.queue.Dequeue());
  67. }
  68. private static Task<ActorMessageInfo> GetAsync(this ActorComponent self)
  69. {
  70. if (self.queue.Count > 0)
  71. {
  72. return Task.FromResult(self.queue.Dequeue());
  73. }
  74. self.tcs = new TaskCompletionSource<ActorMessageInfo>();
  75. return self.tcs.Task;
  76. }
  77. private static async void HandleAsync(this ActorComponent self)
  78. {
  79. while (true)
  80. {
  81. if (self.Id == 0)
  82. {
  83. return;
  84. }
  85. try
  86. {
  87. ActorMessageInfo info = await self.GetAsync();
  88. // 返回null表示actor已经删除,协程要终止
  89. if (info == null)
  90. {
  91. return;
  92. }
  93. await self.entityActorHandler.Handle(info.Session, self.Parent, info.Message);
  94. }
  95. catch (Exception e)
  96. {
  97. Log.Error(e.ToString());
  98. }
  99. }
  100. }
  101. }
  102. }