public override async Task LoadWrapup(ObjectGeneration obj) { try { await Task.WhenAll( obj.IterateFields(expandSets : SetMarkerType.ExpandSets.TrueAndInclude, nonIntegrated : true) .Select(async(field) => { await SetContainerSubTriggers(obj, field); })); foreach (var field in obj.IterateFields(expandSets: SetMarkerType.ExpandSets.TrueAndInclude, nonIntegrated: true)) { await SetRecordTrigger(obj, field, field.GetFieldData()); } await SetObjectTrigger(obj); obj.GetObjectData().WiringComplete.Complete(); await base.LoadWrapup(obj); } catch (Exception ex) { obj.GetObjectData().WiringComplete.SetException(ex); throw; } }
public override async Task PostLoad(ObjectGeneration obj) { obj.GetObjectData().MajorRecordFlags = obj.Node.GetAttribute("majorFlag", false); if (obj.GetObjectData().MajorRecordFlags && obj.GetObjectType() != ObjectType.Record) { throw new ArgumentException(); } }
public override async Task PreLoad(ObjectGeneration obj) { var objData = obj.GetObjectData(); objData.BaseRecordTypeConverter = GetConverter(obj.Node.Element(XName.Get("BaseRecordTypeOverrides", LoquiGenerator.Namespace))); var gameModeOverrides = obj.Node.Element(XName.Get("GameModeOverride", LoquiGenerator.Namespace)); if (gameModeOverrides != null) { var mode = gameModeOverrides.GetAttribute <GameRelease>("release", throwException: true); if (objData.GameReleaseConverters == null) { objData.GameReleaseConverters = new Dictionary <GameRelease, RecordTypeConverter>(); } objData.GameReleaseConverters[mode] = GetConverter(gameModeOverrides); } var versionModeOverrides = obj.Node.Element(XName.Get("VersionOverride", LoquiGenerator.Namespace)); if (versionModeOverrides != null) { var version = versionModeOverrides.GetAttribute <byte>("version", throwException: true); if (objData.VersionConverters == null) { objData.VersionConverters = new Dictionary <byte, RecordTypeConverter>(); } objData.VersionConverters[version] = GetConverter(versionModeOverrides); } await base.PreLoad(obj); }
public override Task GenerateInRegistration(ObjectGeneration obj, FileGeneration fg) { var objData = obj.GetObjectData(); GenerateConverterMember(fg, obj.BaseClass, objData.BaseRecordTypeConverter, "Base"); foreach (var field in obj.IterateFields(expandSets: SetMarkerType.ExpandSets.FalseAndInclude, nonIntegrated: true)) { LoquiType loquiType = field as LoquiType; if (loquiType == null) { switch (field) { case WrapperType wrapper: loquiType = wrapper.SubTypeGeneration as LoquiType; if (loquiType != null) { break; } continue; default: continue; } } var fieldData = loquiType.GetFieldData(); GenerateConverterMember(fg, loquiType.TargetObjectGeneration, fieldData.RecordTypeConverter, field.Name); } return(base.GenerateInRegistration(obj, fg)); }
private void GenerateCustomBinaryEndCreatePartial(ObjectGeneration obj, FileGeneration fg) { var data = obj.GetObjectData(); if (data.CustomBinaryEnd == CustomEnd.Off) { return; } if (data.CustomBinaryEnd == CustomEnd.Normal) { using (var args = new ArgsWrapper(fg, $"public static partial void CustomBinaryEndImport")) { args.Add($"{ReaderClass} {ReaderMemberName}"); args.Add($"{obj.Interface(getter: false, internalInterface: true)} obj"); } using (var args = new FunctionWrapper(fg, $"public static void CustomBinaryEndImportPublic")) { args.Add($"{ReaderClass} {ReaderMemberName}"); args.Add($"{obj.Interface(getter: false, internalInterface: true)} obj"); } using (new BraceWrapper(fg)) { using (var args = new ArgsWrapper(fg, $"CustomBinaryEndImport")) { args.AddPassArg(ReaderMemberName); args.AddPassArg($"obj"); } } } }
public override async Task PreLoad(ObjectGeneration obj) { var recTypeOverrides = obj.Node.Element(XName.Get("BaseRecordTypeOverrides", LoquiGenerator.Namespace)); if (recTypeOverrides == null) { return; } var recConversions = recTypeOverrides.Elements(XName.Get("Mapping", LoquiGenerator.Namespace)); if (recConversions == null || !recConversions.Any()) { return; } var objData = obj.GetObjectData(); objData.BaseRecordTypeConverter = new RecordTypeConverter( recConversions.Select((n) => { return(new KeyValuePair <RecordType, RecordType>( new RecordType(n.GetAttribute("From")), new RecordType(n.GetAttribute("To")))); }).ToArray()); await base.PreLoad(obj); }
public override async Task GenerateInCommon(ObjectGeneration obj, FileGeneration fg, MaskTypeSet maskTypes) { if (!await obj.IsMajorRecord()) { return; } if (!maskTypes.Applicable(LoquiInterfaceType.IGetter, CommonGenerics.Class, MaskType.Normal)) { return; } //ToDo // Modify to getter interface after copy is refactored fg.AppendLine($"partial void PostDuplicate({obj.Name} obj, {obj.ObjectName} rhs, Func<FormKey> getNextFormKey, IList<({nameof(IMajorRecordCommon)} Record, FormKey OriginalFormKey)>? duplicatedRecords);"); fg.AppendLine(); fg.AppendLine($"public{obj.FunctionOverride()}{nameof(IMajorRecordCommon)} Duplicate({nameof(IMajorRecordCommonGetter)} item, Func<FormKey> getNextFormKey, IList<({nameof(IMajorRecordCommon)} Record, FormKey OriginalFormKey)>? duplicatedRecords)"); using (new BraceWrapper(fg)) { if (obj.Abstract) { fg.AppendLine($"throw new {nameof(NotImplementedException)}();"); } else { fg.AppendLine($"var ret = new {obj.Name}(getNextFormKey(){((obj.GetObjectData().GameCategory?.HasFormVersion() ?? false) ? $", (({obj.Interface(getter: true)})item).FormVersion" : string.Empty)});"); //ToDo // Modify to getter interface after copy is refactored fg.AppendLine($"ret.DeepCopyIn(({obj.ObjectName})item);"); fg.AppendLine("duplicatedRecords?.Add((ret, item.FormKey));"); fg.AppendLine($"PostDuplicate(ret, ({obj.ObjectName})item, getNextFormKey, duplicatedRecords);"); fg.AppendLine("return ret;"); } } fg.AppendLine(); }
public override async Task PostLoad(ObjectGeneration obj) { try { foreach (var field in obj.IterateFields(expandSets: SetMarkerType.ExpandSets.TrueAndInclude, nonIntegrated: true)) { MutagenFieldData subData; switch (field) { case WrapperType wrapper: subData = wrapper.SubTypeGeneration.GetFieldData(); break; case DictType_KeyedValue dict: subData = dict.ValueTypeGen.GetFieldData(); break; default: continue; } subData.Parent = field; } } catch (Exception ex) { obj.GetObjectData().WiringComplete.SetException(ex); throw; } }
protected override async Task GenerateNewSnippet(ObjectGeneration obj, FileGeneration fg) { if (await obj.IsMajorRecord()) { fg.AppendLine($"var ret = new {obj.Name}();"); } else { if (obj.TryGetCustomRecordTypeTriggers(out var customLogicTriggers)) { using (var args = new ArgsWrapper(fg, $"var nextRecord = HeaderTranslation.GetNext{(obj.GetObjectType() == ObjectType.Subrecord ? "Subrecord" : "Record")}Type")) { args.Add($"reader: {ReaderMemberName}.Reader"); args.Add("contentLength: out var customLen"); } fg.AppendLine("nextRecord = recordTypeConverter.ConvertToCustom(nextRecord);"); fg.AppendLine("switch (nextRecord.TypeInt)"); using (new BraceWrapper(fg)) { foreach (var item in customLogicTriggers) { fg.AppendLine($"case {item.TypeInt}: // {item.Type}"); } using (new DepthWrapper(fg)) { using (var args = new ArgsWrapper(fg, "return CustomRecordTypeTrigger")) { args.Add($"{ReaderMemberName}: {ReaderMemberName}.SpawnWithLength(customLen + {ReaderMemberName}.{nameof(MutagenFrame.MetaData)}.{nameof(ParsingBundle.Constants)}.{nameof(GameConstants.SubConstants)}.{nameof(GameConstants.SubConstants.HeaderLength)})"); args.Add("recordType: nextRecord"); args.AddPassArg("recordTypeConverter"); } } fg.AppendLine("default:"); using (new DepthWrapper(fg)) { fg.AppendLine("break;"); } } } using (var args = new ArgsWrapper(fg, $"var ret = new {obj.Name}{obj.GetGenericTypes(MaskType.Normal)}")) { if (obj.GetObjectType() == ObjectType.Mod) { args.AddPassArg("modKey"); } if (obj.GetObjectData().GameReleaseOptions != null) { args.AddPassArg("release"); } } if (obj.GetObjectType() == ObjectType.Mod) { fg.AppendLine($"{ReaderMemberName}.MetaData.ModKey = modKey;"); } } }
public static bool IsVariableLengthStruct(this ObjectGeneration objGen) { var objData = objGen.GetObjectData(); return(objGen.GetObjectType() == ObjectType.Subrecord && objData.TriggeringSource == null && objData.HasVersioning()); }
public override async Task <bool> AsyncImport(ObjectGeneration obj) { if (obj.GetObjectData().CustomBinaryEnd == CustomEnd.Async) { return(true); } return(await base.AsyncImport(obj)); }
public override Task PreLoad(ObjectGeneration obj) { var data = obj.GetObjectData(); var record = obj.Node.GetAttribute("recordType"); data.FailOnUnknown = obj.Node.GetAttribute <bool>("failOnUnknownType", defaultVal: false); data.CustomBinary = obj.Node.GetAttribute <bool>("customBinary", defaultVal: false); data.UsesStringFiles = obj.Node.GetAttribute <bool>("usesStringFiles", defaultVal: true); data.CustomBinaryEnd = obj.Node.GetAttribute <CustomEnd>("customBinaryEnd", defaultVal: CustomEnd.Off); data.BinaryOverlay = obj.Node.GetAttribute <BinaryGenerationType>("binaryOverlay", defaultVal: BinaryGenerationType.Normal); var objType = obj.Node.GetAttribute(Mutagen.Bethesda.Generation.Constants.ObjectType); if (!Enum.TryParse <ObjectType>(objType, out var objTypeEnum)) { throw new ArgumentException("Must specify object type."); } data.ObjectType = objTypeEnum; if (record != null) { data.RecordType = new RecordType(record); } else if (objTypeEnum == ObjectType.Group) { data.RecordType = Mutagen.Bethesda.Internals.Constants.Group; } foreach (var elem in obj.Node.Elements(XName.Get("CustomRecordTypeTrigger", LoquiGenerator.Namespace))) { obj.GetObjectData().CustomRecordTypeTriggers.Add(new RecordType(elem.Value)); } if (obj.Node.TryGetAttribute("markerType", out var markerType)) { var markerTypeRec = new RecordType(markerType.Value); data.MarkerType = markerTypeRec; } if (obj.Node.TryGetAttribute("endMarkerType", out var endMarker)) { var markerTypeRec = new RecordType(endMarker.Value); data.EndMarkerType = markerTypeRec; } return(base.PreLoad(obj)); }
public static async Task <TryGet <IEnumerable <RecordType> > > TryGetTriggeringRecordTypes(this ObjectGeneration objGen) { await objGen.LoadingCompleteTask.Task; var data = objGen.GetObjectData(); return(TryGet <IEnumerable <RecordType> > .Create( successful : data.TriggeringRecordTypes.Any(), val : data.TriggeringRecordTypes)); }
public static ObjectType GetObjectType(this ObjectGeneration objGen) { var objType = objGen.GetObjectData().ObjectType; if (objType.HasValue) { return(objType.Value); } return(ObjectType.Subrecord); }
public static async Task <bool> IsSingleTriggerSource(this ObjectGeneration objGen) { var enumer = await objGen.GetObjectData().GenerationTypes; if (!enumer.SelectMany((e) => e.Key).Distinct().Any()) { return(false); } return(!enumer.SelectMany((e) => e.Key).Distinct().CountGreaterThan(1)); }
public static ObjectType GetObjectType(this ObjectGeneration objGen) { var objType = objGen.GetObjectData().ObjectType; if (objType.HasValue) { return(objType.Value); } throw new ArgumentException($"Object {objGen.Name} did not have object type defined."); }
public override async IAsyncEnumerable <string> RequiredUsingStatements(ObjectGeneration obj) { if (obj.GetObjectData().ObjectType == ObjectType.Mod) { yield return("System.Collections.Concurrent"); yield return("System.Threading.Tasks"); yield return("System.IO"); } }
public static bool TryGetMarkerType(this ObjectGeneration objGen, out RecordType recType) { var data = objGen.GetObjectData(); if (data.MarkerType == null) { recType = default; return(false); } recType = data.MarkerType.Value; return(true); }
public override async Task GenerateInRegistration(ObjectGeneration obj, FileGeneration fg) { HashSet <RecordType> trigRecordTypes = new HashSet <RecordType>(); var data = obj.GetObjectData(); trigRecordTypes.Add((await data.GenerationTypes).SelectMany((kv) => kv.Key)); var count = trigRecordTypes.Count(); if (obj.Name.EndsWith("MajorRecord")) { return; } if (count == 1) { fg.AppendLine($"public static readonly {nameof(RecordType)} {Mutagen.Bethesda.Internals.Constants.TriggeringRecordTypeMember} = {obj.RecordTypeHeaderName(trigRecordTypes.First())};"); } else if (count > 1) { fg.AppendLine($"public static ICollectionGetter<RecordType> TriggeringRecordTypes => _TriggeringRecordTypes.Value;"); fg.AppendLine($"private static readonly Lazy<ICollectionGetter<RecordType>> _TriggeringRecordTypes = new Lazy<ICollectionGetter<RecordType>>(() =>"); using (new BraceWrapper(fg) { AppendSemicolon = true, AppendParenthesis = true }) { fg.AppendLine($"return new CollectionGetterWrapper<RecordType>("); using (new DepthWrapper(fg)) { fg.AppendLine("new HashSet<RecordType>("); using (new DepthWrapper(fg)) { fg.AppendLine($"new RecordType[]"); using (new BraceWrapper(fg) { AppendParenthesis = true }) { using (var comma = new CommaWrapper(fg)) { foreach (var trigger in trigRecordTypes) { comma.Add($"{obj.RecordTypeHeaderName(trigger)}"); } } } } } fg.AppendLine(");"); } } await base.GenerateInRegistration(obj, fg); }
public override async Task GenerateInClass(ObjectGeneration obj, FileGeneration fg) { if (!obj.GetObjectData().MajorRecordFlags) { return; } fg.AppendLine("public MajorFlag MajorFlags"); using (new BraceWrapper(fg)) { fg.AppendLine("get => (MajorFlag)this.MajorRecordFlagsRaw;"); fg.AppendLine("set => this.MajorRecordFlagsRaw = (int)value;"); } }
public static bool TryGetCustomRecordTypeTriggers(this ObjectGeneration objGen, out IEnumerable <RecordType> recTypes) { var data = objGen.GetObjectData(); if (data.CustomRecordTypeTriggers == null || data.CustomRecordTypeTriggers.Count == 0) { recTypes = default; return(false); } recTypes = data.CustomRecordTypeTriggers; return(true); }
protected string GetRecordTypeString(ObjectGeneration obj, Accessor gameReleaseAccessor, Accessor versionAccessor) { var data = obj.GetObjectData(); if (data.GameReleaseConverters != null) { return($"recordTypeConverter.Combine({obj.RegistrationName}.Get({gameReleaseAccessor})).ConvertToCustom({obj.RecordTypeHeaderName(obj.GetRecordType())})"); } if (data.VersionConverters != null) { return($"recordTypeConverter.Combine({obj.RegistrationName}.Get({versionAccessor})).ConvertToCustom({obj.RecordTypeHeaderName(obj.GetRecordType())})"); } return($"recordTypeConverter.ConvertToCustom({obj.RecordTypeHeaderName(obj.GetRecordType())})"); }
public override async Task GenerateInInterface(ObjectGeneration obj, FileGeneration fg, bool internalInterface, bool getter) { if (!obj.GetObjectData().MajorRecordFlags || internalInterface) { return; } if (getter) { fg.AppendLine($"{obj.ObjectName}.MajorFlag MajorFlags {{ get; }}"); } else { fg.AppendLine($"new {obj.ObjectName}.MajorFlag MajorFlags {{ get; set; }}"); } }
public void GenerateModGameCategoryRegistration(ObjectGeneration obj, FileGeneration fg) { using (var ns = new NamespaceWrapper(fg, $"Mutagen.Bethesda.{obj.GetObjectData().GameCategory}.Internals", fileScoped: false)) { using (var c = new ClassWrapper(fg, $"{obj.Name}_Registration")) { c.Partial = true; c.Interfaces.Add(nameof(IModRegistration)); } using (new BraceWrapper(fg)) { fg.AppendLine($"public {nameof(GameCategory)} GameCategory => {nameof(GameCategory)}.{obj.GetObjectData().GameCategory};"); } fg.AppendLine(); } }
public override async IAsyncEnumerable <string> RequiredUsingStatements(ObjectGeneration obj) { if (obj.GetObjectData().ObjectType == ObjectType.Mod) { yield return("System.Collections.Concurrent"); yield return("System.Threading.Tasks"); yield return("System.IO"); yield return("System.IO.Abstractions"); yield return("Mutagen.Bethesda.Plugins.Masters"); yield return("Mutagen.Bethesda.Strings.DI"); } }
public override async Task PreLoad(ObjectGeneration obj) { if (obj.GetObjectType() != ObjectType.Mod) { return; } var elems = obj.Node.Elements(XName.Get(GameReleaseOptions, LoquiGenerator.Namespace)); if (!elems.Any()) { return; } var objData = obj.GetObjectData(); objData.GameReleaseOptions = elems.Select(el => Enum.Parse <GameRelease>(el.Value)).ToHashSet(); obj.Interfaces.Add(LoquiInterfaceDefinitionType.IGetter, $"IMajorRecordContextEnumerable<{obj.Interface(getter: false, internalInterface: true)}>"); }
public override async Task GenerateInInterface(ObjectGeneration obj, FileGeneration fg, bool internalInterface, bool getter) { await base.GenerateInInterface(obj, fg, internalInterface, getter); if (obj.GetObjectType() != ObjectType.Mod) { return; } if (!getter) { return; } if (obj.GetObjectData().GameReleaseOptions == null) { return; } fg.AppendLine($"{ReleaseEnumName(obj)} {ReleaseEnumName(obj)} {{ get; }}"); }
public override async Task LoadWrapup(ObjectGeneration obj) { await base.LoadWrapup(obj); foreach (var field in obj.IterateFields(expandSets: SetMarkerType.ExpandSets.FalseAndInclude)) { if (!(field is DataType dataType)) { continue; } XElement elem = new XElement("Enum"); elem.Add(new XAttribute(Loqui.Generation.Constants.NAME, dataType.StateName)); elem.Add(new XAttribute(Loqui.Generation.Constants.ENUM_NAME, $"{obj.ObjectName}.{dataType.EnumName}")); elem.Add(new XAttribute("binary", nameof(BinaryGenerationType.NoGeneration))); elem.Add(new XAttribute(Loqui.Generation.Constants.NULLABLE, "false")); await obj.LoadField(elem, requireName : true, add : true); } obj.GetObjectData().DataTypeModuleComplete.SetResult(); }
public override async Task LoadWrapup(ObjectGeneration obj) { var objData = obj.GetObjectData(); await Task.WhenAll( objData.WiringComplete.Task, objData.DataTypeModuleComplete.Task); bool triggerEncountered = false; foreach (var field in obj.IterateFields( nonIntegrated: true, expandSets: SetMarkerType.ExpandSets.False)) { if (field is SetMarkerType) { continue; } if (field.Derivative || !field.IntegrateField) { continue; } var data = field.GetFieldData(); if (data.Binary == BinaryGenerationType.NoGeneration) { continue; } if (data.HasTrigger) { triggerEncountered = true; } else if (triggerEncountered) { throw new ArgumentException($"{obj.Name} cannot have an embedded field without a record type after ones with record types have been defined: {field.Name}"); } } await base.LoadWrapup(obj); }
private void GenerateWriteParallel(ObjectGeneration obj, FileGeneration fg) { LoquiType groupInstance = null; LoquiType listGroupInstance = null; var objData = obj.GetObjectData(); fg.AppendLine("const int CutCount = 100;"); using (var args = new FunctionWrapper(fg, "public static void WriteParallel")) { args.Add($"{obj.Interface(getter: true, internalInterface: false)} item"); args.Add($"Stream stream"); args.Add($"{nameof(BinaryWriteParameters)} param"); args.Add($"ModKey modKey"); } using (new BraceWrapper(fg)) { string gameConstantsStr; if (objData.GameReleaseOptions == null) { gameConstantsStr = $"{nameof(GameConstants)}.{obj.GetObjectData().GameCategory}"; } else { fg.AppendLine($"var gameConstants = {nameof(GameConstants)}.Get(item.{ReleaseEnumName(obj)}.ToGameRelease());"); gameConstantsStr = $"gameConstants"; } fg.AppendLine($"var bundle = new {nameof(WritingBundle)}({gameConstantsStr});"); fg.AppendLine($"var writer = new MutagenWriter(stream, bundle);"); using (var args = new ArgsWrapper(fg, $"{nameof(ModHeaderWriteLogic)}.{nameof(ModHeaderWriteLogic.WriteHeader)}")) { args.AddPassArg("param"); args.AddPassArg("writer"); args.Add("mod: item"); args.Add("modHeader: item.ModHeader.DeepCopy()"); args.AddPassArg("modKey"); } int groupCount = obj.IterateFields() .Select(f => f as LoquiType) .Where(l => l != null) .Where(l => l.TargetObjectGeneration?.GetObjectData().ObjectType == ObjectType.Group) .Count(); fg.AppendLine($"Stream[] outputStreams = new Stream[{groupCount}];"); fg.AppendLine($"List<Action> toDo = new List<Action>();"); int i = 0; foreach (var field in obj.IterateFields()) { if (!(field is LoquiType loqui)) { continue; } if (loqui.TargetObjectGeneration?.GetObjectData().ObjectType != ObjectType.Group) { continue; } if (loqui.TargetObjectGeneration.Name == "ListGroup") { listGroupInstance = loqui; } else { groupInstance = loqui; } if (loqui.GetGroupTarget().GetObjectData().CustomBinaryEnd == CustomEnd.Off && loqui.TargetObjectGeneration.Name != "ListGroup") { fg.AppendLine($"toDo.Add(() => WriteGroupParallel(item.{field.Name}, writer.MetaData.MasterReferences!, {i}{(objData.GameReleaseOptions == null ? null : ", gameConstants")}, outputStreams{(objData.UsesStringFiles ? ", param.StringsWriter" : null)}));"); } else { fg.AppendLine($"toDo.Add(() => Write{field.Name}Parallel(item.{field.Name}, writer.MetaData.MasterReferences!, {i}{(objData.GameReleaseOptions == null ? null : ", gameConstants")}, outputStreams));"); } i++; } fg.AppendLine("Parallel.Invoke(toDo.ToArray());"); using (var args = new ArgsWrapper(fg, $"{nameof(UtilityTranslation)}.{nameof(UtilityTranslation.CompileStreamsInto)}")) { args.Add("outputStreams.NotNull()"); args.Add("stream"); } } fg.AppendLine(); if (groupInstance != null) { using (var args = new FunctionWrapper(fg, $"public static void WriteGroupParallel<T>")) { args.Add("IGroupGetter<T> group"); args.Add($"{nameof(MasterReferenceReader)} masters"); args.Add("int targetIndex"); if (objData.GameReleaseOptions != null) { args.Add($"{nameof(GameConstants)} gameConstants"); } args.Add("Stream[] streamDepositArray"); if (objData.UsesStringFiles) { args.Add($"{nameof(StringsWriter)}? stringsWriter"); } args.Wheres.AddRange(groupInstance.TargetObjectGeneration.GenerateWhereClauses(LoquiInterfaceType.IGetter, groupInstance.TargetObjectGeneration.Generics)); } using (new BraceWrapper(fg)) { string gameConstantsStr; if (objData.GameReleaseOptions == null) { gameConstantsStr = $"{nameof(GameConstants)}.{obj.GetObjectData().GameCategory}"; } else { gameConstantsStr = "gameConstants"; } fg.AppendLine("if (group.RecordCache.Count == 0) return;"); fg.AppendLine($"var cuts = group.Cut(CutCount).ToArray();"); fg.AppendLine($"Stream[] subStreams = new Stream[cuts.Length + 1];"); fg.AppendLine($"byte[] groupBytes = new byte[{gameConstantsStr}.GroupConstants.HeaderLength];"); fg.AppendLine($"BinaryPrimitives.WriteInt32LittleEndian(groupBytes.AsSpan(), RecordTypes.GRUP.TypeInt);"); fg.AppendLine($"var groupByteStream = new MemoryStream(groupBytes);"); fg.AppendLine($"using (var stream = new MutagenWriter(groupByteStream, {gameConstantsStr}, dispose: false))"); using (new BraceWrapper(fg)) { fg.AppendLine($"stream.Position += 8;"); fg.AppendLine($"GroupBinaryWriteTranslation.WriteEmbedded<T>(group, stream);"); } fg.AppendLine($"subStreams[0] = groupByteStream;"); fg.AppendLine($"Parallel.ForEach(cuts, (cutItems, state, counter) =>"); using (new BraceWrapper(fg) { AppendSemicolon = true, AppendParenthesis = true }) { fg.AppendLine($"{nameof(MemoryTributary)} trib = new {nameof(MemoryTributary)}();"); fg.AppendLine($"var bundle = new {nameof(WritingBundle)}({gameConstantsStr})"); using (var prop = new PropertyCtorWrapper(fg)) { prop.Add($"{nameof(WritingBundle.MasterReferences)} = masters"); if (objData.UsesStringFiles) { prop.Add($"{nameof(WritingBundle.StringsWriter)} = stringsWriter"); } } fg.AppendLine($"using (var stream = new MutagenWriter(trib, bundle, dispose: false))"); using (new BraceWrapper(fg)) { fg.AppendLine($"foreach (var item in cutItems)"); using (new BraceWrapper(fg)) { fg.AppendLine($"item.WriteToBinary(stream);"); } } fg.AppendLine($"subStreams[(int)counter + 1] = trib;"); } fg.AppendLine($"UtilityTranslation.CompileSetGroupLength(subStreams, groupBytes);"); fg.AppendLine($"streamDepositArray[targetIndex] = new CompositeReadStream(subStreams, resetPositions: true);"); } fg.AppendLine(); } }