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); }
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); }