协议(消息)生成

news2025/5/10 2:12:16

目录

协议(消息)生成主要做什么?

知识点二 制作功能前的准备工作

​编辑​编辑 制作消息生成功能

实现效果

​总结

上一篇中配置的XML文件可见:

https://mpbeta.csdn.net/mp_blog/creation/editor/147647176

协议(消息)生成主要做什么?

        //协议生成 主要是使用配置文件中读取出来的信息
        //动态的生成对应语言的代码文件
        //每次添加消息或者数据结构类时,我们不需要再手写代码了
        //我们不仅可以生成C#脚本文件,还可以根据需求生成别的语言的文件
        #endregion

知识点二 制作功能前的准备工作

        //协议生成是不会在发布后使用的功能,主要是在开发时使用
        //所以我们在Unity当中可以把它作为一个编辑器功能来做
        //因此我们可以专门新建一个Editor文件夹 (专门放编辑器相关内容,不会发布)
        //在其中放置配置文件、自动生成相关脚本文件

Unity编辑器功能代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.Xml;

public class ProtocolTool
{
    private static string PROTO_PATH = Application.dataPath + "/Editor/protocolTool/protocolInfo.xml";
    private static GeneratreCSharp generatreCSharp = new GeneratreCSharp();
    [MenuItem("ProtocolTool/生成C#脚本")]
    private static void GenerateCSharp()
    {
        //1.读取xml相关信息
        //XmlNodeList list = GetNodes("enum");
        //2.根据这些信息,去拼接字符串,生成对应的脚本
        generatreCSharp.GeneratreEnum(GetNodes("enum"));
        //刷新编辑器页面 让我们可以看到生成的内容 不需要手动刷新了
        //生成数据结构类
        generatreCSharp.GeneratreData(GetNodes("data"));
        //生成消息类
        generatreCSharp.GeneratreMsg(GetNodes("message"));
        AssetDatabase.Refresh();
    }
    [MenuItem("ProtocolTool/生成C++脚本")]
    private static void GenerateCpp()
    {
        Debug.Log("生成C++脚本");
    }
    [MenuItem("ProtocolTool/生成Java脚本")]
    private static void GenerateJava()
    {
        Debug.Log("生成Java脚本");
    }

    private static XmlNodeList GetNodes(string nodeName)
    {
        XmlDocument xml = new XmlDocument();
        xml.Load(PROTO_PATH);
        XmlNode root= xml.SelectSingleNode("messages");
        return root.SelectNodes(nodeName);
    }
}


 制作消息生成功能

根据配置好的XML文件来制作消息生成工具,分别实现生成枚举类型,数据结构类型(其中包括GetBytesNum,Writing,Reading函数),消息类型脚本

using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using UnityEngine;

