/// <summary>
        /// 获得某个参数的注解
        /// </summary>
        /// <param name="item"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static string GetParamSummary(this FunItem item, string name)
        {
            if (item == null)
            {
                return(string.Empty);
            }

            var p = item.Params.FirstOrDefault(o => o.Name == name);

            if (p != null)
            {
                return(p.Value);
            }
            return(string.Empty);
        }
        /// <summary>
        /// 把vs生成的xml文件转换为必要的文档
        /// </summary>
        /// <param name="xmlFile"></param>
        /// <returns></returns>
        public static List <FunItem> LoadXmlDocument(string xmlFile)
        {
            List <FunItem> ret = new List <FunItem>();

            if (!File.Exists(xmlFile))
            {
                Logs.Error("not find xml file", xmlFile);
                return(ret);
            }

            var xmlData = File.ReadAllText(xmlFile);

            XmlDocument dom = new XmlDocument();

            dom.LoadXml(xmlData);

            foreach (XmlNode node in dom.SelectNodes("//member"))
            {
                FunItem item = new FunItem();

                item.Name = node.Attributes["name"].Value;
                var nav = node.CreateNavigator();
                item.Summary = nav.SelectSingleNode("summary").Value.Trim();

                foreach (XPathNavigator pn in nav.Select("param"))
                {
                    ParamItem pi = new ParamItem();
                    pi.Name  = pn.GetAttribute("name", "");
                    pi.Value = pn.Value.Trim();

                    item.Params.Add(pi);
                }

                ret.Add(item);
            }

            return(ret);
        }
        /// <summary>
        /// 添加一个方法
        /// </summary>
        /// <param name="att"></param>
        /// <param name="methodinfo"></param>
        void AddMethod(NetMethodAttribute att, MethodInfo methodinfo)
        {
            var param = methodinfo.GetParameters();
            if (param.Length < 1)
            {
                Logs.Error(string.Format("{0}.{1} 不支持 {2} 个参数", classType.Name, methodinfo.Name, param.Length.ToString()));
                return;
            }

            if (param[0].ParameterType != typeof(NetState))
            {
                Logs.Error("{0}.{1} 的第一个参数必须是 NetState 对象", classType.Name, methodinfo.Name);
                return;
            }

            if (att.MethodType == NetMethodType.PacketReader)
            {
                Logs.Error("客户端代理类不支持这种模式 {0}", att.MethodType.ToString());
                return;
            }

            if (att.MethodType == NetMethodType.ProtocolStruct)
            {
                #region ProtocolStruct

                Type parameterType = param[1].ParameterType;

                if (!parameterType.IsClass)
                {
                    Logs.Error("{0}.{1} 的第二个参数必须是class类型。", classType.Name, methodinfo.Name);
                    return;
                }

                if (parameterType.GetInterface(typeof(IPacketWriter).FullName) == null)
                {
                    //  自己实现一个对对象的协议写入类
                    AddWriteProxy(parameterType);

                    string methodName = methodinfo.Name;
                    StringBuilder methonNameCode = new StringBuilder();
                    StringBuilder streamWriterCode = new StringBuilder();
                    methonNameCode.AppendFormat("public void {0}({1} obj)",
                        methodName, parameterType.FullName);

                    streamWriterCode.AppendLine("{");
                    streamWriterCode.AppendFormat("var pw = PacketWriter.AcquireContent({0});", att.OpCode);
                    streamWriterCode.AppendLine();
                    streamWriterCode.AppendFormat(
                        @"            PacketProfile packetProfile = PacketProfile.GetOutgoingProfile( {0} );
            if ( packetProfile != null )
                packetProfile.RegConstruct();
                ", att.OpCode);

                    streamWriterCode.AppendFormat("{0}WriteProxy.Write(obj, pw);", parameterType.Name);

                    streamWriterCode.AppendLine("NetState.Send(pw);");
                    streamWriterCode.AppendLine(" if ( packetProfile != null ) packetProfile.Record(pw.Length);");
                    streamWriterCode.AppendLine("PacketWriter.ReleaseContent(pw);");

                    streamWriterCode.AppendLine("}");

                    methonNameCode.Remove(methonNameCode.Length - 1, 1);
                    methonNameCode.Append(")");

                    callCode.AppendLine(methonNameCode.ToString());
                    callCode.AppendLine(streamWriterCode.ToString());
                }
                else
                {
                    //  如果对象实现了 IPacketWriter 接口,则直接使用,否则则自己生成协议代码
                    string methodName = methodinfo.Name;
                    StringBuilder methonNameCode = new StringBuilder();
                    StringBuilder streamWriterCode = new StringBuilder();
                    methonNameCode.AppendFormat("public void {0}({1} obj)",
                        methodName, parameterType.FullName);

                    streamWriterCode.AppendLine("{");
                    streamWriterCode.AppendFormat("var pw = PacketWriter.AcquireContent({0});", att.OpCode);
                    streamWriterCode.AppendLine();
                    streamWriterCode.AppendFormat(
                        @"            PacketProfile packetProfile = PacketProfile.GetOutgoingProfile( {0} );
            if ( packetProfile != null )
                packetProfile.RegConstruct();
                ", att.OpCode);

                    streamWriterCode.AppendLine("obj.Write(pw);");

                    streamWriterCode.AppendLine("NetState.Send(pw);");
                    streamWriterCode.AppendLine(" if ( packetProfile != null ) packetProfile.Record(pw.Length);");
                    streamWriterCode.AppendLine("PacketWriter.ReleaseContent(pw);");
                    streamWriterCode.AppendLine("}");

                    methonNameCode.Remove(methonNameCode.Length - 1, 1);
                    methonNameCode.Append(")");

                    callCode.AppendLine(methonNameCode.ToString());
                    callCode.AppendLine(streamWriterCode.ToString());
                }

                #endregion
            }

            if (att.MethodType == NetMethodType.SimpleMethod)
            {
                #region SimpleMethod


                string methodName = Utils.GetFixCallProxyName(methodinfo.Name);

                StringBuilder methonNameCode = new StringBuilder();
                StringBuilder streamWriterCode = new StringBuilder();
                StringBuilder commentCode = new StringBuilder();

                Console.WriteLine(classType.FullName + "." + methodinfo.Name);
                var doc =
                    funDoc.FirstOrDefault(o => o.Name.IndexOf("M:" + classType.FullName + "." + methodinfo.Name) == 0);
                if (doc == null)
                    doc = new FunItem();


                commentCode.AppendFormat(@"        /// <summary>
        /// {0}
        /// </summary>
", doc.Summary);

                methonNameCode.AppendFormat("public void {0}(", methodName);

                streamWriterCode.AppendLine("{");
                streamWriterCode.AppendFormat("var pw = PacketWriter.AcquireContent({0});", att.OpCode);
                streamWriterCode.AppendLine();
                
                for (int i = 1; i < param.Length; i++)
                {
                    var p = param[i];
                    if (p.ParameterType == typeof(int))
                    {
                        commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name));
                        methonNameCode.AppendFormat("int {0},", p.Name);                        
                        streamWriterCode.AppendFormat("pw.Write({0});\r\n", p.Name);
                    }
                    else if (p.ParameterType == typeof(byte))
                    {
                        commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name));
                        methonNameCode.AppendFormat("byte {0},", p.Name);
                        streamWriterCode.AppendFormat("pw.Write({0});\r\n", p.Name);
                    }
                    else if (p.ParameterType == typeof(long))
                    {
                        commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name));
                        methonNameCode.AppendFormat("long {0},", p.Name);
                        streamWriterCode.AppendFormat("pw.Write({0});\r\n", p.Name);
                    }
                    else if (p.ParameterType == typeof(float))
                    {
                        commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name));
                        methonNameCode.AppendFormat("float {0},", p.Name);
                        streamWriterCode.AppendFormat("pw.Write({0});\r\n", p.Name);
                    }
                    else if (p.ParameterType == typeof(double))
                    {
                        commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name));
                        methonNameCode.AppendFormat("double {0},", p.Name);
                        streamWriterCode.AppendFormat("pw.Write({0});\r\n", p.Name);
                    }
                    else if (p.ParameterType == typeof(bool))
                    {
                        commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name));
                        methonNameCode.AppendFormat("bool {0},", p.Name);
                        streamWriterCode.AppendFormat("pw.Write({0});\r\n", p.Name);
                    }
                    else if (p.ParameterType == typeof(string))
                    {
                        commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name));
                        methonNameCode.AppendFormat("string {0},", p.Name);
                        streamWriterCode.AppendFormat("pw.WriteUTF8Null({0});\r\n", p.Name);
                    }
                    else if (p.ParameterType == typeof(DateTime))
                    {
                        commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name));
                        methonNameCode.AppendFormat("DateTime {0},", p.Name);
                        streamWriterCode.AppendFormat("pw.Write({0}.Ticks);\r\n", p.Name);
                    }
                    else if (p.ParameterType.IsEnum)
                    {
                        commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name));
                        methonNameCode.AppendFormat("{0} {1},", Utils.GetFixFullTypeName(p.ParameterType.FullName), p.Name);
                        streamWriterCode.AppendFormat("pw.Write((byte){0});\r\n", p.Name);
                    }
                    else if (p.ParameterType.IsLayoutSequential)
                    {
                        commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name));
                        methonNameCode.AppendFormat("{0} {1},", Utils.GetFixFullTypeName(p.ParameterType.FullName), p.Name);
                        streamWriterCode.AppendFormat("pw.WriteStruct({0});\r\n", p.Name);

                    }
                    else if (p.ParameterType.IsArray)
                    {
                        #region 数组的处理

                        var arrayType = p.ParameterType.GetElementType();

                        commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name));
                        methonNameCode.AppendFormat("{0} {1},", Utils.GetFixFullTypeName(p.ParameterType.FullName), p.Name);

                        //  先写入长度
                        streamWriterCode.AppendFormat("pw.Write((int){0}.Length);\r\n", p.Name);
                        streamWriterCode.AppendFormat("for(int i = 0;i < {0}.Length;i++){{\r\n", p.Name);

                        if (arrayType == typeof(int))
                        {
                            streamWriterCode.AppendFormat("pw.Write({0}[i]);\r\n", p.Name);
                        }
                        else if (arrayType == typeof(byte))
                        {
                            streamWriterCode.AppendFormat("pw.Write({0}[i]);\r\n", p.Name);
                        }
                        else if (arrayType == typeof(long))
                        {
                            streamWriterCode.AppendFormat("pw.Write({0}[i]);\r\n", p.Name);
                        }
                        else if (arrayType == typeof(float))
                        {
                            streamWriterCode.AppendFormat("pw.Write({0}[i]);\r\n", p.Name);
                        }
                        else if (arrayType == typeof(double))
                        {
                            streamWriterCode.AppendFormat("pw.Write({0}[i]);\r\n", p.Name);
                        }
                        else if (arrayType == typeof(bool))
                        {
                            streamWriterCode.AppendFormat("pw.Write({0}[i]);\r\n", p.Name);
                        }
                        else if (arrayType == typeof(string))
                        {
                            streamWriterCode.AppendFormat("pw.WriteUTF8Null({0}[i]);\r\n", p.Name);
                        }
                        else if (p.ParameterType == typeof(DateTime))
                        {
                            streamWriterCode.AppendFormat("pw.Write({0}.Ticks);\r\n", p.Name);
                        }
                        else if (arrayType.IsEnum)
                        {
                            streamWriterCode.AppendFormat("pw.Write((byte){0}[i]);\r\n", p.Name);
                        }
                        else if (arrayType.IsLayoutSequential)
                        {
                            streamWriterCode.AppendFormat("pw.WriteStruct({0}[i]);\r\n", p.Name);
                        }

                        streamWriterCode.AppendLine("}");

                        #endregion
                    }
                    else if (p.ParameterType.IsClass)
                    {
                        AddWriteProxy(p.ParameterType, doc.GetParamSummary(p.Name));

                        commentCode.AppendFormat("/// <param name=`{0}`>{1}</param>\r\n", p.Name, doc.GetParamSummary(p.Name));
                        methonNameCode.AppendFormat("{0} {1},", Utils.GetFixFullTypeName(p.ParameterType.FullName), p.Name);
                        streamWriterCode.AppendFormat("{0}WriteProxy.Write({1}, pw);\r\n", p.ParameterType.Name, p.Name);
                    }
                    else
                    {
                        Logs.Error(string.Format("{0}.{1} 存在不支持的参数 {2},类型未:{3}",
                            classType.Name, methodinfo.Name, p.Name, p.ParameterType.Name));
                    }

                }

                streamWriterCode.AppendLine("NetState.Send(pw);PacketWriter.ReleaseContent(pw);");
                streamWriterCode.AppendLine("}");

                if (param.Length > 1)
                    methonNameCode.Remove(methonNameCode.Length - 1, 1);

                methonNameCode.Append(")");

                callCode.AppendLine(commentCode.ToString());
                callCode.AppendLine(methonNameCode.ToString());
                callCode.AppendLine(streamWriterCode.ToString());

                #endregion
            }
        }
Beispiel #4
0
        /// <summary>
        /// 把vs生成的xml文件转换为必要的文档
        /// </summary>
        /// <param name="xmlFile"></param>
        /// <returns></returns>
        public static List<FunItem> LoadXmlDocument(string xmlFile)
        {
            List<FunItem> ret = new List<FunItem>();

            if (!File.Exists(xmlFile))
            {
                Logs.Error("not find xml file", xmlFile);
                return ret;
            }

            var xmlData = File.ReadAllText(xmlFile);

            XmlDocument dom = new XmlDocument();
            dom.LoadXml(xmlData);

            foreach (XmlNode node in dom.SelectNodes("//member"))
            {
                FunItem item = new FunItem();

                item.Name = node.Attributes["name"].Value;
                var nav = node.CreateNavigator();
                item.Summary = nav.SelectSingleNode("summary").Value.Trim();

                foreach (XPathNavigator pn in nav.Select("param"))
                {

                    ParamItem pi = new ParamItem();
                    pi.Name = pn.GetAttribute("name", "");
                    pi.Value = pn.Value.Trim();

                    item.Params.Add(pi);
                }

                ret.Add(item);
            }

            return ret;
        }