/// <summary> /// 创建实例 /// </summary> /// <param name="param"></param> /// <returns></returns> public static object createTypeInstance(object param) { luaMessage other = luaMessageCache.get(param); if (other == null) { return(null); } var newMsg = new luaMessage(param); var otherFieldsInfo = (Dictionary <int, fieldDataInfo>)other.valueL; otherFieldsInfo.Keys.CopyTo(_auxiliary, 0); int count = otherFieldsInfo.Count; int key = 0; fieldDataInfo info = null; for (int i = 0; i < count; i++) { //创建field key = _auxiliary[i]; info = otherFieldsInfo[key]; var descriptor = info.descriptor; // fieldDescriptor.copyCreateDescriptor(info.descriptor); if (descriptor != null) { var fieldData = fieldDataInfo.createFieldData(key, descriptor); if (fieldData != null) { newMsg.addField(key, fieldData); } } } return(newMsg); }
//////////////////////////////////////////////////////////////////////// /// <summary> /// 添加消息缓存 /// </summary> /// <param name="key"></param> /// <param name="msg"></param> internal static void add(object key, luaMessage msg) { if (_cache.Contains(key)) { return; } _cache.Add(key, msg); }
/// <summary> /// 根据message生成table /// </summary> internal static void createLuaTable(LuaState state, luaMessage msg) { //压入消息表 LuaDLL.lua_newtable(state.L); fieldDataInfo field = null; for (int idx = 1; idx <= msg.fieldsCount(); idx++) { field = (fieldDataInfo)msg[idx]; if (field.Value == null) { continue; } string key = field.descriptor.name; ProtoTypeCode typeCode = field.descriptor.typeCode; if (field.descriptor.isRepeated()) { LuaDLL.lua_pushstring(state.L, key); LuaDLL.lua_newtable(state.L); for (int j = 0; j < field.Value.count(); j++) { if (field.descriptor.haveNestedType()) { createLuaTable(state, (luaMessage)field.Value[j]); } else { object luaValue = field.Value[j]; pushLuaValue(typeCode, state, luaValue); } LuaDLL.lua_rawseti(state.L, -2, j + 1); } LuaDLL.lua_settable(state.L, -3); } else { LuaDLL.lua_pushstring(state.L, key); if (field.descriptor.haveNestedType()) { createLuaTable(state, (luaMessage)field.Value.valueL); } else { object luaValue = field.Value.valueL; pushLuaValue(typeCode, state, luaValue); } LuaDLL.lua_settable(state.L, -3); } } }
/// <summary> /// LUA带有嵌入式消息读取 /// /// 测试流程: /// 1、C#中生成消息实例,并给消息字段赋值 /// 2、用C#的写入方式写入流中 /// 3、用lua的解析方式方式从流中读取数据,生成对应lua消息类型实例 /// /// 消息定义文件: /// 1、lua部分: /// 文件: protoMsgDef.lua.txt /// 定义: idMsg=900000, table="lua_message", nestedTable="lua_nested" /// /// 2、C#部分 /// 文件: Analys.proto /// 定义: message=lua_message, message=lua_nested /// /// </summary> static void luaProtoMsgWithNestR() { Msg.lua_message msg = new Msg.lua_message(); msg.value_repeated.Add(new Msg.lua_nested() { value_int32 = 1, value_bool = true, value_bytes = System.Text.Encoding.UTF8.GetBytes("Hello"), value_string = "Oh", }); msg.value_repeated.Add(new Msg.lua_nested() { value_int32 = 2, value_bool = true, value_bytes = System.Text.Encoding.UTF8.GetBytes("World"), value_string = "Yes", }); using (MemoryStream stream = new MemoryStream()) { //序列化 ProtoBuf.Serializer.Serialize(stream, msg); //反序列化 luaMessage msgRev = null; using (var desializeStream = new MemoryStream(stream.ToArray(), 0, (int)stream.Length)) { using (luaProtoReader reader = luaProtoReader.createLuaProtoReader(desializeStream)) { if (reader != null) { msgRev = reader.readLuaMessage(900000); } } //消息发送测试 luaProtobuf.getInstance().receiveMsg(900000, desializeStream); } //打印结果 string lsss = msgRev.logStr(); LogSys.Log(lsss); if (msgRev != null) { LogSys.Log("_LUA_PROTO_R_WITH_NEST_ success!"); } } }
/////////////////////////////////////////////////////////////////////////// /// <summary> /// 从流中读取lua消息 /// </summary> /// <param name="idMsg">配置表中的消息索引</param> /// <returns></returns> public luaMessage readLuaMessage(object idMsg) { luaMessage msg = (luaMessage)luaMessageCache.createTypeInstance(idMsg); if (msg == null) { return(null); } int fieldCount = msg.fieldsCount(); fieldDataInfo fieldData = null; for (int idx = 1; idx <= fieldCount; idx++) { fieldData = (fieldDataInfo)msg[idx]; if (fieldData == null) { continue; } WireType wireType = fieldData.descriptor.wireType; ProtoTypeCode typeCode = fieldData.descriptor.typeCode; string nestedTypeName = fieldData.descriptor.nestedTypeName; if (tryReadFieldHeader(idx, wireType)) { //创建值字段 if (!fieldData.appendValue()) { continue; } if (fieldData.descriptor.isRepeated()) { do { var obj = readLuaObject(typeCode, wireType, nestedTypeName); fieldData.Value.addChild(obj); } while (tryReadFieldHeader(idx, wireType)); } else { fieldData.Value.valueL = readLuaObject(typeCode, wireType, nestedTypeName); } } } return(msg); }
/// <summary> /// LUA无嵌入式消息读取 /// /// 测试流程: /// 1、从lua中读取消息数据表(table) /// 2、用C#的写入方式写入流中 /// 3、用lua的解析方式方式从流中读取数据,生成对应lua消息类型实例 /// /// 消息定义文件: /// 1、lua部分: /// 文件: protoMsgDef.lua.txt /// 定义: idMsg=900001, table="lua_message2" /// /// 2、C#部分 /// 文件: Analys.proto /// 定义: message=lua_message2 /// /// </summary> static void luaProtoMsgWithoutNestR() { using (MemoryStream mem = new MemoryStream()) { var msg2 = new Msg.lua_message2(); msg2.value_int32 = 1; msg2.value_uint32 = 2; msg2.value_int64 = 3; msg2.value_uint64 = 4; msg2.value_bool = true; msg2.value_bytes = System.Text.Encoding.UTF8.GetBytes("I have a dream!"); msg2.value_float = 5.0f; msg2.value_double = 6.0; msg2.value_string = "All men are created equal!"; ProtoBuf.Serializer.Serialize(mem, msg2); MemoryStream desializeStream = null; luaMessage msgRev = null; try { desializeStream = new System.IO.MemoryStream(mem.ToArray(), 0, (int)mem.Length); using (luaProtoReader reader = luaProtoReader.createLuaProtoReader(desializeStream)) { if (reader != null) { msgRev = reader.readLuaMessage(900001); } } } finally { if (desializeStream != null) { desializeStream.Dispose(); } desializeStream = null; //打印结果 string lsss = msgRev.logStr(); LogSys.Log(lsss); if (msgRev != null) { LogSys.Log("_LUA_PROTO_R_WITHOUT_NEST_ success!"); } } } }
/// <summary> /// LUA无嵌入式消息写入 /// /// 测试流程: /// 1、从lua中读取消息数据表(table) /// 2、用lua的写入方式写入流中 /// 3、用原有的解析方式从流中读取数据,生成对应C#消息类型实例 /// /// 消息定义文件: /// 1、lua部分: /// 文件: protoMsgDef.lua.txt /// 定义: idMsg=900001, table="lua_message2" /// 数据: table="____protoMsg900001" /// /// 2、C#部分 /// 文件: Analys.proto /// 定义: message=lua_message2 /// /// </summary> static void luaProtoMsgWithoutNestW() { var protoMsg = luaSvrManager.getInstance().luaSvr.luaState.getTable("____protoMsg900001"); luaMessage msg = luaProtoHelper.readLuaMessage(900001, protoMsg); //打印消息 string lsss = msg.logStr(); LogSys.Log(lsss); using (MemoryStream stream = new MemoryStream()) { //把lua表的数据写入流中 var protoWriter = new luaProtoWriter(stream); protoWriter.writeLuaMessage(msg); protoWriter.close(); MemoryStream desializeStream = null; Msg.lua_message2 msgRev = null; try { desializeStream = new System.IO.MemoryStream(stream.ToArray(), 0, (int)stream.Length); msgRev = ProtoBuf.Serializer.Deserialize <Msg.lua_message2>(desializeStream); } finally { if (desializeStream != null) { desializeStream.Dispose(); } desializeStream = null; } if (msgRev != null) { LogSys.Log("_LUA_PROTO_W_WITHOUT_NEST_ success!"); } } }
/////////////////////////////////////////////////////////////////////////// /// <summary> /// 写入消息 /// </summary> /// <param name="msg"></param> /// <returns></returns> public bool writeLuaMessage(luaMessage msg) { if (msg == null) { return(false); } int nFieldCount = msg.count(); for (int fieldIdx = 1; fieldIdx <= nFieldCount; fieldIdx++) { var field = (fieldDataInfo)msg[fieldIdx]; if (field.Value == null) { continue; } var wireType = field.descriptor.wireType; var typeCode = field.descriptor.typeCode; //写入数据 if (field.descriptor.isRepeated()) { int listCount = field.Value.count(); for (int i = 0; i < listCount; i++) { writeField(field.number, wireType, typeCode, field.Value[i]); } } else { writeField(field.number, wireType, typeCode, field.Value.valueL); } } return(true); }
/// <summary> /// 初始化消息定义 /// </summary> static internal void init() { LuaTable protoCfgTbl = luaSvrManager.getInstance().LuaProtoDefTbl; if (protoCfgTbl == null) { return; } object key = 0; foreach (LuaTable.TablePair kvp in protoCfgTbl) { key = luaProtoHelper.regualarKey(kvp.key); if (key == null || kvp.value.GetType() != typeof(LuaTable)) { continue; } //LogSys.Log("***************************** << " + kvp.key.ToString() + " >> ***********************************"); //创建消息实体 var luaMsg = new luaMessage(key); //读取消息定义 var msgTbl = (LuaTable)kvp.value; foreach (LuaTable.TablePair field in msgTbl) { var fieldInfo = (LuaTable)field.value; if (fieldInfo == null) { continue; } int idx = (int)luaProtoHelper.regualarKey(field.key); EFieldModifier modifier = (EFieldModifier)luaProtoHelper.regualarKey(fieldInfo[1]); //类型信息 ProtoTypeCode typeCode = ProtoTypeCode.Empty; string nestedTypeName = null; if (fieldInfo[2].GetType() == typeof(double)) { typeCode = (ProtoTypeCode)luaProtoHelper.regualarKey(fieldInfo[2]); } else { typeCode = ProtoTypeCode.Type; nestedTypeName = (string)fieldInfo[2]; } string name = (string)fieldInfo[3]; //创建field var descriptor = fieldDescriptor.createDescriptor(modifier, typeCode, name, nestedTypeName); if (descriptor != null) { var info = fieldDataInfo.createFieldData(idx, descriptor); if (info != null) { luaMsg.addField(idx, info); } } //调试信息 string fieldLog = string.Format("idx={0}, modifier={1}, typeCode={2}[{3}], name={4}", idx, modifier, typeCode, nestedTypeName, name); //LogSys.Log(fieldLog); } //加入消息缓存 luaMessageCache.add(key, luaMsg); } }
/// <summary> /// 读取lua消息 /// </summary> internal static luaMessage readLuaMessage(object idMsg, LuaTable luaMsgTbl) { if (luaMsgTbl == null) { return(null); } luaMessage msg = (luaMessage)luaMessageCache.createTypeInstance(idMsg); if (msg == null) { return(null); } //按照索引顺序读取lua表中对应字段的值 int count = msg.fieldsCount(); fieldDataInfo fieldData = null; for (int i = 1; i <= count; i++) { fieldData = (fieldDataInfo)msg[i]; if (fieldData == null) { continue; } //检查lua表中对应字段的值 string name = fieldData.descriptor.name; if (luaMsgTbl[name] == null) { continue; } //创建值字段 if (!fieldData.appendValue()) { continue; } fieldDescriptor des = fieldData.descriptor; if (des.isRepeated()) { LuaTable repeatedTbl = (LuaTable)luaMsgTbl[name]; for (int j = 1; j <= repeatedTbl.length(); j++) { object subValue = luaType2CType(des.typeCode, repeatedTbl[j]); if (subValue == null) { continue; } //嵌入类型 if (des.haveNestedType()) { object subMsg = readLuaMessage(des.nestedTypeName, (LuaTable)subValue); if (subMsg != null) { fieldData.Value.addChild(subMsg); } } else { fieldData.Value.addChild(subValue); } } } else { object value = luaType2CType(des.typeCode, luaMsgTbl[name]); if (value == null) { continue; } //嵌入类型 if (des.haveNestedType()) { fieldData.Value.valueL = readLuaMessage(des.nestedTypeName, (LuaTable)value); } else { fieldData.Value.valueL = value; } } } return(msg); }