public class GeneratreCSharp 
{
    //协议保存路径
    private string SAVE_PATH = Application.dataPath + "/Scripts/Protocol/";
    //生成枚举脚本的逻辑
    public void GeneratreEnum(XmlNodeList nodes)
    {
       
        string namespaceStr = "";
        string enumNameStr = "";
        string fieldStr = "";
        foreach (XmlNode enumNodes in nodes)
        {
            //获取命名空间配置信息
            namespaceStr = enumNodes.Attributes["namespace"].Value;
            //获取枚举名配置信息
            enumNameStr = enumNodes.Attributes["name"].Value;
            //获取所有字段节点 然后进行字符串拼接
            XmlNodeList enumFields = enumNodes.SelectNodes("field");
            //一个新的枚举 需要清空一次上一次拼接的字段字符串
            fieldStr = "";
            foreach (XmlNode  enumField in enumFields)
            {
                fieldStr += "\t\t" + enumField.Attributes["name"].Value;
                if (enumField.InnerText != "")
                    fieldStr +="="+ enumField.InnerText;
                fieldStr += ",\r\n";
            }
            //对所有可变的内容进行拼接
            string enumStr = $"namespace {namespaceStr}\r\n" +
                               "{\r\n" +
                               $"\tpublic enum {enumNameStr}\r\n" +
                               "\t{\r\n" +
                               $"{fieldStr}" +
                               "\t}\r\n" +
                               "}";
            //保存文件的路径
            string path = SAVE_PATH + namespaceStr + "/Enum/";
            //如果不存在这个文件夹 则创建
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
            //字符串保存 存储为枚举脚本文件
            File.WriteAllText(path + enumNameStr + ".cs", enumStr);
        }
        Debug.Log("枚举生成结束");
    }
    //生成数据结构类的逻辑
    public void GeneratreData(XmlNodeList nodes)
    {
        string namespaceStr = "";
        string classNameStr = "";
        string fieldStr = "";
        string GetBytesNumStr = "";
        string WritingStr = "";
        string ReadingStr = "";
        foreach (XmlNode dataNode in nodes)
        {
            //命名空间
            namespaceStr = dataNode.Attributes["namespace"].Value;
            //类名
            classNameStr = dataNode.Attributes["name"].Value;
            //读取所有字段节点
            XmlNodeList fields = dataNode.SelectNodes("field");
            //通过这个方法进行成员变量声明的拼接 返回拼接结果
            fieldStr = GetFieldStr(fields);
            //通过这个方法对GetBytesNum函数中字符串内容进行拼接 返回结果
            GetBytesNumStr = GetGetBytesNumStr(fields);
            //通过这个方法对Writing函数中字符串内容进行拼接 返回结果
            WritingStr = GetWritingStr(fields);
            //通过这个方法对Reading函数中字符串内容进行拼接 返回结果
            ReadingStr = GetReadingStr(fields);
            string dataStr = "using System;\r\n"+
                             "using System.Collections.Generic;\r\n" +
                             "using System.Text;\r\n"+
            $"namespace {namespaceStr}\r\n" +
                                "{\r\n" +
                                $"\tpublic class {classNameStr} : BaseData\r\n" +
                                "\t{\r\n" +
                                      $"{fieldStr}" +
                                      "\t\tpublic override int GetBytesNum()\r\n" +
                                      "\t\t{\r\n" +
                                      "\t\t\tint num=0;\r\n" +
                                      $"{GetBytesNumStr}" +
                                      "\t\t\treturn num;\r\n"+
                                      "\t\t}\r\n"+
                                      "\t\tpublic override byte[] Writing()\r\n"+
                                      "\t\t{\r\n"+
                                      "\t\t\tint index =0;\r\n"+
                                      "\t\t\tbyte [] bytes =new byte[GetBytesNum()];\r\n"+
                                      $"{WritingStr}"+
                                      "\t\t\treturn bytes;\r\n"+
                                      "\t\t}\r\n"+
                                       "\t\tpublic override int Reading(byte[] bytes, int beginIndex = 0)\r\n" +
                                      "\t\t{\r\n" +
                                      "\t\t\tint index =beginIndex ;\r\n" +
                                      $"{ReadingStr}" +
                                      "\t\t\treturn index - beginIndex;\r\n" +
                                      "\t\t}\r\n" +
                                      "\t}\r\n" +
                                      "}";
            //保存文件的路径
            string path = SAVE_PATH + namespaceStr + "/Data/";
            //如果不存在这个文件夹 则创建
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
            //字符串保存 存储为枚举脚本文件
            File.WriteAllText(path + classNameStr + ".cs", dataStr);
        }
        Debug.Log("数据结构类生成结束");
    }
    private string GetFieldStr(XmlNodeList fields)
    {
        string fieldStr = "";
        foreach (XmlNode  field in fields)
        {
            //变量类型
            string type = field.Attributes["type"].Value;
            //变量名
            string fieldName = field.Attributes["name"].Value;
            if(type=="list")
            {
                string T = field.Attributes["T"].Value;
                fieldStr += "\t\tpublic List<" + T + ">";
            }
            else if(type =="array")
            {
                string data = field.Attributes["data"].Value;
                fieldStr += "\t\tpublic " + data + "[]";
            }
            else if(type=="dic")
            {
                string Tkey = field.Attributes["Tkey"].Value;
                string Tvalue = field.Attributes["Tvalue"].Value;
                fieldStr += "\t\tpublic Dictionary<" + Tkey + "," + Tvalue + ">";
            }
            else if(type=="enum")
            {
                string data = field.Attributes["data"].Value;
                fieldStr += "\tpublic " + data + " ";
            }
            else
            {
                fieldStr += "\t\tpublic " + type + " ";
            }
            fieldStr += fieldName + ";\r\n";
        }
        return fieldStr;
    }
    private string GetGetBytesNumStr(XmlNodeList fields)
    {
        string bytesNumStr = "";
        string type = "";
        string name = "";
        foreach (XmlNode field in fields)
        {
            type = field.Attributes["type"].Value;
            name = field.Attributes["name"].Value;
            if (type == "list")
            {
                string T = field.Attributes["T"].Value;
                bytesNumStr += "\t\t\tnum +=2;\r\n";//+2是为了节约字节数 用一个short去存储信息
                bytesNumStr += "\t\t\tfor(int i = 0;i< " + name + ".Count;i++)\r\n";
                //这里使用name+"[i]"的目的是获取list当中的元素传入使用
                bytesNumStr += "\t\t\t\tnum +=" + GetValueBytesNum(T, name + "[i]") + ";\r\n";
            }
            else if (type == "array")
            {
                string data = field.Attributes["data"].Value;
                bytesNumStr += "\t\t\tnum +=2;\r\n";//+2是为了节约字节数 用一个short去存储信息
                bytesNumStr += "\t\t\tfor(int i = 0;i<" + name + ".Length;i++)\r\n";
                //这里使用name+"[i]"的目的是获取list当中的元素传入使用
                bytesNumStr += "\t\t\t\tnum +=" + GetValueBytesNum(data, name + "[i]") + ";\r\n";
            }
            else if (type == "dic")
            {
                string Tkey = field.Attributes["Tkey"].Value;
                string Tvalude = field.Attributes["Tvalue"].Value;
                bytesNumStr += "\t\t\tnum +=2;\r\n";//+2是为了节约字节数 用一个short去存储信息
                bytesNumStr += "\t\t\tforeach(" + Tkey + " key in " + name + ".Keys)\r\n";
                bytesNumStr += "\t\t\t{\r\n";
                bytesNumStr += "\t\t\t\tnum +=" + GetValueBytesNum(Tkey, "key") + ";\r\n";
                bytesNumStr += "\t\t\t\tnum +=" + GetValueBytesNum(Tvalude, name + "[key]") + ";\r\n";
                bytesNumStr += "\t\t\t}\r\n";
            }
            else
                bytesNumStr += "\t\t\tnum +=" + GetValueBytesNum(type, name)+";\r\n";
        }
        return bytesNumStr;
    }
    private string  GetValueBytesNum(string type,string name)
    {
        switch (type)
        {
            case "int":
            case "float":
            case "enum":
                return "4";
            case "long":
                return "8";
            case "byte":
            case "bool":
                return "1";
            case "short":
                return "2";
            case "string":
                return "4+Encoding.UTF8.GetByteCount(" + name + ")";
            default:
                return name + ".GetBytesNum()";
        }
    }
    private string GetWritingStr(XmlNodeList fields)
    {
        string writingStr = "";
        string type = "";
        string name = "";
        foreach (XmlNode  field in fields)
        {
            type = field.Attributes["type"].Value;
            name = field.Attributes["name"].Value;
            if(type=="list")
            {
                string T = field.Attributes["T"].Value;
                writingStr += "\t\t\tWriteShort(bytes, (short)" + name + ".Count, ref index);\r\n";
                writingStr += "\t\t\tfor (int i=0; i < " + name + ".Count;++i)\r\n";
                writingStr += "\t\t\t\t" + GetWritingValueStr(T, name + "[i]") + "\r\n";
            }
            else if(type=="array")
            {
                string data = field.Attributes["data"].Value;
                writingStr += "\t\t\tWriteShort(bytes, (short)" + name + ".Length, ref index);\r\n";
                writingStr += "\t\t\tfor (int i=0; i < " + name + ".Length;++i)\r\n";
                writingStr += "\t\t\t\t" + GetWritingValueStr(data, name + "[i]") + "\r\n";
            }
            else if(type=="dic")
            {
                string Tkey = field.Attributes["Tkey"].Value;
                string Tvalue = field.Attributes["Tvalue"].Value;
                writingStr += "\t\t\tWriteShort(bytes, (short)" + name + ".Count, ref index);\r\n";
                writingStr += "\t\t\tforeach(" + Tkey + " key in " + name + ".Keys)\r\n";
                writingStr += "\t\t\t{\r\n";
                writingStr += "\t\t\t\t" + GetWritingValueStr(Tkey, "key") + "\r\n";
                writingStr += "\t\t\t\t" + GetWritingValueStr(Tvalue, name + "[key]") + "\r\n";
                writingStr += "\t\t\t}\r\n";
            }
            else
            {
                writingStr += "\t\t\t" + GetWritingValueStr(type, name) + "\r\n";
            }
        
        }
        return writingStr;
    }
    private string GetWritingValueStr(string type,string name)
    {
        switch (type)
        {
            case "byte":
                return "WriteByte(bytes ," + name + ", ref index);";
            case "int":
                return "WriteInt(bytes ," + name + ", ref index);";
            case "bool":
                return "WriteBool(bytes ," + name + ", ref index);";
            case "short":
                return "WriteShort(bytes ," + name + ", ref index);";
            case "long":
                return "WriteLong(bytes ," + name + ", ref index);";
            case "float":
                return "WriteFloat(bytes ," + name + ", ref index);";
            case "string":
                return "WriteString(bytes ," + name + ", ref index);";
            case "enum":
                return "WriteInt(bytes ,Convert.ToInt32(" + name + "), ref index);";
            default:
                return "WriteData(bytes ," + name + ", ref index);";
        }
    }
    private string GetReadingStr(XmlNodeList  fields)
    {
        string readingStr = "";
        string type = "";
        string name = "";
        foreach (XmlNode field in fields)
        {
            type = field.Attributes["type"].Value;
            name = field.Attributes["name"].Value;
            if (type == "list")
            {
                string T = field.Attributes["T"].Value;
                readingStr += "\t\t\t" + name + " =new List<" + T + ">();\r\n";
                readingStr += "\t\t\tshort " + name + "Count =ReadShort(bytes, ref index);\r\n";
                readingStr += "\t\t\tfor (int i = 0; i < " + name + "Count; ++i)\r\n";
                readingStr += "\t\t\t\t" + name + ".Add(" + GetReadingValueStr(T) + ");\r\n";
            }
            else if (type == "array")
            {
                string data = field.Attributes["data"].Value;
                readingStr += "\t\t\tshort " + name + "Length =ReadShort(bytes, ref index);\r\n";
                readingStr += "\t\t\t" + name + " = new " + data + "[" + name + "Length];\r\n";
                readingStr += "\t\t\tfor (int i = 0; i < " + name + "Length; ++i)\r\n";
                readingStr += "\t\t\t\t" + name + "[i]" +" = "+ GetReadingValueStr(data) + ";\r\n";
            }
            else if (type == "dic")
            {
                string Tkey = field.Attributes["Tkey"].Value;
                string Tvalue = field.Attributes["Tvalue"].Value;
                readingStr += "\t\t\t" + name + " = new  Dictionary<" + Tkey + ", " + Tvalue + ">();\r\n";
                readingStr += "\t\t\tshort " + name + "Count =ReadShort(bytes, ref index);\r\n";
                readingStr += "\t\t\tfor (int i = 0; i < " + name + "Count; ++i)\r\n";
                readingStr += "\t\t\t\t" + name + ".Add(" + GetReadingValueStr(Tkey) + ", " +
                                                     GetReadingValueStr(Tvalue) + ");\r\n";
            }
            else if(type=="enum")
            {
                string data = field.Attributes["data"].Value;
                readingStr += "\t\t\t" + name + " = (" + data + ")ReadInt(bytes, ref index);\r\n";
            }
            else
                readingStr += "\t\t\t" + name + " = " + GetReadingValueStr(type) + ";\r\n";
        }
        return readingStr;
    }
    private string GetReadingValueStr(string type)
    {
        switch (type)
        {
            case "byte":
                return "ReadByte(bytes, ref index)";
            case "int":
                return "ReadInt(bytes, ref index)";
            case "short":
                return "ReadShort(bytes, ref index)";
            case "long":
                return "ReadLong(bytes, ref index)";
            case "float":
                return "ReadFloat(bytes, ref index)";
            case "bool":
                return "ReadBool(bytes, ref index)";
            case "string":
                return "ReadString(bytes, ref index)";
            default:
                return "ReadData<" + type + ">(bytes, ref index)";
        }
    }
    public void GeneratreMsg(XmlNodeList nodes)
    {
        string idStr = "";
        string namespaceStr = "";
        string classNameStr = "";
        string fieldStr = "";
        string GetBytesNumStr = "";
        string WritingStr = "";
        string ReadingStr = "";
        foreach (XmlNode dataNode in nodes)
        {
            //消息ID
            idStr = dataNode.Attributes["id"].Value;
            //命名空间
            namespaceStr = dataNode.Attributes["namespace"].Value;
            //类名
            classNameStr = dataNode.Attributes["name"].Value;
            //读取所有字段节点
            XmlNodeList fields = dataNode.SelectNodes("field");
            //通过这个方法进行成员变量声明的拼接 返回拼接结果
            fieldStr = GetFieldStr(fields);
            //通过这个方法对GetBytesNum函数中字符串内容进行拼接 返回结果
            GetBytesNumStr = GetGetBytesNumStr(fields);
            //通过这个方法对Writing函数中字符串内容进行拼接 返回结果
            WritingStr = GetWritingStr(fields);
            //通过这个方法对Reading函数中字符串内容进行拼接 返回结果
            ReadingStr = GetReadingStr(fields);
            string dataStr = "using System;\r\n" +
                             "using System.Collections.Generic;\r\n" +
                             "using System.Text;\r\n" +
            $"namespace {namespaceStr}\r\n" +
                                "{\r\n" +
                                $"\tpublic class {classNameStr} : BaseMsg\r\n" +
                                "\t{\r\n" +
                                      $"{fieldStr}" +
                                      "\t\tpublic override int GetBytesNum()\r\n" +
                                      "\t\t{\r\n" +
                                      "\t\t\tint num=8;\r\n" +//这个8代表的是 消息ID的4个字节和消息长度的4个字节
                                      $"{GetBytesNumStr}" +
                                      "\t\t\treturn num;\r\n" +
                                      "\t\t}\r\n" +
                                      "\t\tpublic override byte[] Writing()\r\n" +
                                      "\t\t{\r\n" +
                                      "\t\t\tint index =0;\r\n" +
                                      "\t\t\tbyte [] bytes =new byte[GetBytesNum()];\r\n" +
                                      "\t\t\tWriteInt(bytes, GetID(), ref index);\r\n" +
                                      "\t\t\tWriteInt(bytes, bytes.Length - 8, ref index);\r\n" +
                                      $"{WritingStr}" +
                                      "\t\t\treturn bytes;\r\n" +
                                      "\t\t}\r\n" +
                                      "\t\tpublic override int Reading(byte[] bytes, int beginIndex = 0)\r\n" +
                                      "\t\t{\r\n" +
                                      "\t\t\tint index =beginIndex ;\r\n" +
                                      $"{ReadingStr}" +
                                      "\t\t\treturn index - beginIndex;\r\n" +
                                      "\t\t}\r\n" +
                                      "\t\tpublic override int GetID()\r\n" +
                                      "\t\t{\r\n" +
                                      "\t\t\treturn " + idStr + ";\r\n"+
                                      "\t\t}\r\n" +
                                      "\t}\r\n" +
                                      "}";
            //保存文件的路径
            string path = SAVE_PATH + namespaceStr + "/Msg/";
            //如果不存在这个文件夹 则创建
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
            //字符串保存 存储为枚举脚本文件
            File.WriteAllText(path + classNameStr + ".cs", dataStr);
        }
        Debug.Log("数据结构类生成结束");
    }
}

