using System; using System.Collections.Generic; using System.Threading.Tasks; namespace Model { public struct ActorMessageInfo { public Session Session; public IActorMessage Message; } [ObjectEvent] public class ActorComponentEvent : ObjectEvent, IAwake { public void Awake(IEntityActorHandler iEntityActorHandler) { this.Get().Awake(iEntityActorHandler); } } /// /// 挂上这个组件表示该Entity是一个Actor, 它会将Entity位置注册到Location Server, 接收的消息将会队列处理 /// public class ActorComponent: Component { private IEntityActorHandler entityActorHandler; private long actorId; // 队列处理消息 private readonly Queue queue = new Queue(); private TaskCompletionSource tcs; public async void Awake(IEntityActorHandler iEntityActorHandler) { try { this.entityActorHandler = iEntityActorHandler; this.actorId = this.Owner.Id; Game.Scene.GetComponent().Add(this.Owner); await Game.Scene.GetComponent().Add(this.actorId); } catch (Exception) { Log.Error($"register actor fail: {this.actorId}"); } this.HandleAsync(); } public void Add(ActorMessageInfo info) { this.queue.Enqueue(info); if (this.tcs == null) { return; } this.tcs?.SetResult(this.queue.Dequeue()); this.tcs = null; } private Task GetAsync() { if (this.queue.Count > 0) { return Task.FromResult(this.queue.Dequeue()); } this.tcs = new TaskCompletionSource(); return this.tcs.Task; } private async void HandleAsync() { while (true) { ActorMessageInfo info = await this.GetAsync(); await this.entityActorHandler.Handle(info.Session, this.Owner, info.Message); } } public override async void Dispose() { try { if (this.Id == 0) { return; } base.Dispose(); Game.Scene.GetComponent().Remove(actorId); await Game.Scene.GetComponent().Remove(this.actorId); } catch (Exception) { Log.Error($"unregister actor fail: {this.actorId}"); } } } }