cfclient/F6/MsgHandler.cs
2024-05-22 08:51:14 +08:00

98 lines
2.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using Google.Protobuf;
using pbr = global::Google.Protobuf.Reflection;
namespace F6
{
internal delegate Google.Protobuf.IMessage CreateMsg();
internal delegate void HandlerMsg(Google.Protobuf.IMessage msg);
internal class HandlerRec
{
internal CreateMsg createMsg;
internal List<HandlerMsg> handlers = new List<HandlerMsg>();
}
class MsgHandler
{
public delegate void HandlerDelegate<in T>(T msg);
private Type cmMsgType;
private Type smMsgType;
private Dictionary<int, HandlerRec> handlerHash = new Dictionary<int, HandlerRec>();
public MsgHandler(Type cmMsgType, Type smMsgType)
{
this.cmMsgType = cmMsgType;
this.smMsgType = smMsgType;
}
public int GetCMMsgId(string msgName)
{
return this.GetPbMsgId(this.cmMsgType, "_" + msgName);
}
public int GetSMMsgId(string msgName)
{
return this.GetPbMsgId(this.smMsgType, "_" + msgName);
}
public int GetPbMsgId(Type enumType, string msgName)
{
foreach (var f in enumType.GetFields())
{
var tAttrs = f.GetCustomAttributes(typeof(pbr::OriginalNameAttribute), false);
if (tAttrs.Length > 0)
{
var tAttr = (pbr::OriginalNameAttribute)tAttrs[0];
if (tAttr.Name.Equals(msgName))
{
var val = Enum.Parse(enumType, f.Name);
return Convert.ToInt32(val);
}
}
}
return 0;
}
protected void RegisterHandler<T>(HandlerDelegate<T> handler) where T : IMessage<T> ,new()
{
int msgId = this.GetSMMsgId(typeof(T).Name);
HandlerRec handler1;
if (!this.handlerHash.TryGetValue(msgId, out handler1))
{
handler1 = new HandlerRec();
handler1.createMsg += () =>
{
return new T();
};
this.handlerHash.Add(msgId, handler1);
}
handler1.handlers.Add((Google.Protobuf.IMessage msg) =>
{
handler((T)msg);
});
}
virtual protected void DispatchMsg(int msgId, byte[] data)
{
HandlerRec handler;
if (this.handlerHash.TryGetValue(msgId, out handler))
{
var msg = handler.createMsg();
msg.Descriptor.Parser.ParseFrom(data);
foreach (var h in handler.handlers)
{
h(msg);
}
}
}
}
}