void GenerateSerialization() { m_Weaver.DLog(m_td, " GenerateSerialization"); foreach (var m in m_td.Methods) { if (m.Name == "Serialize") return; } if (m_td.Fields.Count == 0) { return; } // check for self-referencing types foreach (var field in m_td.Fields) { if (field.FieldType.FullName == m_td.FullName) { m_Weaver.fail = true; Log.Error("GenerateSerialization for " + m_td.Name + " [" + field.FullName + "]. [MessageBase] member cannot be self referencing."); return; } } MethodDefinition serializeFunc = new MethodDefinition("Serialize", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, m_Weaver.voidType); serializeFunc.Parameters.Add(new ParameterDefinition("writer", ParameterAttributes.None, m_Weaver.m_ScriptDef.MainModule.ImportReference(m_Weaver.NetworkWriterType))); ILProcessor serWorker = serializeFunc.Body.GetILProcessor(); foreach (var field in m_td.Fields) { if (field.IsStatic || field.IsPrivate || field.IsSpecialName) continue; if (field.FieldType.Resolve().HasGenericParameters) { m_Weaver.fail = true; Log.Error("GenerateSerialization for " + m_td.Name + " [" + field.FieldType + "/" + field.FieldType.FullName + "]. [MessageBase] member cannot have generic parameters."); return; } if (field.FieldType.Resolve().IsInterface) { m_Weaver.fail = true; Log.Error("GenerateSerialization for " + m_td.Name + " [" + field.FieldType + "/" + field.FieldType.FullName + "]. [MessageBase] member cannot be an interface."); return; } MethodReference writeFunc = m_Weaver.GetWriteFunc(field.FieldType); if (writeFunc != null) { serWorker.Append(serWorker.Create(OpCodes.Ldarg_1)); serWorker.Append(serWorker.Create(OpCodes.Ldarg_0)); serWorker.Append(serWorker.Create(OpCodes.Ldfld, field)); serWorker.Append(serWorker.Create(OpCodes.Call, writeFunc)); } else { m_Weaver.fail = true; Log.Error("GenerateSerialization for " + m_td.Name + " unknown type [" + field.FieldType + "/" + field.FieldType.FullName + "]. [MessageBase] member variables must be basic types."); return; } } serWorker.Append(serWorker.Create(OpCodes.Ret)); m_td.Methods.Add(serializeFunc); }
// serialization of individual element MethodReference GenerateSerialization() { m_Weaver.DLog(m_TypeDef, " GenerateSerialization"); foreach (var m in m_TypeDef.Methods) { if (m.Name == "SerializeItem") { return(m); } } MethodDefinition serializeFunc = new MethodDefinition("SerializeItem", kPublicVirtualHide, m_Weaver.voidType); serializeFunc.Parameters.Add(new ParameterDefinition("writer", ParameterAttributes.None, m_Weaver.m_ScriptDef.MainModule.ImportReference(m_Weaver.NetworkWriterType))); serializeFunc.Parameters.Add(new ParameterDefinition("item", ParameterAttributes.None, m_ItemType)); ILProcessor serWorker = serializeFunc.Body.GetILProcessor(); if (m_ItemType.IsGenericInstance) { m_Weaver.fail = true; Log.Error("GenerateSerialization for " + Helpers.PrettyPrintType(m_ItemType) + " failed. Struct passed into SyncListStruct<T> can't have generic parameters"); return(null); } foreach (var field in m_ItemType.Resolve().Fields) { if (field.IsStatic || field.IsPrivate || field.IsSpecialName) { continue; } var importedField = m_Weaver.m_ScriptDef.MainModule.ImportReference(field); var ft = importedField.FieldType.Resolve(); if (ft.HasGenericParameters) { m_Weaver.fail = true; Log.Error("GenerateSerialization for " + m_TypeDef.Name + " [" + ft + "/" + ft.FullName + "]. UNet [MessageBase] member cannot have generic parameters."); return(null); } if (ft.IsInterface) { m_Weaver.fail = true; Log.Error("GenerateSerialization for " + m_TypeDef.Name + " [" + ft + "/" + ft.FullName + "]. UNet [MessageBase] member cannot be an interface."); return(null); } MethodReference writeFunc = m_Weaver.GetWriteFunc(field.FieldType); if (writeFunc != null) { serWorker.Append(serWorker.Create(OpCodes.Ldarg_1)); serWorker.Append(serWorker.Create(OpCodes.Ldarg_2)); serWorker.Append(serWorker.Create(OpCodes.Ldfld, importedField)); serWorker.Append(serWorker.Create(OpCodes.Call, writeFunc)); } else { m_Weaver.fail = true; Log.Error("GenerateSerialization for " + m_TypeDef.Name + " unknown type [" + ft + "/" + ft.FullName + "]. UNet [MessageBase] member variables must be basic types."); return(null); } } serWorker.Append(serWorker.Create(OpCodes.Ret)); m_TypeDef.Methods.Add(serializeFunc); return(serializeFunc); }