using System;
using System.Collections.Generic;
using System.Reflection;
using Base;
namespace Model
{
///
/// 消息分发组件
///
[ComponentEvent(typeof(MessageDispatherComponent))]
public class MessageDispatherComponent: Component
{
private AppType AppType;
private Dictionary> handlers;
private Dictionary messageOpcode { get; set; }
private void Awake(AppType appType)
{
this.AppType = appType;
this.Load();
}
private void Load()
{
this.handlers = new Dictionary>();
this.messageOpcode = new Dictionary();
Assembly[] assemblies = Game.ComponentEventManager.GetAssemblies();
foreach (Assembly assembly in assemblies)
{
Type[] types = assembly.GetTypes();
foreach (Type type in types)
{
object[] attrs = type.GetCustomAttributes(typeof(MessageAttribute), false);
if (attrs.Length == 0)
{
continue;
}
MessageAttribute messageAttribute = (MessageAttribute)attrs[0];
this.messageOpcode[type] = messageAttribute;
}
}
foreach (Assembly assembly in assemblies)
{
Type[] types = assembly.GetTypes();
foreach (Type type in types)
{
object[] attrs = type.GetCustomAttributes(typeof(MessageHandlerAttribute), false);
if (attrs.Length == 0)
{
continue;
}
MessageHandlerAttribute messageHandlerAttribute = (MessageHandlerAttribute)attrs[0];
if (!messageHandlerAttribute.Type.Is(this.AppType))
{
continue;
}
object obj = Activator.CreateInstance(type);
IMHandler imHandler = obj as IMHandler;
if (imHandler == null)
{
throw new Exception($"message handler not inherit AMEvent or AMRpcEvent abstract class: {obj.GetType().FullName}");
}
Type messageType = imHandler.GetMessageType();
ushort opcode = this.GetOpcode(messageType);
List list;
if (!this.handlers.TryGetValue(opcode, out list))
{
list = new List();
this.handlers.Add(opcode, list);
}
list.Add(imHandler);
}
}
}
public ushort GetOpcode(Type type)
{
MessageAttribute messageAttribute;
if (!this.messageOpcode.TryGetValue(type, out messageAttribute))
{
throw new Exception($"查找Opcode失败: {type.Name}");
}
return messageAttribute.Opcode;
}
public void Handle(Session session, MessageInfo messageInfo)
{
List actions;
if (!this.handlers.TryGetValue(messageInfo.Opcode, out actions))
{
Log.Error($"消息 {messageInfo.Opcode} 没有处理");
return;
}
foreach (IMHandler ev in actions)
{
try
{
ev.Handle(session, messageInfo);
}
catch (Exception e)
{
Log.Error(e.ToString());
}
}
}
public override void Dispose()
{
if (this.Id == 0)
{
return;
}
base.Dispose();
}
}
}