实现效果

点击生成C#脚本,就会在Unity编辑器中生成一个Protocol文件夹,里边有我们想要的消息脚本

                                                                                                                       

以GamePlayer命名空间为例展示生成后的代码

这是Data文件夹脚本

using System;
using System.Collections.Generic;
using System.Text;
namespace GamePlayer
{
	public class PlayerData : BaseData
	{
		public int id;
		public float atk;
		public bool sex;
		public long lev;
		public int[]arrays;
		public List<int>list;
		public Dictionary<int,string>dic;
		public override int GetBytesNum()
		{
			int num=0;
			num +=4;
			num +=4;
			num +=1;
			num +=8;
			num +=2;
			for(int i = 0;i<arrays.Length;i++)
				num +=4;
			num +=2;
			for(int i = 0;i< list.Count;i++)
				num +=4;
			num +=2;
			foreach(int key in dic.Keys)
			{
				num +=4;
				num +=4+Encoding.UTF8.GetByteCount(dic[key]);
			}
			return num;
		}
		public override byte[] Writing()
		{
			int index =0;
			byte [] bytes =new byte[GetBytesNum()];
			WriteInt(bytes ,id, ref index);
			WriteFloat(bytes ,atk, ref index);
			WriteBool(bytes ,sex, ref index);
			WriteLong(bytes ,lev, ref index);
			WriteShort(bytes, (short)arrays.Length, ref index);
			for (int i=0; i < arrays.Length;++i)
				WriteInt(bytes ,arrays[i], ref index);
			WriteShort(bytes, (short)list.Count, ref index);
			for (int i=0; i < list.Count;++i)
				WriteInt(bytes ,list[i], ref index);
			WriteShort(bytes, (short)dic.Count, ref index);
			foreach(int key in dic.Keys)
			{
				WriteInt(bytes ,key, ref index);
				WriteString(bytes ,dic[key], ref index);
			}
			return bytes;
		}
		public override int Reading(byte[] bytes, int beginIndex = 0)
		{
			int index =beginIndex ;
			id = ReadInt(bytes, ref index);
			atk = ReadFloat(bytes, ref index);
			sex = ReadBool(bytes, ref index);
			lev = ReadLong(bytes, ref index);
			short arraysLength =ReadShort(bytes, ref index);
			arrays = new int[arraysLength];
			for (int i = 0; i < arraysLength; ++i)
				arrays[i] = ReadInt(bytes, ref index);
			list =new List<int>();
			short listCount =ReadShort(bytes, ref index);
			for (int i = 0; i < listCount; ++i)
				list.Add(ReadInt(bytes, ref index));
			dic = new  Dictionary<int, string>();
			short dicCount =ReadShort(bytes, ref index);
			for (int i = 0; i < dicCount; ++i)
				dic.Add(ReadInt(bytes, ref index), ReadString(bytes, ref index));
			return index - beginIndex;
		}
	}
}

