using System;
using System.Collections.Generic;
namespace ET.Server
{
///
/// Actor消息分发组件
///
[FriendOf(typeof(ActorMessageDispatcherComponent))]
public static class ActorMessageDispatcherComponentHelper
{
[ObjectSystem]
public class ActorMessageDispatcherComponentAwakeSystem: AwakeSystem
{
protected override void Awake(ActorMessageDispatcherComponent self)
{
ActorMessageDispatcherComponent.Instance = self;
self.Awake();
}
}
[ObjectSystem]
public class ActorMessageDispatcherComponentLoadSystem: LoadSystem
{
protected override void Load(ActorMessageDispatcherComponent self)
{
self.Load();
}
}
[ObjectSystem]
public class ActorMessageDispatcherComponentDestroySystem: DestroySystem
{
protected override void Destroy(ActorMessageDispatcherComponent self)
{
self.ActorMessageHandlers.Clear();
ActorMessageDispatcherComponent.Instance = null;
}
}
public static void Awake(this ActorMessageDispatcherComponent self)
{
self.Load();
}
public static void Load(this ActorMessageDispatcherComponent self)
{
self.ActorMessageHandlers.Clear();
var types = EventSystem.Instance.GetTypes(typeof (ActorMessageHandlerAttribute));
foreach (Type type in types)
{
object obj = Activator.CreateInstance(type);
IMActorHandler imHandler = obj as IMActorHandler;
if (imHandler == null)
{
throw new Exception($"message handler not inherit IMActorHandler abstract class: {obj.GetType().FullName}");
}
object[] attrs = type.GetCustomAttributes(typeof(ActorMessageHandlerAttribute), false);
foreach (object attr in attrs)
{
ActorMessageHandlerAttribute actorMessageHandlerAttribute = attr as ActorMessageHandlerAttribute;
Type messageType = imHandler.GetRequestType();
Type handleResponseType = imHandler.GetResponseType();
if (handleResponseType != null)
{
Type responseType = OpcodeTypeComponent.Instance.GetResponseType(messageType);
if (handleResponseType != responseType)
{
throw new Exception($"message handler response type error: {messageType.FullName}");
}
}
ActorMessageDispatcherInfo actorMessageDispatcherInfo = new ActorMessageDispatcherInfo(actorMessageHandlerAttribute.SceneType, imHandler);
self.RegisterHandler(messageType, actorMessageDispatcherInfo);
}
}
}
private static void RegisterHandler(this ActorMessageDispatcherComponent self, Type type, ActorMessageDispatcherInfo handler)
{
if (!self.ActorMessageHandlers.ContainsKey(type))
{
self.ActorMessageHandlers.Add(type, new List());
}
self.ActorMessageHandlers[type].Add(handler);
}
///
/// 分发actor消息
///
public static async ETTask Handle(
this ActorMessageDispatcherComponent self, Entity entity, object message, Action reply)
{
List list;
if (!self.ActorMessageHandlers.TryGetValue(message.GetType(), out list))
{
throw new Exception($"not found message handler: {message}");
}
SceneType sceneType = entity.DomainScene().SceneType;
foreach (ActorMessageDispatcherInfo actorMessageDispatcherInfo in list)
{
if (actorMessageDispatcherInfo.SceneType != sceneType)
{
continue;
}
await actorMessageDispatcherInfo.IMActorHandler.Handle(entity, message, reply);
}
}
}
}