internal void Serialize(CppTypeContext context) { var data = context.LocalType; var headerLocation = Path.Combine(_config.OutputDirectory, _config.OutputHeaderDirectory, context.HeaderFileName); Directory.CreateDirectory(Path.GetDirectoryName(headerLocation)); using var ms = new MemoryStream(); using var rawWriter = new StreamWriter(ms); using var writer = new CppStreamWriter(rawWriter, " "); // Write header writer.WriteComment($"Autogenerated from {nameof(CppHeaderCreator)}"); writer.WriteComment("Created by Sc2ad"); writer.WriteComment("========================================================================="); writer.WriteLine("#pragma once"); // TODO: determine when/if we need this writer.WriteLine("#pragma pack(push, 8)"); // Write SerializerContext and actual type try { _serializer.Serialize(writer, context, true); } catch (UnresolvedTypeException e) { if (_config.UnresolvedTypeExceptionHandling?.TypeHandling == UnresolvedTypeExceptionHandling.DisplayInFile) { writer.WriteComment("Unresolved type exception!"); writer.WriteLine("/*"); writer.WriteLine(e); writer.WriteLine("*/"); } else if (_config.UnresolvedTypeExceptionHandling?.TypeHandling == UnresolvedTypeExceptionHandling.SkipIssue) { return; } else if (_config.UnresolvedTypeExceptionHandling?.TypeHandling == UnresolvedTypeExceptionHandling.Elevate) { throw new InvalidOperationException($"Cannot elevate {e} to a parent type- there is no parent type!"); } } // End the namespace writer.CloseDefinition(); hasIl2CppTypeCheckInclude = context.NeedIl2CppUtilsFunctionsInHeader; if (data.This.Namespace == "System" && data.This.Name == "ValueType") { IncludeIl2CppTypeCheckIfNotAlready(writer); writer.WriteLine("template<class T>"); writer.WriteLine("struct is_value_type<T, typename std::enable_if_t<std::is_base_of_v<System::ValueType, T>>> : std::true_type{};"); } DefineIl2CppArgTypes(writer, context); writer.Flush(); writer.WriteLine("#pragma pack(pop)"); writer.Flush(); writer.WriteIfDifferent(headerLocation, context); }
// Write the field here public override void Serialize(CppStreamWriter writer, IField field, bool asHeader) { if (writer is null) { throw new ArgumentNullException(nameof(writer)); } if (field is null) { throw new ArgumentNullException(nameof(field)); } // If we could not resolve the type name, don't serialize the field (this should cause a critical failure in the type) if (ResolvedTypeNames[field] == null) { throw new UnresolvedTypeException(field.DeclaringType, field.Type); } var fieldString = ""; foreach (var spec in field.Specifiers) { fieldString += $"{spec} "; } writer.WriteComment(fieldString + field.Type + " " + field.Name); writer.WriteComment($"Offset: 0x{field.Offset:X}"); if (!field.Specifiers.IsStatic() && !field.Specifiers.IsConst()) { writer.WriteFieldDeclaration(ResolvedTypeNames[field] !, SafeFieldNames[field]); } writer.Flush(); Serialized(field); }
internal void Serialize(CppTypeContext context) { var sourceLocation = Path.Combine(_config.OutputDirectory, _config.OutputSourceDirectory, context.CppFileName); Directory.CreateDirectory(Path.GetDirectoryName(sourceLocation)); using var ms = new MemoryStream(); using var rawWriter = new StreamWriter(ms); using var writer = new CppStreamWriter(rawWriter, " "); // Write header writer.WriteComment($"Autogenerated from {nameof(CppSourceCreator)}"); writer.WriteComment($"Created by Sc2ad"); writer.WriteComment("========================================================================="); try { // Write SerializerContext and actual type _serializer.Serialize(writer, context, false); } catch (UnresolvedTypeException e) { if (_config.UnresolvedTypeExceptionHandling?.TypeHandling == UnresolvedTypeExceptionHandling.DisplayInFile) { writer.WriteLine("// Unresolved type exception!"); writer.WriteLine("/*"); writer.WriteLine(e); writer.WriteLine("*/"); } else if (_config.UnresolvedTypeExceptionHandling?.TypeHandling == UnresolvedTypeExceptionHandling.SkipIssue) { return; } else if (_config.UnresolvedTypeExceptionHandling?.TypeHandling == UnresolvedTypeExceptionHandling.Elevate) { throw new InvalidOperationException($"Cannot elevate {e} to a parent type- there is no parent type!"); } } writer.Flush(); rawWriter.Flush(); writer.WriteIfDifferent(sourceLocation, context); }