Exemple #1
0
        static MajorRecordInstantiator()
        {
            if (!LoquiRegistration.TryGetRegister(typeof(TMajor), out var regis))
            {
                throw new ArgumentException();
            }

            var ctorInfo = regis.ClassType.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic)
                           .Where(c =>
            {
                var param = c.GetParameters();
                if (param.Length != 2)
                {
                    return(false);
                }
                if (param[0].ParameterType != typeof(FormKey))
                {
                    return(false);
                }
                if (param[1].ParameterType != typeof(GameRelease))
                {
                    return(false);
                }
                return(true);
            })
                           .First();
            var paramInfo = ctorInfo.GetParameters();
            ParameterExpression formKey     = Expression.Parameter(typeof(FormKey), "formKey");
            ParameterExpression gameRelease = Expression.Parameter(typeof(GameRelease), "gameRelease");
            NewExpression       newExp      = Expression.New(ctorInfo, formKey, gameRelease);
            LambdaExpression    lambda      = Expression.Lambda(typeof(Func <FormKey, GameRelease, TMajor>), newExp, formKey, gameRelease);

            Activator = (Func <FormKey, GameRelease, TMajor>)lambda.Compile();
        }
Exemple #2
0
    public bool TryGetTranslator(Type?t, out GetResponse <ObjTransl> not)
    {
        if (t == null)
        {
            not = NullTranslationItem;
            return(true);
        }

        if (typeDict.TryGetValue(t, out var item))
        {
            not = item;
            return(true);
        }

        if (LoquiRegistration.TryGetRegister(t, out var regis))
        {
            var loquiTypes = new Type[]
            {
                regis.ClassType
            };

            var xmlConverterGenType = loquiTranslation.MakeGenericType(loquiTypes);
            var xmlCaster           = GetCaster(xmlConverterGenType, regis.ClassType);
            item = GetResponse <ObjTransl> .Succeed(xmlCaster);

            typeDict[t] = item;
            not         = item;
            return(true);
        }

        if (t.IsEnum ||
            (Nullable.GetUnderlyingType(t)?.IsEnum ?? false))
        {
            var implType = enumTranslation.MakeGenericType(Nullable.GetUnderlyingType(t) ?? t);
            var caster   = GetCaster(implType, t);
            not = SetTranslator(caster, t);
            return(true);
        }

        foreach (var genType in GenericTypes)
        {
            var defs = genType.GetGenericArguments();
            if (defs.Length != 1)
            {
                continue;
            }
            var def = defs[0];
            if (t.InheritsFrom(def))
            {
                var implType = genType.MakeGenericType(t);
                var caster   = GetCaster(implType, t);
                not = SetTranslator(caster, t);
                return(true);
            }
        }
        not = default;
        return(false);
    }
        private static Type GetRecordType(Type t)
        {
            if (LoquiRegistration.TryGetRegister(t, out var regis))
            {
                return(regis.ClassType);
            }

            return(t);
        }
