示例#1
0
        /// <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 !;
        /// <summary>
        /// Constructs a LoadOrderLinkCache around a target load order
        /// </summary>
        /// <param name="loadOrder">LoadOrder to resolve against when linking</param>
        public ImmutableLoadOrderLinkCache(IEnumerable <TModGetter> loadOrder)
        {
            this._listedOrder   = loadOrder.ToList();
            this._priorityOrder = _listedOrder.Reverse().ToList();
            var firstMod = _listedOrder.FirstOrDefault();

            this._hasAny = firstMod != null;
            // ToDo
            // Upgrade to bounce off ModInstantiator systems
            this._gameCategory   = firstMod?.GameRelease.ToCategory() ?? GameCategory.Oblivion;
            this._linkInterfaces = LinkInterfaceMapping.InterfaceToObjectTypes(_gameCategory);
        }
示例#3
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);
 }