/// <summary> /// Creates a method that will store all the readers and writers into /// <see cref="Writer{T}.Write"/> and <see cref="Reader{T}.Read"/> /// /// The method will be marked InitializeOnLoadMethodAttribute so it gets /// executed before mirror runtime code /// </summary> /// <param name="currentAssembly"></param> public void InitializeReaderAndWriters() { MethodDefinition rwInitializer = module.GeneratedClass().AddMethod( "InitReadWriters", Mono.Cecil.MethodAttributes.Public | Mono.Cecil.MethodAttributes.Static); ConstructorInfo attributeconstructor = typeof(RuntimeInitializeOnLoadMethodAttribute).GetConstructor(new [] { typeof(RuntimeInitializeLoadType) }); var customAttributeRef = new CustomAttribute(module.ImportReference(attributeconstructor)); customAttributeRef.ConstructorArguments.Add(new CustomAttributeArgument(module.ImportReference <RuntimeInitializeLoadType>(), RuntimeInitializeLoadType.BeforeSceneLoad)); rwInitializer.CustomAttributes.Add(customAttributeRef); if (IsEditorAssembly(module)) { // editor assembly, add InitializeOnLoadMethod too. Useful for the editor tests ConstructorInfo initializeOnLoadConstructor = typeof(InitializeOnLoadMethodAttribute).GetConstructor(new Type[0]); var initializeCustomConstructorRef = new CustomAttribute(module.ImportReference(initializeOnLoadConstructor)); rwInitializer.CustomAttributes.Add(initializeCustomConstructorRef); } ILProcessor worker = rwInitializer.Body.GetILProcessor(); writers.InitializeWriters(worker); readers.InitializeReaders(worker); RegisterMessages(worker); worker.Append(worker.Create(OpCodes.Ret)); }
/// <exception cref="ValueSerializerException">Throws when attribute is used incorrectly</exception> /// <exception cref="SerializeFunctionException">Throws when can not generate read or write function</exception> public static ValueSerializer GetSerializer(ModuleDefinition module, FieldDefinition field, Writers writers, Readers readers) { // if field is in this module use its type for Packer field, // else use the generated class TypeDefinition holder = field.DeclaringType.Module == module ? field.DeclaringType : module.GeneratedClass(); string name = field.DeclaringType.Module == module ? field.Name : $"{field.DeclaringType.FullName}_{field.Name}"; return(GetSerializer(module, holder, field, field.FieldType, name, writers, readers)); }
/// <exception cref="ValueSerializerException">Throws when attribute is used incorrectly</exception> /// <exception cref="SerializeFunctionException">Throws when can not generate read or write function</exception> public static ValueSerializer GetSerializer(ModuleDefinition module, FieldReference field, TypeReference fieldType, Writers writers, Readers readers) { // note: we have to `Resolve()` DeclaringType first, because imported referencev `Module` will be equal. var holder = field.DeclaringType.Resolve(); var name = field.Name; // if field is in this module use its type for Packer field, // else use the generated class if (holder.Module != module) { holder = module.GeneratedClass(); name = $"{field.DeclaringType.FullName}_{field.Name}"; } return(GetSerializer(module, holder, field.Resolve(), fieldType, name, writers, readers)); }