Exemple #4
0
 static ModInstantiator()
 {
     if (!LoquiRegistration.TryGetRegister(typeof(TMod), out var regis))
     {
         throw new ArgumentException();
     }
     Activator = ModInstantiatorReflection.GetActivator <TMod>(regis);
     Importer  = ModInstantiatorReflection.GetImporter <TMod>(regis);
 }
        /// <inheritdoc />
        public bool TryResolve(FormKey formKey, Type type, [MaybeNullWhen(false)] out IMajorRecordCommonGetter majorRec)
        {
            if (!_hasAny || formKey.IsNull)
            {
                majorRec = default;
                return(false);
            }

            DepthCache <IMajorRecordCommonGetter> cache;

            lock (this._winningRecords)
            {
                // Get cache object by type
                if (!this._winningRecords.TryGetValue(type, out cache))
                {
                    cache = new DepthCache <IMajorRecordCommonGetter>();
                    if (type.Equals(typeof(IMajorRecordCommon)) ||
                        type.Equals(typeof(IMajorRecordCommonGetter)))
                    {
                        this._winningRecords[typeof(IMajorRecordCommon)]       = cache;
                        this._winningRecords[typeof(IMajorRecordCommonGetter)] = cache;
                    }
                    else if (LoquiRegistration.TryGetRegister(type, out var registration))
                    {
                        this._winningRecords[registration.ClassType]  = cache;
                        this._winningRecords[registration.GetterType] = cache;
                        this._winningRecords[registration.SetterType] = cache;
                        if (registration.InternalGetterType != null)
                        {
                            this._winningRecords[registration.InternalGetterType] = cache;
                        }
                        if (registration.InternalSetterType != null)
                        {
                            this._winningRecords[registration.InternalSetterType] = cache;
                        }
                    }
                    else
                    {
                        if (!_linkInterfaces.TryGetValue(type, out var objs))
                        {
                            throw new ArgumentException($"A lookup was queried for an unregistered type: {type.Name}");
                        }
                        this._winningRecords[type] = cache;
                    }
                }
            }

            lock (cache)
            {
                // Check for record
                if (cache.TryGetValue(formKey, out majorRec))
                {
                    return(true);
                }
                if (IsPastDepth(cache.Depth))
                {
                    majorRec = default !;
        /// <summary>
        /// Looks up a given FormKey to try to locate the target record.
        ///
        /// Will only look into the Groups that are applicable to the given type.
        /// </summary>
        /// <param name="formKey">FormKey to search for</param>
        /// <param name="majorRec">MajorRecord if found</param>
        /// <typeparam name="TMajor">MajorRecod type or interface to look for</typeparam>
        /// <returns>True if record was found</returns>
        /// <exception cref="ArgumentException">
        /// An unexpected TMajor type will throw an exception.
        /// Unexpected types include:
        ///   - Major Record Types that are not part of this game type.  (Querying for Oblivion records on a Skyrim mod)
        ///   - A setter type is requested from a getter only object.
        /// </exception>
        public bool TryLookup <TMajor>(FormKey formKey, [MaybeNullWhen(false)] out TMajor majorRec)
            where TMajor : class, IMajorRecordCommonGetter
        {
            if (!_hasAny)
            {
                majorRec = default;
                return(false);
            }

            lock (this._loadOrderMajorRecords)
            {
                // Get cache object by type
                if (!this._loadOrderMajorRecords.TryGetValue(typeof(TMajor), out InternalTypedCache cache))
                {
                    cache = new InternalTypedCache();
                    if (typeof(TMajor).Equals(typeof(IMajorRecordCommon)) ||
                        typeof(TMajor).Equals(typeof(IMajorRecordCommonGetter)))
                    {
                        this._loadOrderMajorRecords[typeof(IMajorRecordCommon)]       = cache;
                        this._loadOrderMajorRecords[typeof(IMajorRecordCommonGetter)] = cache;
                    }
                    else if (LoquiRegistration.TryGetRegister(typeof(TMajor), out var registration))
                    {
                        this._loadOrderMajorRecords[registration.ClassType]  = cache;
                        this._loadOrderMajorRecords[registration.GetterType] = cache;
                        this._loadOrderMajorRecords[registration.SetterType] = cache;
                        if (registration.InternalGetterType != null)
                        {
                            this._loadOrderMajorRecords[registration.InternalGetterType] = cache;
                        }
                        if (registration.InternalSetterType != null)
                        {
                            this._loadOrderMajorRecords[registration.InternalSetterType] = cache;
                        }
                    }
                    else
                    {
                        var interfaceMappings = LinkInterfaceMapping.InterfaceToObjectTypes(_gameMode);
                        if (!interfaceMappings.TryGetValue(typeof(TMajor), out var objs))
                        {
                            throw new ArgumentException($"A lookup was queried for an unregistered type: {typeof(TMajor).Name}");
                        }
                        this._loadOrderMajorRecords[typeof(TMajor)] = cache;
                    }
                }

                // Check for record
                if (cache.Dictionary.TryGetValue(formKey, out var majorRecObj))
                {
                    majorRec = (majorRecObj as TMajor) !;
                    return(majorRec != null);
                }
                if (cache.Depth >= this._loadOrder.Count)
                {
                    majorRec = default !;
 public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
 {
     if (value is not Type type)
     {
         return(Binding.DoNothing);
     }
     if (LoquiRegistration.TryGetRegister(type, out var registration))
     {
         return(registration.ProtocolKey.Namespace);
     }
     return(string.Empty);
 }
 public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
 {
     if (value is not Type type)
     {
         return(Binding.DoNothing);
     }
     if (LoquiRegistration.TryGetRegister(type, out var register))
     {
         return(register.ClassType.Name);
     }
     return(type.Name);
 }
        static MajorRecordPrinter()
        {
            var t = typeof(TMajor);

            if (LoquiRegistration.TryGetRegister(t, out var regis))
            {
                _TypeString = $"{regis.ProtocolKey.Namespace}.{t.Name}";
            }
            else
            {
                _TypeString = t.Name;
            }
        }
        static MajorRecordInstantiator()
        {
            if (!LoquiRegistration.TryGetRegister(typeof(T), out var regis))
            {
                throw new ArgumentException();
            }

            var ctorInfo = regis.ClassType.GetConstructors()
                           .Where(c => c.GetParameters().Length == 1)
                           .Where(c => c.GetParameters()[0].ParameterType == typeof(FormKey))
                           .First();
            var paramInfo              = ctorInfo.GetParameters();
            ParameterExpression param  = Expression.Parameter(typeof(FormKey), "formKey");
            NewExpression       newExp = Expression.New(ctorInfo, param);
            LambdaExpression    lambda = Expression.Lambda(typeof(MajorRecordActivator <T>), newExp, param);

            Activator = (MajorRecordActivator <T>)lambda.Compile();
        }
Exemple #11
0
 private IReadOnlyCache <IModContext <TMod, IMajorRecordCommon, IMajorRecordCommonGetter>, FormKey> GetContextCache(Type type)
 {
     if (!_contexts.TryGetValue(type, out var cache))
     {
         if (type.Equals(typeof(IMajorRecordCommon)) ||
             type.Equals(typeof(IMajorRecordCommonGetter)))
         {
             cache = ConstructContextCache(type);
             _contexts[typeof(IMajorRecordCommon)]       = cache;
             _contexts[typeof(IMajorRecordCommonGetter)] = cache;
         }
         else if (LoquiRegistration.TryGetRegister(type, out var registration))
         {
             cache = ConstructContextCache(type);
             _contexts[registration.ClassType]  = cache;
             _contexts[registration.GetterType] = cache;
             _contexts[registration.SetterType] = cache;
             if (registration.InternalGetterType != null)
             {
                 _contexts[registration.InternalGetterType] = cache;
             }
             if (registration.InternalSetterType != null)
             {
                 _contexts[registration.InternalSetterType] = cache;
             }
         }
         else
         {
             var interfaceMappings = LinkInterfaceMapping.InterfaceToObjectTypes(_sourceMod.GameRelease.ToCategory());
             if (!interfaceMappings.TryGetValue(type, out var objs))
             {
                 throw new ArgumentException($"A lookup was queried for an unregistered type: {type.Name}");
             }
             var majorRecords = new Cache <IModContext <TMod, IMajorRecordCommon, IMajorRecordCommonGetter>, FormKey>(x => x.Record.FormKey);
             foreach (var objType in objs)
             {
                 majorRecords.Set(GetContextCache(LoquiRegistration.GetRegister(objType).GetterType).Items);
             }
             _contexts[type] = majorRecords;
             cache           = majorRecords;
         }
     }
     return(cache);
 }
        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 #13
0
        internal static IEnumerable <IModContext <IFallout4Mod, IMajorRecordCommon, IMajorRecordCommonGetter> > EnumerateMajorRecordContexts(
            this IReadOnlyList <IWorldspaceBlockGetter> worldspaceBlocks,
            IWorldspaceGetter worldspace,
            ILinkCache linkCache,
            Type type,
            ModKey modKey,
            IModContext?parent,
            bool throwIfUnknown,
            Func <IFallout4Mod, IWorldspaceGetter, IWorldspace> getOrAddAsOverride,
            Func <IFallout4Mod, IWorldspaceGetter, string?, IWorldspace> duplicateInto)
        {
            foreach (var readOnlyBlock in worldspaceBlocks)
            {
                var blockNumX    = readOnlyBlock.BlockNumberX;
                var blockNumY    = readOnlyBlock.BlockNumberY;
                var blockContext = new ModContext <IWorldspaceBlockGetter>(
                    modKey: modKey,
                    parent: parent,
                    record: readOnlyBlock);
                foreach (var readOnlySubBlock in readOnlyBlock.Items)
                {
                    var subBlockNumY    = readOnlySubBlock.BlockNumberY;
                    var subBlockNumX    = readOnlySubBlock.BlockNumberX;
                    var subBlockContext = new ModContext <IWorldspaceSubBlockGetter>(
                        modKey: modKey,
                        parent: blockContext,
                        record: readOnlySubBlock);
                    foreach (var readOnlyCell in readOnlySubBlock.Items)
                    {
                        Func <IFallout4Mod, ICellGetter, bool, string?, ICell> cellGetter = (mod, copyCell, dup, edid) =>
                        {
                            var worldspaceCopy = getOrAddAsOverride(mod, worldspace);
                            var formKey        = copyCell.FormKey;
                            var retrievedBlock = worldspaceCopy.SubCells.FirstOrDefault(x => x.BlockNumberX == blockNumX && x.BlockNumberY == blockNumY);
                            if (retrievedBlock == null)
                            {
                                retrievedBlock = new WorldspaceBlock()
                                {
                                    BlockNumberX = blockNumX,
                                    BlockNumberY = blockNumY,
                                    GroupType    = GroupTypeEnum.ExteriorCellBlock,
                                };
                                worldspaceCopy.SubCells.Add(retrievedBlock);
                            }
                            var subBlock = retrievedBlock.Items.FirstOrDefault(x => x.BlockNumberX == subBlockNumX && x.BlockNumberY == subBlockNumY);
                            if (subBlock == null)
                            {
                                subBlock = new WorldspaceSubBlock()
                                {
                                    BlockNumberX = subBlockNumX,
                                    BlockNumberY = subBlockNumY,
                                    GroupType    = GroupTypeEnum.ExteriorCellSubBlock,
                                };
                                retrievedBlock.Items.Add(subBlock);
                            }
                            var cell = subBlock.Items.FirstOrDefault(cell => cell.FormKey == formKey);
                            if (cell == null)
                            {
                                if (dup)
                                {
                                    cell = copyCell.Duplicate(mod.GetNextFormKey(edid), CellCopyMask);
                                }
                                else
                                {
                                    cell = copyCell.DeepCopy(CellCopyMask);
                                }
                                subBlock.Items.Add(cell);
                            }
                            return(cell);
                        };

                        if (LoquiRegistration.TryGetRegister(type, out var regis) &&
                            regis.ClassType == typeof(Cell))
                        {
                            yield return(new ModContext <IFallout4Mod, 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 #14
0
        public static SettingsNodeVM MemberFactory(SettingsParameters param, string memberName, Type targetType, object?defaultVal)
        {
            switch (targetType.Name)
            {
            case "Boolean":
                return(new BoolSettingsVM(memberName, defaultVal));

            case "SByte":
                return(new Int8SettingsVM(memberName, defaultVal));

            case "Int16":
                return(new Int16SettingsVM(memberName, defaultVal));

            case "Int32":
                return(new Int32SettingsVM(memberName, defaultVal));

            case "Int64":
                return(new Int64SettingsVM(memberName, defaultVal));

            case "Byte":
                return(new UInt8SettingsVM(memberName, defaultVal));

            case "UInt16":
                return(new UInt16SettingsVM(memberName, defaultVal));

            case "UInt32":
                return(new UInt32SettingsVM(memberName, defaultVal));

            case "UInt64":
                return(new UInt64SettingsVM(memberName, defaultVal));

            case "Double":
                return(new DoubleSettingsVM(memberName, defaultVal));

            case "Single":
                return(new FloatSettingsVM(memberName, defaultVal));

            case "Decimal":
                return(new DecimalSettingsVM(memberName, defaultVal));

            case "ModKey":
                return(new ModKeySettingsVM(param.DetectedLoadOrder.Transform(x => x.Listing.ModKey), memberName, defaultVal));

            case "FormKey":
                return(new FormKeySettingsVM(memberName, defaultVal));

            case "Array`1":
            case "List`1":
            case "IEnumerable`1":
            {
                var firstGen = targetType.GenericTypeArguments[0];
                switch (firstGen.Name)
                {
                case "SByte":
                    return(EnumerableNumericSettingsVM.Factory <sbyte, Int8SettingsVM>(memberName, defaultVal, new Int8SettingsVM()));

                case "Int16":
                    return(EnumerableNumericSettingsVM.Factory <short, Int16SettingsVM>(memberName, defaultVal, new Int16SettingsVM()));

                case "Int32":
                    return(EnumerableNumericSettingsVM.Factory <int, Int32SettingsVM>(memberName, defaultVal, new Int32SettingsVM()));

                case "Int64":
                    return(EnumerableNumericSettingsVM.Factory <long, Int64SettingsVM>(memberName, defaultVal, new Int64SettingsVM()));

                case "Byte":
                    return(EnumerableNumericSettingsVM.Factory <byte, UInt8SettingsVM>(memberName, defaultVal, new UInt8SettingsVM()));

                case "UInt16":
                    return(EnumerableNumericSettingsVM.Factory <ushort, UInt16SettingsVM>(memberName, defaultVal, new UInt16SettingsVM()));

                case "UInt32":
                    return(EnumerableNumericSettingsVM.Factory <uint, UInt32SettingsVM>(memberName, defaultVal, new UInt32SettingsVM()));

                case "UInt64":
                    return(EnumerableNumericSettingsVM.Factory <ulong, UInt64SettingsVM>(memberName, defaultVal, new UInt64SettingsVM()));

                case "Double":
                    return(EnumerableNumericSettingsVM.Factory <double, DoubleSettingsVM>(memberName, defaultVal, new DoubleSettingsVM()));

                case "Single":
                    return(EnumerableNumericSettingsVM.Factory <float, FloatSettingsVM>(memberName, defaultVal, new FloatSettingsVM()));

                case "Decimal":
                    return(EnumerableNumericSettingsVM.Factory <decimal, DecimalSettingsVM>(memberName, defaultVal, new DecimalSettingsVM()));

                case "ModKey":
                    return(EnumerableModKeySettingsVM.Factory(param, memberName, defaultVal));

                case "FormKey":
                    return(EnumerableFormKeySettingsVM.Factory(memberName, defaultVal));

                default:
                {
                    if (firstGen.Name.Contains("FormLink") &&
                        firstGen.IsGenericType &&
                        firstGen.GenericTypeArguments.Length == 1)
                    {
                        var formLinkGen = firstGen.GenericTypeArguments[0];
                        if (!LoquiRegistration.TryGetRegister(formLinkGen, out var regis))
                        {
                            throw new ArgumentException($"Can't create a formlink control for type: {formLinkGen}");
                        }
                        return(EnumerableFormLinkSettingsVM.Factory(param, memberName, regis.GetterType, defaultVal));
                    }
                    var foundType = param.Assembly.GetType(firstGen.FullName !);
                    if (foundType != null)
                    {
                        return(new EnumerableObjectSettingsVM(param, memberName, foundType));
                    }
                }
                    return(new UnknownSettingsVM(memberName));
                }
            }

            case "HashSet`1":
            {
                var firstGen = targetType.GenericTypeArguments[0];
                switch (firstGen.Name)
                {
                case "ModKey":
                    return(EnumerableModKeySettingsVM.Factory(param, memberName, defaultVal));

                case "FormKey":
                    return(EnumerableFormKeySettingsVM.Factory(memberName, defaultVal));

                default:
                {
                    if (firstGen.Name.Contains("FormLink") &&
                        firstGen.IsGenericType &&
                        firstGen.GenericTypeArguments.Length == 1)
                    {
                        var formLinkGen = firstGen.GenericTypeArguments[0];
                        if (!LoquiRegistration.TryGetRegister(formLinkGen, out var regis))
                        {
                            throw new ArgumentException($"Can't create a formlink control for type: {formLinkGen}");
                        }
                        return(EnumerableFormLinkSettingsVM.Factory(param, memberName, regis.GetterType, defaultVal));
                    }
                    var foundType = param.Assembly.GetType(firstGen.FullName !);
                    if (foundType != null)
                    {
                        return(new EnumerableObjectSettingsVM(param, memberName, foundType));
                    }
                }
                    return(new UnknownSettingsVM(memberName));
                }
            }

            default:
            {
                if (targetType.Name.Contains("FormLink") &&
                    targetType.IsGenericType &&
                    targetType.GenericTypeArguments.Length == 1)
                {
                    return(new FormLinkSettingsVM(param.LinkCache, memberName, targetType));
                }
                var foundType = param.Assembly.GetType(targetType.FullName !);
                if (foundType != null)
                {
                    return(new ObjectSettingsVM(param, memberName, foundType));
                }
            }
                return(new UnknownSettingsVM(memberName));
            }
        }
Exemple #15
0
        internal static IEnumerable <IModContext <IOblivionMod, IMajorRecordCommon, IMajorRecordCommonGetter> > EnumerateMajorRecordContexts(
            this IReadOnlyList <IWorldspaceBlockGetter> worldspaceBlocks,
            IWorldspaceGetter worldspace,
            ILinkCache linkCache,
            Type type,
            ModKey modKey,
            IModContext?parent,
            bool throwIfUnknown,
            Func <IOblivionMod, IWorldspaceGetter, IWorldspace> getter)
        {
            foreach (var readOnlyBlock in worldspaceBlocks)
            {
                var blockNumX     = readOnlyBlock.BlockNumberX;
                var blockNumY     = readOnlyBlock.BlockNumberY;
                var blockModified = readOnlyBlock.LastModified;
                var blockContext  = new ModContext <IWorldspaceBlockGetter>(
                    modKey: modKey,
                    parent: parent,
                    record: readOnlyBlock);
                foreach (var readOnlySubBlock in readOnlyBlock.Items)
                {
                    var subBlockNumY     = readOnlySubBlock.BlockNumberY;
                    var subBlockNumX     = readOnlySubBlock.BlockNumberX;
                    var subBlockModified = readOnlySubBlock.LastModified;
                    var subBlockContext  = new ModContext <IWorldspaceSubBlockGetter>(
                        modKey: modKey,
                        parent: blockContext,
                        record: readOnlySubBlock);
                    foreach (var readOnlyCell in readOnlySubBlock.Items)
                    {
                        Func <IOblivionMod, ICellGetter, ICell> cellGetter = (mod, copyCell) =>
                        {
                            var worldspaceCopy = getter(mod, worldspace);
                            var formKey        = copyCell.FormKey;
                            var retrievedBlock = worldspaceCopy.SubCells.FirstOrDefault(x => x.BlockNumberX == blockNumX && x.BlockNumberY == blockNumY);
                            if (retrievedBlock == null)
                            {
                                retrievedBlock = new WorldspaceBlock()
                                {
                                    BlockNumberX = blockNumX,
                                    BlockNumberY = blockNumY,
                                    GroupType    = GroupTypeEnum.ExteriorCellBlock,
                                    LastModified = blockModified,
                                };
                                worldspaceCopy.SubCells.Add(retrievedBlock);
                            }
                            var subBlock = retrievedBlock.Items.FirstOrDefault(x => x.BlockNumberX == subBlockNumX && x.BlockNumberY == subBlockNumY);
                            if (subBlock == null)
                            {
                                subBlock = new WorldspaceSubBlock()
                                {
                                    BlockNumberX = subBlockNumX,
                                    BlockNumberY = subBlockNumY,
                                    GroupType    = GroupTypeEnum.ExteriorCellSubBlock,
                                    LastModified = readOnlySubBlock.LastModified,
                                };
                                retrievedBlock.Items.Add(subBlock);
                            }
                            var cell = subBlock.Items.FirstOrDefault(cell => cell.FormKey == formKey);
                            if (cell == null)
                            {
                                cell = copyCell.DeepCopy(CellCopyMask);
                                subBlock.Items.Add(cell);
                            }
                            return(cell);
                        };

                        if (LoquiRegistration.TryGetRegister(type, out var regis) &&
                            regis.ClassType == typeof(Cell))
                        {
                            yield return(new ModContext <IOblivionMod, 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);
                            }
                        }
                    }
                }
            }
        }
Exemple #16
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);
                            }
                        }
                    }
                }
            }
        }