ActorComponentSystem.cs 2.7 KB

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