예제 #1
0
        public bool CanPerform(Type target, Operation restrictTo = Operation.All)
        {
            Operation oldAllowedOp = this.allowedOp;

            this.allowedOp = oldAllowedOp & restrictTo;

            // Convert ContentRef requests to their respective Resource-requests
            target = ResTypeFromRefType(target);

            if (this.checkedTypes.Contains(target))
            {
                this.allowedOp = oldAllowedOp;
                return(false);
            }
            this.curComplexity++;
            this.checkedTypes.Add(target);

            bool result = false;

            if (!result && this.data.GetDataPresent(target))
            {
                result = true;
            }
            if (!result && this.data.GetDataPresent(target.MakeArrayType()))
            {
                result = true;
            }
            if (!result && this.data.ContainsContentRefs(target))
            {
                result = true;
            }
            if (!result && this.data.ContainsComponentRefs(target))
            {
                result = true;
            }
            if (!result)
            {
                result = CorePluginRegistry.GetDataConverters(target).Any(s => !this.usedConverters.Contains(s) && s.CanConvertFrom(this));
            }

            if (result || this.allowedOp != oldAllowedOp)
            {
                this.checkedTypes.Remove(target);
            }
            this.maxComplexity = Math.Max(this.maxComplexity, this.curComplexity);
            this.curComplexity--;

            this.allowedOp = oldAllowedOp;
            return(result);
        }
예제 #2
0
        public IEnumerable <object> Perform(Type target, Operation restrictTo = Operation.All)
        {
            Operation oldAllowedOp = this.allowedOp;

            this.allowedOp = oldAllowedOp & restrictTo;

            // Convert ContentRef requests to their respective Resource-requests
            Type originalType = target;

            target = ResTypeFromRefType(target);

            //Log.Editor.Write("Convert to {0}", target.Name);
            bool fittingDataFound = false;

            // Check if there already is fitting data available
            IEnumerable <object> fittingData = null;

            if (fittingData == null)
            {
                // Single object
                if (this.data.GetDataPresent(target))
                {
                    fittingData = new[] { this.data.GetData(target) }
                }
                ;
            }
            if (fittingData == null)
            {
                // Object array
                Type arrType = target.MakeArrayType();
                if (this.data.GetDataPresent(arrType))
                {
                    fittingData = this.data.GetData(arrType) as IEnumerable <object>;
                }
            }
            if (fittingData == null)
            {
                // ComponentRefs
                if (this.data.ContainsComponentRefs(target))
                {
                    fittingData = this.data.GetComponentRefs(target);
                }
            }
            if (fittingData == null)
            {
                // ContentRefs
                if (this.data.ContainsContentRefs(target))
                {
                    fittingData = this.data.GetContentRefs(target).Res();
                }
            }

            // If something fitting was found, directly add it to the operation results
            if (fittingData != null)
            {
                fittingDataFound = true;
                foreach (object obj in fittingData)
                {
                    this.AddResult(obj);
                }
            }

            // No result yet? Search suitable converters
            if (!fittingDataFound)
            {
                var converterQuery = CorePluginRegistry.GetDataConverters(target);
                List <ConvComplexityEntry> converters = new List <ConvComplexityEntry>();
                foreach (var c in converterQuery)
                {
                    this.maxComplexity = 0;
                    if (this.usedConverters.Contains(c))
                    {
                        continue;
                    }
                    if (!c.CanConvertFrom(this))
                    {
                        continue;
                    }
                    converters.Add(new ConvComplexityEntry(c, this.maxComplexity));
                }

                // Perform conversion
                converters.StableSort((c1, c2) => (c2.Converter.Priority - c1.Converter.Priority) * 10000 + (c1.Complexity - c2.Complexity));
                foreach (var c in converters)
                {
                    //Log.Editor.Write("using {0}", s.GetType().Name);
                    //Log.Editor.PushIndent();
                    //Log.Editor.Write("before: {0}", this.Result.ToString(o => string.Format("{0} {1}", o.GetType().Name, o), ", "));
                    this.usedConverters.Add(c.Converter);
                    bool handled = c.Converter.Convert(this);
                    this.usedConverters.Remove(c.Converter);
                    //Log.Editor.Write("after: {0}", this.Result.ToString(o => string.Format("{0} {1}", o.GetType().Name, o), ", "));
                    //Log.Editor.PopIndent();
                    if (handled)
                    {
                        break;
                    }
                }
            }

            IEnumerable <object> returnValue = this.result;

            // Convert back to Resource requests
            if (typeof(IContentRef).IsAssignableFrom(originalType))
            {
                returnValue = result.OfType <Resource>().Select(r => r.GetContentRef());
            }

            returnValue = returnValue ?? (IEnumerable <object>)Array.CreateInstance(originalType, 0);
            returnValue = returnValue.Where(originalType.IsInstanceOfType);

            this.allowedOp = oldAllowedOp;
            return(returnValue);
        }