这是Enum文件夹中脚本

namespace GamePlayer
{
	public enum E_PLAYER_TYPE
	{
		MAIN=1,
		OTHER,
	}
}

  这是Msg文件夹中脚本

using System;
using System.Collections.Generic;
using System.Text;
namespace GamePlayer
{
	public class PlayerMsg : BaseMsg
	{
		public int playerID;
		public PlayerData data;
		public override int GetBytesNum()
		{
			int num=8;
			num +=4;
			num +=data.GetBytesNum();
			return num;
		}
		public override byte[] Writing()
		{
			int index =0;
			byte [] bytes =new byte[GetBytesNum()];
			WriteInt(bytes, GetID(), ref index);
			WriteInt(bytes, bytes.Length - 8, ref index);
			WriteInt(bytes ,playerID, ref index);
			WriteData(bytes ,data, ref index);
			return bytes;
		}
		public override int Reading(byte[] bytes, int beginIndex = 0)
		{
			int index =beginIndex ;
			playerID = ReadInt(bytes, ref index);
			data = ReadData<PlayerData>(bytes, ref index);
			return index - beginIndex;
		}
		public override int GetID()
		{
			return 1001;
		}
	}
}

​总结


        // 根据配置生成脚本的文件的主要思路就是
        // 按规则拼接字符串
        // 只要有数据和规则,我们就可以动态的创建脚本文件
        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2371957.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux 系统的指令详解介绍

