ActorComponent.cs 2.3 KB

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