Exemple #1
0
            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);
            }
Exemple #2
0
 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);
 }
Exemple #3
0
 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);
                            }
                        }
                    }
                }
            }
        }
Exemple #6
0
        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);
                            }
                        }
                    }
                }
            }
        }