ActorComponent.cs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. using System;
  2. using System.Threading.Tasks;
  3. namespace Model
  4. {
  5. public struct ActorMessageInfo
  6. {
  7. public Session Session;
  8. public ActorRequest Message;
  9. }
  10. [ObjectEvent]
  11. public class ActorComponentEvent : ObjectEvent<ActorComponent>, IAwake, IAwake<IEntityActorHandler>
  12. {
  13. public void Awake()
  14. {
  15. this.Get().Awake();
  16. }
  17. public void Awake(IEntityActorHandler iEntityActorHandler)
  18. {
  19. this.Get().Awake(iEntityActorHandler);
  20. }
  21. }
  22. /// <summary>
  23. /// 挂上这个组件表示该Entity是一个Actor, 它会将Entity位置注册到Location Server, 接收的消息将会队列处理
  24. /// </summary>
  25. public class ActorComponent: Component
  26. {
  27. private IEntityActorHandler entityActorHandler;
  28. private long actorId;
  29. // 队列处理消息
  30. private readonly EQueue<ActorMessageInfo> queue = new EQueue<ActorMessageInfo>();
  31. private TaskCompletionSource<ActorMessageInfo> tcs;
  32. public void Awake()
  33. {
  34. this.entityActorHandler = new CommonEntityActorHandler();
  35. this.actorId = this.Entity.Id;
  36. Game.Scene.GetComponent<ActorManagerComponent>().Add(this.Entity);
  37. this.HandleAsync();
  38. }
  39. public void Awake(IEntityActorHandler iEntityActorHandler)
  40. {
  41. this.entityActorHandler = iEntityActorHandler;
  42. this.actorId = this.Entity.Id;
  43. Game.Scene.GetComponent<ActorManagerComponent>().Add(this.Entity);
  44. this.HandleAsync();
  45. }
  46. public async Task AddLocation()
  47. {
  48. await Game.Scene.GetComponent<LocationProxyComponent>().Add(this.actorId);
  49. }
  50. public async Task RemoveLocation()
  51. {
  52. await Game.Scene.GetComponent<LocationProxyComponent>().Remove(this.actorId);
  53. }
  54. public void Add(ActorMessageInfo info)
  55. {
  56. this.queue.Enqueue(info);
  57. if (this.tcs == null)
  58. {
  59. return;
  60. }
  61. var t = this.tcs;
  62. this.tcs = null;
  63. t.SetResult(this.queue.Dequeue());
  64. }
  65. private Task<ActorMessageInfo> GetAsync()
  66. {
  67. if (this.queue.Count > 0)
  68. {
  69. return Task.FromResult(this.queue.Dequeue());
  70. }
  71. this.tcs = new TaskCompletionSource<ActorMessageInfo>();
  72. return this.tcs.Task;
  73. }
  74. private async void HandleAsync()
  75. {
  76. while (true)
  77. {
  78. try
  79. {
  80. ActorMessageInfo info = await this.GetAsync();
  81. await this.entityActorHandler.Handle(info.Session, this.Entity, info.Message);
  82. }
  83. catch (Exception e)
  84. {
  85. Log.Error(e.ToString());
  86. }
  87. }
  88. }
  89. public override void Dispose()
  90. {
  91. try
  92. {
  93. if (this.Id == 0)
  94. {
  95. return;
  96. }
  97. base.Dispose();
  98. Game.Scene.GetComponent<ActorManagerComponent>().Remove(actorId);
  99. }
  100. catch (Exception)
  101. {
  102. Log.Error($"unregister actor fail: {this.actorId}");
  103. }
  104. }
  105. }
  106. }