public static void WriteCellsParallel( IListGroupGetter <ICellBlockGetter> group, MasterReferenceReader masters, int targetIndex, Stream[] streamDepositArray) { if (group.Records.Count == 0) { return; } Stream[] streams = new Stream[group.Records.Count + 1]; byte[] groupBytes = new byte[GameConstants.Oblivion.GroupConstants.HeaderLength]; BinaryPrimitives.WriteInt32LittleEndian(groupBytes.AsSpan(), RecordTypes.GRUP.TypeInt); var groupByteStream = new MemoryStream(groupBytes); using (var stream = new MutagenWriter(groupByteStream, GameConstants.Oblivion, dispose: false)) { stream.Position += 8; ListGroupBinaryWriteTranslation.WriteEmbedded <ICellBlockGetter>(group, stream); } streams[0] = groupByteStream; Parallel.ForEach(group.Records, (cellBlock, state, counter) => { WriteBlocksParallel( cellBlock, masters, (int)counter + 1, streams); }); PluginUtilityTranslation.CompileSetGroupLength(streams, groupBytes); streamDepositArray[targetIndex] = new CompositeReadStream(streams, resetPositions: true); }
static partial void WriteBinaryContainedRecordTypeCustom <T>( MutagenWriter writer, IListGroupGetter <T> item) where T : class, ICellBlockGetter, IXmlItem, IBinaryItem { Mutagen.Bethesda.Binary.Int32BinaryTranslation.Instance.Write( writer, GroupRecordTypeGetter <T> .GRUP_RECORD_TYPE.TypeInt); }
public static partial void WriteBinaryContainedRecordTypeCustom <T>( MutagenWriter writer, IListGroupGetter <T> item) where T : class, ICellBlockGetter, IBinaryItem { Int32BinaryTranslation <MutagenFrame, MutagenWriter> .Instance.Write( writer, GroupRecordTypeGetter <T> .GRUP_RECORD_TYPE.TypeInt); }
internal static IEnumerable <IModContext <IOblivionMod, IOblivionModGetter, IMajorRecordCommon, IMajorRecordCommonGetter> > EnumerateMajorRecordContexts( this IListGroupGetter <ICellBlockGetter> cellBlocks, ILinkCache linkCache, ModKey modKey, IModContext?parent) { return(EnumerateMajorRecordContexts( cellBlocks, linkCache, type: typeof(IMajorRecordCommonGetter), modKey: modKey, parent: parent, throwIfUnknown: true)); }
internal static IEnumerable <IModContext <IOblivionMod, IOblivionModGetter, IMajorRecordCommon, IMajorRecordCommonGetter> > EnumerateMajorRecordContexts( this IListGroupGetter <ICellBlockGetter> cellBlocks, ILinkCache linkCache, Type type, ModKey modKey, IModContext?parent, bool throwIfUnknown) { foreach (var readOnlyBlock in cellBlocks.Records) { var blockNum = readOnlyBlock.BlockNumber; var blockModified = readOnlyBlock.LastModified; var blockContext = new ModContext <ICellBlockGetter>( modKey: modKey, parent: parent, record: readOnlyBlock); foreach (var readOnlySubBlock in readOnlyBlock.SubBlocks) { var subBlockNum = readOnlySubBlock.BlockNumber; var subBlockModified = readOnlySubBlock.LastModified; var subBlockContext = new ModContext <ICellSubBlockGetter>( modKey: modKey, parent: blockContext, record: readOnlySubBlock); foreach (var readOnlyCell in readOnlySubBlock.Cells) { Func <IOblivionMod, ICellGetter, bool, string?, ICell> cellGetter = (mod, copyCell, dup, edid) => { var formKey = copyCell.FormKey; var retrievedBlock = mod.Cells.Records.FirstOrDefault(x => x.BlockNumber == blockNum); if (retrievedBlock == null) { retrievedBlock = new CellBlock() { BlockNumber = blockNum, GroupType = GroupTypeEnum.InteriorCellBlock, LastModified = blockModified, }; mod.Cells.Records.Add(retrievedBlock); } var subBlock = retrievedBlock.SubBlocks.FirstOrDefault(x => x.BlockNumber == subBlockNum); if (subBlock == null) { subBlock = new CellSubBlock() { BlockNumber = subBlockNum, GroupType = GroupTypeEnum.InteriorCellSubBlock, LastModified = subBlockModified, }; retrievedBlock.SubBlocks.Add(subBlock); } var cell = subBlock.Cells.FirstOrDefault(cell => cell.FormKey == formKey); if (cell == null) { if (dup) { cell = copyCell.Duplicate(mod.GetNextFormKey(edid), CellCopyMask); } else { cell = copyCell.DeepCopy(CellCopyMask); } subBlock.Cells.Add(cell); } return(cell); }; if (LoquiRegistration.TryGetRegister(type, out var regis) && regis.ClassType == typeof(Cell)) { yield return(new ModContext <IOblivionMod, IOblivionModGetter, IMajorRecordCommon, IMajorRecordCommonGetter>( modKey: modKey, record: readOnlyCell, getOrAddAsOverride: (m, r) => cellGetter(m, (ICellGetter)r, false, default(string?)), duplicateInto: (m, r, e) => cellGetter(m, (ICellGetter)r, true, e), parent: subBlockContext)); } else { foreach (var con in CellCommon.Instance.EnumerateMajorRecordContexts( readOnlyCell, linkCache, type, modKey, subBlockContext, throwIfUnknown, (m, c) => cellGetter(m, c, false, default(string?)), (m, c, e) => cellGetter(m, c, true, e))) { yield return(con); } } } } } }
internal static IEnumerable <IModContext <ISkyrimMod, IMajorRecordCommon, IMajorRecordCommonGetter> > EnumerateMajorRecordContexts( this IListGroupGetter <ICellBlockGetter> cellBlocks, ILinkCache linkCache, Type type, ModKey modKey, IModContext?parent, bool throwIfUnknown) { foreach (var readOnlyBlock in cellBlocks.Records) { var blockNum = readOnlyBlock.BlockNumber; var blockContext = new ModContext <ICellBlockGetter>( modKey: modKey, parent: parent, record: readOnlyBlock); foreach (var readOnlySubBlock in readOnlyBlock.SubBlocks) { var subBlockNum = readOnlySubBlock.BlockNumber; var subBlockContext = new ModContext <ICellSubBlockGetter>( modKey: modKey, parent: blockContext, record: readOnlySubBlock); foreach (var readOnlyCell in readOnlySubBlock.Cells) { Func <ISkyrimMod, ICellGetter, ICell> cellGetter = (mod, copyCell) => { var formKey = copyCell.FormKey; var retrievedBlock = mod.Cells.Records.FirstOrDefault(x => x.BlockNumber == blockNum); if (retrievedBlock == null) { retrievedBlock = new CellBlock() { BlockNumber = blockNum, GroupType = GroupTypeEnum.InteriorCellBlock, }; mod.Cells.Records.Add(retrievedBlock); } var subBlock = retrievedBlock.SubBlocks.FirstOrDefault(x => x.BlockNumber == subBlockNum); if (subBlock == null) { subBlock = new CellSubBlock() { BlockNumber = subBlockNum, GroupType = GroupTypeEnum.InteriorCellSubBlock, }; retrievedBlock.SubBlocks.Add(subBlock); } var cell = subBlock.Cells.FirstOrDefault(cell => cell.FormKey == formKey); if (cell == null) { cell = copyCell.DeepCopy(CellCopyMask); subBlock.Cells.Add(cell); } return(cell); }; if (LoquiRegistration.TryGetRegister(type, out var regis) && regis.ClassType == typeof(Cell)) { yield return(new ModContext <ISkyrimMod, IMajorRecordCommon, IMajorRecordCommonGetter>( modKey: modKey, record: readOnlyCell, getter: (m, r) => cellGetter(m, (ICellGetter)r), parent: subBlockContext)); } else { foreach (var con in CellCommon.Instance.EnumerateMajorRecordContexts(readOnlyCell, linkCache, type, modKey, subBlockContext, throwIfUnknown, cellGetter)) { yield return(con); } } } } } }