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 handlers = new List(); } public class MsgHandler { public delegate void HandlerDelegate(T msg); private Type cmMsgType; private Type smMsgType; private Dictionary handlerHash = new Dictionary(); public MsgHandler(Type cmMsgType, Type smMsgType) { this.cmMsgType = cmMsgType; this.smMsgType = smMsgType; } public int GetCMMsgId(Type type) { return this.GetPbMsgId(this.cmMsgType, "_" + type.Name); } public int GetSMMsgId(Type type) { return this.GetPbMsgId(this.smMsgType, "_" + type.Name); } 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; } public void RegisterHandler(HandlerDelegate handler) where T : IMessage ,new() { int msgId = this.GetSMMsgId(typeof(T)); 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); }); } public void DispatchMsg(int msgId, byte[] data, int offset, int length) { HandlerRec handler; if (this.handlerHash.TryGetValue(msgId, out handler)) { var msg = handler.createMsg(); msg = msg.Descriptor.Parser.ParseFrom(data, offset, length); foreach (var h in handler.handlers) { h(msg); } } } } }