Linux 系统的指令详解介绍 一、指令的本质与定义1. 什么是指令?2. Linux 指令分类二、指令格式解析1. 基础语法结构2. 语法要素详解(1)选项类型(2)参数类型三、核心指令分类1. 文件操作指令2. 文本处理指令3. 系统管理指令一、指令的本质与定义 1. 什么是指令? 定义:在…

Milvus(17):向量索引、FLAT、IVF_FLAT

1 索引向量字段 利用存储在索引文件中的元数据&#xff0c;Milvus 以专门的结构组织数据&#xff0c;便于在搜索或查询过程中快速检索所需的信息。 Milvus 提供多种索引类型和指标&#xff0c;可对字段值进行排序&#xff0c;以实现高效的相似性搜索。下表列出了不同向量字段类…

芯片笔记 - 手册参数注释

芯片手册参数注释 基础参数外围设备USB OTG&#xff08;On-The-Go&#xff09;以太网存储卡&#xff08;SD&#xff09;SDIO 3.0(Secure Digital Input/Output)GPIO&#xff08;General Purpose Input/Output 通用输入/输出接口&#xff09;ADC&#xff08;Analog to Digital C…

RabbitMQ学习(第二天)

文章目录 1、生产者可靠性①、生产者重连②、生产者确认 2、MQ可靠性①、数据持久化②、LazyQueue(惰性队列) 3、消费者可靠性①、消费者确认②、失败重试机制③、保证业务幂等性 总结 之前的学习中&#xff0c;熟悉了java中搭建和操作RabbitMQ发送接收消息&#xff0c;熟悉使用…

