/* deserialization of entire list. generates code like: * * static public void ReadStructBuf(NetworkReader reader, SyncListBuf instance) * { * ushort count = reader.ReadUInt16(); * instance.Clear() * for (ushort i = 0; i < count; i++) * { * instance.AddInternal(instance.DeserializeItem(reader)); * } * } */ void GenerateReadFunc(MethodReference readItemFunc) { var functionName = "_ReadStruct" + m_TypeDef.Name + "_"; if (m_TypeDef.DeclaringType != null) { functionName += m_TypeDef.DeclaringType.Name; } else { functionName += "None"; } // create new reader for this type MethodDefinition readerFunc = new MethodDefinition(functionName, MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig, Weaver.voidType); readerFunc.Parameters.Add(new ParameterDefinition("reader", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkReaderType))); readerFunc.Parameters.Add(new ParameterDefinition("instance", ParameterAttributes.None, m_TypeDef)); readerFunc.Body.Variables.Add(new VariableDefinition(Weaver.uint16Type)); readerFunc.Body.Variables.Add(new VariableDefinition(Weaver.uint16Type)); readerFunc.Body.InitLocals = true; ILProcessor worker = readerFunc.Body.GetILProcessor(); worker.Append(worker.Create(OpCodes.Ldarg_0)); worker.Append(worker.Create(OpCodes.Callvirt, Weaver.NetworkReadUInt16)); worker.Append(worker.Create(OpCodes.Stloc_0)); // Call Clear() from the base class worker.Append(worker.Create(OpCodes.Ldarg_1)); MethodReference genericClearMethod = Helpers.MakeHostInstanceGeneric(Weaver.SyncListClear, m_ItemType); worker.Append(worker.Create(OpCodes.Callvirt, genericClearMethod)); worker.Append(worker.Create(OpCodes.Ldc_I4_0)); worker.Append(worker.Create(OpCodes.Stloc_1)); var loopCheckLabel = worker.Create(OpCodes.Nop); worker.Append(worker.Create(OpCodes.Br, loopCheckLabel)); // loop body var loopHeadLabel = worker.Create(OpCodes.Nop); worker.Append(loopHeadLabel); worker.Append(worker.Create(OpCodes.Ldarg_1)); worker.Append(worker.Create(OpCodes.Ldarg_1)); worker.Append(worker.Create(OpCodes.Ldarg_0)); worker.Append(worker.Create(OpCodes.Callvirt, readItemFunc)); // call the generic AddInternal from the base class var addInternal = Weaver.ResolveMethod(Weaver.SyncListStructType, "AddInternal"); var addInternalTyped = Helpers.MakeHostInstanceGeneric(addInternal, m_ItemType); worker.Append(worker.Create(OpCodes.Callvirt, addInternalTyped)); worker.Append(worker.Create(OpCodes.Ldloc_1)); worker.Append(worker.Create(OpCodes.Ldc_I4_1)); worker.Append(worker.Create(OpCodes.Add)); worker.Append(worker.Create(OpCodes.Conv_U2)); worker.Append(worker.Create(OpCodes.Stloc_1)); // loop check worker.Append(loopCheckLabel); worker.Append(worker.Create(OpCodes.Ldloc_1)); worker.Append(worker.Create(OpCodes.Ldloc_0)); worker.Append(worker.Create(OpCodes.Blt, loopHeadLabel)); // done //worker.Append(worker.Create(OpCodes.Ldloc_1)); worker.Append(worker.Create(OpCodes.Ret)); Weaver.RegisterReadByReferenceFunc(m_TypeDef.FullName, readerFunc); }
private void GenerateReadFunc(MethodReference readItemFunc) { string name = "_ReadStruct" + this.m_TypeDef.Name + "_"; if (this.m_TypeDef.DeclaringType != null) { name = name + this.m_TypeDef.DeclaringType.Name; } else { name = name + "None"; } MethodDefinition newReaderFunc = new MethodDefinition(name, MethodAttributes.CompilerControlled | MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.Static, Weaver.voidType) { Parameters = { new ParameterDefinition("reader", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkReaderType)), new ParameterDefinition("instance", ParameterAttributes.None, this.m_TypeDef) }, Body = { Variables = { new VariableDefinition("v0", Weaver.uint16Type), new VariableDefinition("v1", Weaver.uint16Type) }, InitLocals = true } }; ILProcessor iLProcessor = newReaderFunc.Body.GetILProcessor(); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldarg_0)); iLProcessor.Append(iLProcessor.Create(OpCodes.Callvirt, Weaver.NetworkReadUInt16)); iLProcessor.Append(iLProcessor.Create(OpCodes.Stloc_0)); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldarg_1)); TypeReference[] arguments = new TypeReference[] { this.m_ItemType }; MethodReference method = Helpers.MakeHostInstanceGeneric(Weaver.SyncListClear, arguments); iLProcessor.Append(iLProcessor.Create(OpCodes.Callvirt, method)); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldc_I4_0)); iLProcessor.Append(iLProcessor.Create(OpCodes.Stloc_1)); Instruction target = iLProcessor.Create(OpCodes.Nop); iLProcessor.Append(iLProcessor.Create(OpCodes.Br, target)); Instruction instruction = iLProcessor.Create(OpCodes.Nop); iLProcessor.Append(instruction); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldarg_1)); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldarg_1)); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldarg_0)); iLProcessor.Append(iLProcessor.Create(OpCodes.Callvirt, readItemFunc)); TypeReference[] referenceArray2 = new TypeReference[] { this.m_ItemType }; MethodReference reference3 = Helpers.MakeHostInstanceGeneric(Weaver.ResolveMethod(Weaver.SyncListStructType, "AddInternal"), referenceArray2); iLProcessor.Append(iLProcessor.Create(OpCodes.Callvirt, reference3)); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldloc_1)); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldc_I4_1)); iLProcessor.Append(iLProcessor.Create(OpCodes.Add)); iLProcessor.Append(iLProcessor.Create(OpCodes.Conv_U2)); iLProcessor.Append(iLProcessor.Create(OpCodes.Stloc_1)); iLProcessor.Append(target); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldloc_1)); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldloc_0)); iLProcessor.Append(iLProcessor.Create(OpCodes.Blt, instruction)); iLProcessor.Append(iLProcessor.Create(OpCodes.Ret)); Weaver.RegisterReadByReferenceFunc(this.m_TypeDef.FullName, newReaderFunc); }
/*serialization of entire list. generates code like: * * static public void WriteStructBuf(NetworkWriter writer, SyncListBuf items) * { * ushort count = (ushort)items.Count; * writer.Write(count); * for (ushort i=0; i < count; i++) * { * items.SerializeItem(writer, items.GetItem(i)); * } * } */ void GenerateWriteFunc(MethodReference writeItemFunc) { var functionName = "_WriteStruct" + m_TypeDef.GetElementType().Name + "_"; if (m_TypeDef.DeclaringType != null) { functionName += m_TypeDef.DeclaringType.Name; } else { functionName += "None"; } // create new writer for this type MethodDefinition writerFunc = new MethodDefinition(functionName, MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig, Weaver.voidType); writerFunc.Parameters.Add(new ParameterDefinition("writer", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkWriterType))); writerFunc.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(m_TypeDef))); writerFunc.Body.Variables.Add(new VariableDefinition(Weaver.uint16Type)); writerFunc.Body.Variables.Add(new VariableDefinition(Weaver.uint16Type)); writerFunc.Body.InitLocals = true; ILProcessor worker = writerFunc.Body.GetILProcessor(); worker.Append(worker.Create(OpCodes.Ldarg_1)); // call the generic Count from the base class var getCount = Weaver.ResolveMethod(Weaver.SyncListStructType, "get_Count"); var getCountTyped = Helpers.MakeHostInstanceGeneric(getCount, m_ItemType); worker.Append(worker.Create(OpCodes.Callvirt, getCountTyped)); worker.Append(worker.Create(OpCodes.Stloc_0)); worker.Append(worker.Create(OpCodes.Ldarg_0)); worker.Append(worker.Create(OpCodes.Ldloc_0)); worker.Append(worker.Create(OpCodes.Callvirt, Weaver.NetworkWriteUInt16)); worker.Append(worker.Create(OpCodes.Ldc_I4_0)); worker.Append(worker.Create(OpCodes.Stloc_1)); var loopCheckLabel = worker.Create(OpCodes.Nop); worker.Append(worker.Create(OpCodes.Br, loopCheckLabel)); //loop start var loopStartLabel = worker.Create(OpCodes.Nop); worker.Append(loopStartLabel); worker.Append(worker.Create(OpCodes.Ldarg_1)); worker.Append(worker.Create(OpCodes.Ldarg_0)); worker.Append(worker.Create(OpCodes.Ldarg_1)); worker.Append(worker.Create(OpCodes.Ldloc_1)); // call the generic [] from the base class var getItem = Weaver.ResolveMethod(Weaver.SyncListStructType, "GetItem"); var getItemTyped = Helpers.MakeHostInstanceGeneric(getItem, m_ItemType); worker.Append(worker.Create(OpCodes.Callvirt, getItemTyped)); worker.Append(worker.Create(OpCodes.Callvirt, writeItemFunc)); worker.Append(worker.Create(OpCodes.Ldloc_1)); worker.Append(worker.Create(OpCodes.Ldc_I4_1)); worker.Append(worker.Create(OpCodes.Add)); worker.Append(worker.Create(OpCodes.Conv_U2)); worker.Append(worker.Create(OpCodes.Stloc_1)); worker.Append(loopCheckLabel); worker.Append(worker.Create(OpCodes.Ldloc_1)); worker.Append(worker.Create(OpCodes.Ldloc_0)); worker.Append(worker.Create(OpCodes.Blt, loopStartLabel)); worker.Append(worker.Create(OpCodes.Ret)); Weaver.RegisterWriteFunc(m_TypeDef.FullName, writerFunc); }
private void GenerateReadFunc(MethodReference readItemFunc) { string text = "_ReadStruct" + this.m_TypeDef.Name + "_"; if (this.m_TypeDef.DeclaringType != null) { text += this.m_TypeDef.DeclaringType.Name; } else { text += "None"; } MethodDefinition methodDefinition = new MethodDefinition(text, MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig, Weaver.voidType); methodDefinition.Parameters.Add(new ParameterDefinition("reader", ParameterAttributes.None, Weaver.scriptDef.MainModule.Import(Weaver.NetworkReaderType))); methodDefinition.Parameters.Add(new ParameterDefinition("instance", ParameterAttributes.None, this.m_TypeDef)); methodDefinition.Body.Variables.Add(new VariableDefinition("v0", Weaver.uint16Type)); methodDefinition.Body.Variables.Add(new VariableDefinition("v1", Weaver.uint16Type)); methodDefinition.Body.InitLocals = true; ILProcessor iLProcessor = methodDefinition.Body.GetILProcessor(); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldarg_0)); iLProcessor.Append(iLProcessor.Create(OpCodes.Callvirt, Weaver.NetworkReadUInt16)); iLProcessor.Append(iLProcessor.Create(OpCodes.Stloc_0)); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldarg_1)); MethodReference method = Helpers.MakeHostInstanceGeneric(Weaver.SyncListClear, new TypeReference[] { this.m_ItemType }); iLProcessor.Append(iLProcessor.Create(OpCodes.Callvirt, method)); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldc_I4_0)); iLProcessor.Append(iLProcessor.Create(OpCodes.Stloc_1)); Instruction instruction = iLProcessor.Create(OpCodes.Nop); iLProcessor.Append(iLProcessor.Create(OpCodes.Br, instruction)); Instruction instruction2 = iLProcessor.Create(OpCodes.Nop); iLProcessor.Append(instruction2); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldarg_1)); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldarg_1)); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldarg_0)); iLProcessor.Append(iLProcessor.Create(OpCodes.Callvirt, readItemFunc)); MethodReference self = Weaver.ResolveMethod(Weaver.SyncListStructType, "AddInternal"); MethodReference method2 = Helpers.MakeHostInstanceGeneric(self, new TypeReference[] { this.m_ItemType }); iLProcessor.Append(iLProcessor.Create(OpCodes.Callvirt, method2)); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldloc_1)); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldc_I4_1)); iLProcessor.Append(iLProcessor.Create(OpCodes.Add)); iLProcessor.Append(iLProcessor.Create(OpCodes.Conv_U2)); iLProcessor.Append(iLProcessor.Create(OpCodes.Stloc_1)); iLProcessor.Append(instruction); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldloc_1)); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldloc_0)); iLProcessor.Append(iLProcessor.Create(OpCodes.Blt, instruction2)); iLProcessor.Append(iLProcessor.Create(OpCodes.Ret)); Weaver.RegisterReadByReferenceFunc(this.m_TypeDef.FullName, methodDefinition); }