Ejemplo n.º 1
0
        /// <summary>
        /// Find the closest template in the base cache to the input template.
        /// </summary>
        private CachedTag FindClosestTemplate(CachedTag sourceRmt2Tag, RenderMethodTemplate sourceRmt2)
        {
            Debug.Assert(IsInitialized);

            Rmt2Descriptor sourceRmt2Desc;

            if (!Rmt2Descriptor.TryParse(sourceRmt2Tag.Name, out sourceRmt2Desc))
            {
                throw new ArgumentException($"Invalid rmt2 name '{sourceRmt2Tag.Name}'", nameof(sourceRmt2Tag));
            }

            var relevantRmt2s = new List <Rmt2Pairing>();

            foreach (var rmt2Tag in BaseCache.TagCache.NonNull().Where(tag => tag.IsInGroup("rmt2")))
            {
                Rmt2Descriptor destRmt2Desc;
                if (!Rmt2Descriptor.TryParse(rmt2Tag.Name, out destRmt2Desc))
                {
                    continue;
                }

                // ignore ms30 templates if desired
                if (!UseMs30 && destRmt2Desc.IsMs30)
                {
                    continue;
                }

                // ignore templates that are not of the same type
                if (destRmt2Desc.Type != sourceRmt2Desc.Type)
                {
                    continue;
                }

                // match the options from the rmt2 tag names
                int commonOptions = 0;
                for (int i = 0; i < sourceRmt2Desc.Options.Length; i++)
                {
                    if (sourceRmt2Desc.Options[i] == destRmt2Desc.Options[i])
                    {
                        commonOptions++;
                    }
                }

                // if we found an exact match, return it
                if (commonOptions == sourceRmt2Desc.Options.Length)
                {
                    return(rmt2Tag);
                }

                // add it to the list to be considered
                relevantRmt2s.Add(new Rmt2Pairing()
                {
                    CommonOptions = commonOptions,
                    DestTag       = rmt2Tag,
                    SourceTag     = sourceRmt2Tag
                });
            }

            // if we've reached here, we haven't found an extract match.
            // now we need to consider other factors such as which options they have, which parameters are missing etc..
            // whatever can be used to narrow it down.
            foreach (var pairing in relevantRmt2s)
            {
                var rmt2 = GetTemplate(pairing.DestTag);
                pairing.RealParams    = MatchParameterBlocks(sourceRmt2.RealParameterNames, rmt2.RealParameterNames);
                pairing.IntParams     = MatchParameterBlocks(sourceRmt2.IntegerParameterNames, rmt2.IntegerParameterNames);
                pairing.BoolParams    = MatchParameterBlocks(sourceRmt2.BooleanParameterNames, rmt2.BooleanParameterNames);
                pairing.TextureParams = MatchParameterBlocks(sourceRmt2.TextureParameterNames, rmt2.TextureParameterNames);
            }

            // finally order by some criteria
            var ordered = relevantRmt2s
                          .OrderBy(x => x.CommonOptions);
            //.ThenByDescending(x => x.MissingFromDest);


            // return the best rmt2 or the default if one could not be found (only when a template type is not in the base cache)
            var bestRmt2 = ordered.LastOrDefault()?.DestTag;

            if (bestRmt2 == null)
            {
                return(BaseCache.GetTag(DefaultTemplate));
            }

            return(bestRmt2);
        }