【JS逆向基础】爬虫核心模块:request模块与包的概念

前言&#xff1a;这篇文章主要介绍JS逆向爬虫中最常用的request模块&#xff0c;然后引出一系列的模块的概念&#xff0c;当然Python中其他比较常用的还有很多模块&#xff0c;正是这些模块也可以称之为库的东西构成了Python强大的生态&#xff0c;使其几乎可以实现任何功能。下…

LabVIEW燃气轮机测控系统

在能源需求不断增长以及生态环境保护备受重视的背景下&#xff0c;微型燃气轮机凭借其在经济性、可靠性、维护性及排放性等方面的显著优势&#xff0c;在航空航天、分布式发电等众多领域得到广泛应用。随着计算机技术的快速发展&#xff0c;虚拟仪器应运而生&#xff0c;LabVIE…

QT | 常用控件

前言 &#x1f493; 个人主页&#xff1a;普通young man-CSDN博客 ⏩ 文章专栏&#xff1a;C_普通young man的博客-CSDN博客 ⏩ 本人giee: 普通小青年 (pu-tong-young-man) - Gitee.com 若有问题 评论区见&#x1f4dd; &#x1f389;欢迎大家点赞&#x1f44d;收藏⭐文章 —…

LLM论文笔记 28: Universal length generalization with Turing Programs

Arxiv日期&#xff1a;2024.10.4机构&#xff1a;Harvard University 关键词 图灵机 CoT 长度泛化 核心结论 Turing Programs 的提出 提出 Turing Programs&#xff0c;一种基于图灵机计算步骤的通用 CoT 策略。通过将算法任务分解为逐步的“磁带更新”&#xff08;类似图灵…

AI日报 · 2025年5月07日|谷歌发布 Gemini 2.5 Pro 预览版 (I/O 版本),大幅提升编码与视频理解能力

1、谷歌发布 Gemini 2.5 Pro 预览版 (I/O 版本)&#xff0c;大幅提升编码与视频理解能力 谷歌于5月6日提前发布 Gemini 2.5 Pro 预览版 (I/O 版本)&#xff0c;为开发者带来更强编码能力&#xff0c;尤其优化了前端与UI开发、代码转换及智能体工作流构建&#xff0c;并在WebDe…

指定Docker镜像源,使用阿里云加速异常解决

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo异常贴图 yum-config-manager&#xff1a;找不到命令 因为系统默认没有安装这个命令&#xff0c;这个命令在yum-utils 包里&#xff0c;可以通过命令yum -y install yum-util…

VITA STANDARDS LIST,VITA 标准清单下载

VITA STANDARDS LIST&#xff0c;VITA 标准清单下载 DesignationTitleAbstractStatusVMEbus Handbook, 4th EditionA users guide to the VME, VME64 and VME64x bus specifications - features over 70 product photos and over 160 circuit diagrams, tables and graphs. The…

Python从入门到高手8.3节-元组的常用操作方法

目录 11.3.1 元组的常用操作方法 11.3.2 元组的查找 11.3.3 祈祷明天不再打雷下雨 11.3.1 元组的常用操作方法 元组类型是一种抽象数据类型&#xff0c;抽象数据类型定义了数据类型的操作方法&#xff0c;在本节的内容中&#xff0c;着重介绍元组类型的操作方法。 ​ 元组是…

Linux系统安装PaddleDetection

一、安装cuda 1. 查看设备 先输入nvidia-smi&#xff0c;查看设备支持的最大cuda版本&#xff0c;选择官网中支持的cuda版本 https://www.paddlepaddle.org.cn/install/quick?docurl/documentation/docs/zh/install/conda/linux-conda.html 2. 下载CUDA并安装 使用快捷键…

【漫话机器学习系列】239.训练错误率(Training Error Rate)

机器学习基础概念 | 训练错误率&#xff08;Training Error Rate&#xff09;详解 在机器学习模型训练过程中&#xff0c;评估模型性能是至关重要的一个环节。其中&#xff0c;训练错误率&#xff08;Training Error Rate&#xff09; 是最基础也最重要的性能指标之一。 本文将…

OpenCV 图形API(80)图像与通道拼接函数-----仿射变换函数warpAffine()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 对图像应用仿射变换。 函数 warpAffine 使用指定的矩阵对源图像进行变换&#xff1a; dst ( x , y ) src ( M 11 x M 12 y M 13 , M 21 x M…

数据结构与算法:图论——最短路径

最短路径 先给出一些leetcode算法题&#xff0c;以后遇见了相关题目再往上增加 最短路径的4个常用算法是Floyd、Bellman-Ford、SPFA、Dijkstra。不同应用场景下&#xff0c;应有选择地使用它们&#xff1a; 图的规模小&#xff0c;用Floyd。若边的权值有负数&#xff0c;需要…

提示词工程:通向AGI时代的人机交互艺术

‌引言&#xff1a;从基础到精通的提示词学习之旅‌ 欢迎来到 ‌"AGI时代核心技能"‌ 系列课程的第二模块——‌提示词工程‌。在这个模块中&#xff0c;我们将系统性地探索如何通过精心设计的提示词&#xff0c;释放大型语言模型的全部潜力&#xff0c;实现高效、精…

是更换Window资源管理器的时候了-> Files-community/Files

Files • 主页https://files.community/ 它已经做到了 云盘文件集成、标签页和多种布局、丰富的文件预览…… 您想要的一切现代文件管理器的强大功能&#xff0c; Files 都能做到。 概述 Files 是一个现代文件管理器&#xff0c;可帮助用户组织他们的文件和文件夹。Files 的…

基于windows安装MySQL8.0.40

基于windows安装MySQL8.0.40 基于windows 安装 MySQL8.0.40&#xff0c;解压文件到D:\mysql-8.0.40-winx64 在D:\mysql-8.0.40-winx64目录下创建my.ini文件&#xff0c;并更新一下内容 [client] #客户端设置&#xff0c;即客户端默认的连接参数 # 设置mysql客户端连接服务…

【Vue】组件自定义事件 TodoList 自定义事件数据传输

目录 一、绑定 二、解绑 组件自定义事件总结 TodoList案例对数据传输事件的修改 总结不易~ 本章节对我有很大收获&#xff0c; 希望对你也是&#xff01;&#xff01;&#xff01; 本章节素材已上传Gitee&#xff1a;yihaohhh/我爱Vue - Gitee.com 前面我们学习的clikc、…