Пример #1
0
        public static IEnumerable <SearchItem> Sum(SearchExpressionContext c)
        {
            var    skipCount = 0;
            string selector  = null;

            if (c.args[0].types.HasFlag(SearchExpressionType.Selector))
            {
                skipCount++;
                selector = c.args[0].innerText.ToString();
            }

            return(c.ForEachArgument(skipCount).AggregateResults(0d,
                                                                 (context, item, sum) => Aggregate(item, selector, sum, (d, _sum) => _sum + d),
                                                                 (context, sum) => EvaluatorUtils.CreateItem(sum, context.ResolveAlias("Sum"))));
        }
Пример #2
0
        public static IEnumerable <SearchItem> Min(SearchExpressionContext c)
        {
            var    skipCount = 0;
            string selector  = null;

            if (c.args[0].types.HasFlag(SearchExpressionType.Selector))
            {
                skipCount++;
                selector = c.args[0].innerText.ToString();
            }

            return(c.ForEachArgument(skipCount).AggregateResults(double.MaxValue,
                                                                 (context, item, min) => Aggregate(item, selector, min, (d, _min) => d < _min),
                                                                 (context, min) => EvaluatorUtils.CreateItem(min, context.ResolveAlias("Min"))));
        }
        public static bool Check(SearchExpression e, SearchExpressionContext c)
        {
            var result = e.Execute(c);
            var count  = result.Count();

            if (count == 0)
            {
                return(false);
            }
            if (count == 1)
            {
                return(IsTrue(result.First()));
            }
            return(true);
        }
Пример #4
0
        public static IEnumerable <SearchItem> Sort(SearchExpressionContext c)
        {
            var dataSet = c.args[0];

            bool sortAscend = true;

            if (c.args.Length == 3)
            {
                var sortAscendExpr = c.args[2];
                if (sortAscendExpr.IsKeyword(SearchExpressionKeyword.Desc))
                {
                    sortAscend = false;
                }
                else
                {
                    sortAscend = sortAscendExpr.GetBooleanValue(sortAscend);
                }
            }
            var sortComparer     = new SortItemComparer(c.args[1].innerText.ToString(), sortAscend);
            var sortedSet        = new List <SearchItem>();
            var selectExpression = dataSet.Apply(nameof(Select), c.args[1]);

            foreach (var r in selectExpression.Execute(c))
            {
                if (r != null)
                {
                    var insertAt = sortedSet.BinarySearch(r, sortComparer);
                    if (insertAt < 0)
                    {
                        insertAt = ~insertAt;
                    }
                    sortedSet.Insert(insertAt, r);
                }
                else
                {
                    yield return(null);
                }
            }

            int score = 0;

            foreach (var r in sortedSet)
            {
                r.score = score++;
                yield return(r);
            }
        }
Пример #5
0
        public static IEnumerable <SearchItem> Range(SearchExpressionContext c)
        {
            var range = new RangeDouble();
            var alias = c.ResolveAlias("Range");

            foreach (var sr in c.args[0].Execute(c))
            {
                if (GetRange(sr, ref range))
                {
                    break;
                }
                else
                {
                    yield return(null);
                }
            }

            if (!range.valid)
            {
                if (c.args.Length < 2)
                {
                    c.ThrowError("No expression to end range");
                }
                foreach (var sr in c.args[1].Execute(c))
                {
                    if (GetRange(sr, ref range))
                    {
                        break;
                    }
                    else
                    {
                        yield return(null);
                    }
                }
            }

            if (!range.valid)
            {
                c.ThrowError("Incomplete range");
            }

            for (double d = range.start.Value; d < range.end.Value; d += 1d)
            {
                yield return(EvaluatorUtils.CreateItem(d, alias));
            }
        }
        public static void ValidateExpressionArguments(SearchExpressionContext c, IEnumerable <Signature> signatures)
        {
            // First pass to get all valid argument number signatures (must do a ToList to separate the 2 passes)
            // Second pass to validate the argument types. The last error is kept (lowest number of arguments if no signature matches the number of argument, wrong type if there is at least one)
            var lastError     = "";
            var errorPosition = StringView.Null;

            if (signatures.Where(s => ValidateExpressionArgumentsCount(c.expression.evaluator.name, c.args, s, (msg, errorPos) => { lastError = msg; errorPosition = errorPos; })).ToList()
                .Any(s => ValidateExpressionArguments(c.expression.evaluator.name, c.args, s, (msg, errorPos) => { lastError = msg; errorPosition = errorPos; })))
            {
                return;
            }

            if (!errorPosition.valid)
            {
                errorPosition = c.expression.innerText;
            }
            c.ThrowError($"Error while evaluating arguments for {c.expression.evaluator.name}. {lastError}", errorPosition);
        }
Пример #7
0
        public static IEnumerable <SearchItem> If(SearchExpressionContext c)
        {
            if (c.args.Length < 2)
            {
                c.ThrowError("Not enough parameters for if");
            }

            bool cond = false;

            foreach (var item in c.args[0].Execute(c))
            {
                if (item == null)
                {
                    yield return(null);
                }
                else
                {
                    cond |= EvaluatorUtils.IsTrue(item);
                    if (!cond)
                    {
                        break;
                    }
                }
            }
            if (cond)
            {
                foreach (var item in c.args[1].Execute(c))
                {
                    yield return(item);
                }
            }
            else if (c.args.Length == 2)
            {
                // Nothing to do.
            }
            else
            {
                foreach (var item in c.args[2].Execute(c))
                {
                    yield return(item);
                }
            }
        }
        public static IEnumerable <SearchItem> Evaluate(SearchExpressionContext c, SearchExpression expression)
        {
            var concurrentList = new ConcurrentBag <SearchItem>();
            var yieldSignal    = new EventWaitHandle(false, EventResetMode.AutoReset);
            var task           = Task.Run(() =>
            {
                var enumerable = expression.Execute(c, SearchExpressionExecutionFlags.ThreadedEvaluation);
                foreach (var searchItem in enumerable)
                {
                    if (searchItem != null)
                    {
                        concurrentList.Add(searchItem);
                        yieldSignal.Set();
                    }
                }
            });

            while (!concurrentList.IsEmpty || !TaskHelper.IsTaskFinished(task))
            {
                if (!yieldSignal.WaitOne(0))
                {
                    if (concurrentList.IsEmpty)
                    {
                        Dispatcher.ProcessOne();
                    }
                    yield return(null);
                }
                while (concurrentList.TryTake(out var item))
                {
                    yield return(item);
                }
            }

            if (task.IsFaulted && task.Exception?.InnerException != null)
            {
                if (task.Exception.InnerException is SearchExpressionEvaluatorException sex)
                {
                    throw sex;
                }
                UnityEngine.Debug.LogException(task.Exception.InnerException);
            }
        }
Пример #9
0
        public static IEnumerable <SearchItem> GroupBy(SearchExpressionContext c)
        {
            string selector = null;

            if (c.args.Length > 1)
            {
                selector = c.args[1].innerText.ToString();
            }

            var outputValueFieldName = System.Guid.NewGuid().ToString("N");
            var dataSet = SelectorManager.SelectValues(c.search, c.args[0].Execute(c), selector, outputValueFieldName);

            foreach (var _group in dataSet.GroupBy(item => item.GetValue(outputValueFieldName)))
            {
                var group   = _group;
                var groupId = group.Key?.ToString() ?? $"group{++s_NextGroupId}";

                if (c.HasFlag(SearchExpressionExecutionFlags.Expand))
                {
                    var evaluator = new SearchExpressionEvaluator(groupId, _ => group, SearchExpressionEvaluationHints.Default);
                    var genExpr   = new SearchExpression(SearchExpressionType.Group,
                                                         groupId.GetStringView(), groupId.GetStringView(), (group.Key?.ToString() ?? groupId).GetStringView(),
                                                         evaluator);

                    yield return(EvaluatorUtils.CreateSearchExpressionItem(genExpr));
                }
                else
                {
                    SearchProvider groupProvider = null;
                    foreach (var item in group)
                    {
                        if (groupProvider == null)
                        {
                            groupProvider = SearchUtils.CreateGroupProvider(item.provider, groupId, s_NextGroupId);
                        }
                        item.provider = groupProvider;
                        yield return(item);
                    }
                }
            }
        }
Пример #10
0
        public static IEnumerable <SearchItem> Select(SearchExpressionContext c)
        {
            if (c.args.Length < 2)
            {
                c.ThrowError($"Invalid arguments");
            }

            // Select dataset
            var       dataset   = c.args[0].Execute(c);
            const int batchSize = 100;

            foreach (var batch in dataset.Batch(batchSize))
            {
                var results = batch;
                var sIt     = c.args.Skip(1).GetEnumerator();
                while (sIt.MoveNext())
                {
                    var selector = sIt.Current;
                    if (IsSelectorLiteral(selector))
                    {
                        var selectorName  = selector.innerText.ToString();
                        var selectorAlias = c.ResolveAlias(selector);
                        results = TaskEvaluatorManager.EvaluateMainThread(results, item =>
                        {
                            var selectedValue = SelectorManager.SelectValue(item, c.search, selectorName, out string suggestedSelectorName);
                            AddSelectedValue(item, selector.innerText.ToString(), selectorAlias ?? suggestedSelectorName, selectedValue);
                            return(item);
                        }, batchSize);
                    }
                    else
                    {
                        results = ProcessIterableSelector(c, results, selector);
                    }
                }

                foreach (var r in results)
                {
                    yield return(r);
                }
            }
        }
Пример #11
0
        public static IEnumerable <SearchItem> Sum(SearchExpressionContext c)
        {
            var    skipCount = 0;
            string selector  = null;

            if (c.args[0].types.HasFlag(SearchExpressionType.Selector))
            {
                skipCount++;
                selector = c.args[0].innerText.ToString();
            }

            foreach (var arg in c.args.Skip(skipCount))
            {
                var sum = 0d;
                foreach (var r in arg.Execute(c))
                {
                    sum = Aggregate(r, selector, sum, (d, _sum) => _sum + d);
                }
                yield return(SearchExpression.CreateItem(sum, c.ResolveAlias(arg, "Sum")));
            }
        }
Пример #12
0
        public static IEnumerable <SearchItem> Max(SearchExpressionContext c)
        {
            var    skipCount = 0;
            string selector  = null;

            if (c.args[0].types.HasFlag(SearchExpressionType.Selector))
            {
                skipCount++;
                selector = c.args[0].innerText.ToString();
            }

            foreach (var arg in c.args.Skip(skipCount))
            {
                double max = double.MinValue;
                foreach (var r in arg.Execute(c))
                {
                    max = Aggregate(r, selector, max, (d, _max) => d > _max);
                }
                yield return(SearchExpression.CreateItem(max, c.ResolveAlias(arg, "Max")));
            }
        }
Пример #13
0
        public static IEnumerable <SearchItem> Avg(SearchExpressionContext c)
        {
            var    skipCount = 0;
            string selector  = null;

            if (c.args[0].types.HasFlag(SearchExpressionType.Selector))
            {
                skipCount++;
                selector = c.args[0].innerText.ToString();
            }

            foreach (var arg in c.args.Skip(skipCount))
            {
                var avg = Average.Zero;
                foreach (var r in arg.Execute(c))
                {
                    avg = Aggregate(r, selector, avg, (d, _avg) => _avg.Add(d));
                }
                yield return(SearchExpression.CreateItem(avg.result, c.ResolveAlias(arg, "Average")));
            }
        }
Пример #14
0
        public static IEnumerable <SearchItem> Random(SearchExpressionContext c)
        {
            if (c.args.Length == 0)
            {
                c.ThrowError("No arguments");
            }

            foreach (var e in c.args)
            {
                if (e != null)
                {
                    foreach (var r in Random(c, e))
                    {
                        yield return(r);
                    }
                }
                else
                {
                    yield return(null);
                }
            }
        }
Пример #15
0
        static IEnumerable <SearchItem> Random(SearchExpressionContext c, SearchExpression e)
        {
            var set = new List <SearchItem>();

            foreach (var item in e.Execute(c))
            {
                if (item != null)
                {
                    set.Add(item);
                }
                yield return(null); // Wait until we have all results.
            }

            var randomItem = Random(set);

            // Rename random item label if an alias is defined.
            if (c.ResolveAlias(e) is string alias)
            {
                randomItem.label = alias;
            }
            yield return(randomItem);
        }
Пример #16
0
        public static IEnumerable <SearchItem> Map(SearchExpressionContext c)
        {
            var mapSet   = c.args[0].Execute(c);
            var mapQuery = c.args[1];

            foreach (var m in mapSet)
            {
                if (m == null)
                {
                    yield return(null);
                }
                else
                {
                    using (c.runtime.Push(m))
                    {
                        foreach (var e in mapQuery.Execute(c))
                        {
                            yield return(e);
                        }
                    }
                }
            }
        }
Пример #17
0
        public static IEnumerable <SearchItem> IsTrue(SearchExpressionContext c)
        {
            foreach (var e in c.args)
            {
                bool isTrue = false;
                foreach (var item in e.Execute(c))
                {
                    if (item == null)
                    {
                        yield return(null);
                    }
                    else
                    {
                        isTrue |= EvaluatorUtils.IsTrue(item);
                        if (!isTrue)
                        {
                            break;
                        }
                    }
                }

                yield return(EvaluatorUtils.CreateItem(isTrue, c.ResolveAlias(e, "IsTrue")));
            }
        }
Пример #18
0
        internal IEnumerable <SearchItem> Execute(SearchExpressionContext c, SearchExpressionExecutionFlags executionFlags)
        {
            if (!evaluator.valid || evaluator.execute == null)
            {
                c.ThrowError("Invalid expression evaluator");
            }
            try
            {
                if (!evaluator.hints.HasFlag(SearchExpressionEvaluationHints.ThreadNotSupported))
                {
                    return(Evaluate(c, executionFlags));
                }

                // We cannot only return the IEnumerable of the evaluator, as the iteration itself needs to be
                // done on the main thread. If we return the IEnumerable itself, we will unroll the items and call the evaluator
                // in the evaluation thread.
                return(TaskEvaluatorManager.EvaluateMainThreadUnroll(() => Evaluate(c, executionFlags)));
            }
            catch (SearchExpressionEvaluatorException ex)
            {
                ExceptionDispatchInfo.Capture(ex).Throw();
                return(null); // To stop visual studio complaining about not all code path return a value
            }
        }
Пример #19
0
        public static IEnumerable <SearchItem> Union(SearchExpressionContext c)
        {
            if (c.args == null || c.args.Length == 0)
            {
                c.ThrowError("Nothing to merge");
            }

            var set = new HashSet <int>();

            foreach (var e in c.args)
            {
                foreach (var item in e.Execute(c))
                {
                    if (item == null)
                    {
                        yield return(null);
                    }
                    else if (set.Add(item.value.GetHashCode()))
                    {
                        yield return(item);
                    }
                }
            }
        }
Пример #20
0
        public static IEnumerable <SearchItem> Selection(SearchExpressionContext c)
        {
            var selection = TaskEvaluatorManager.EvaluateMainThread(() =>
            {
                var instanceIds = UnityEditor.Selection.instanceIDs;
                return(instanceIds.Select(id =>
                {
                    string assetPath = AssetDatabase.GetAssetPath(id);
                    return new SelectionResult(id, assetPath);
                }).ToList());
            });

            foreach (var selectionResult in selection)
            {
                if (string.IsNullOrEmpty(selectionResult.assetPath))
                {
                    yield return(SearchExpression.CreateItem(selectionResult.instanceId, c.ResolveAlias("Selection")));
                }
                else
                {
                    yield return(SearchExpression.CreateItem(selectionResult.assetPath, c.ResolveAlias("Selection")));
                }
            }
        }
 public static IEnumerable <SearchItem> Constant(SearchExpressionContext c)
 {
     if (c.expression.types.HasAny(SearchExpressionType.Function))
     {
         using (c.runtime.Push(c.args[0], c.args.Skip(1)))
             yield return(Constant(c.runtime.current).First());
     }
     else if (c.expression.types.HasAny(SearchExpressionType.Number))
     {
         yield return(SearchExpression.CreateItem(c.expression.GetNumberValue(), c.expression.alias.ToString()));
     }
     else if (c.expression.types.HasAny(SearchExpressionType.Text | SearchExpressionType.Keyword))
     {
         yield return(SearchExpression.CreateItem(c.expression.innerText.ToString(), c.expression.alias.ToString()));
     }
     else if (c.expression.types.HasAny(SearchExpressionType.Boolean))
     {
         yield return(SearchExpression.CreateItem(c.expression.GetBooleanValue(), c.expression.alias.ToString()));
     }
     else
     {
         c.ThrowError($"Invalid constant expression");
     }
 }
Пример #22
0
 ArgumentEnumerable(SearchExpressionContext c)
 {
     context = c;
 }
 public static IEnumerable <SearchItem> Set(SearchExpressionContext c)
 {
     return(c.args.SelectMany(e => e.Execute(c)));
 }
Пример #24
0
        public override IEnumerator <SearchItem> GetEnumerator()
        {
            foreach (var argument in m_ArgumentEnumerable)
            {
                var results = argument.Execute(context);
                if (results == null)
                {
                    yield break;
                }

                bool started = false;
                SearchExpressionContext argContext = default;
                foreach (var searchItem in results)
                {
                    if (m_SkipNullResult && searchItem == null)
                    {
                        yield return(null);

                        continue;
                    }

                    if (!started)
                    {
                        // We need to start yielding result in order for the evaluation context to be valid.
                        if (!context.valid)
                        {
                            context.ThrowError("Invalid argument context");
                        }
                        argContext = context.runtime.current;
                        OnAggregateStart(argContext);
                        started = true;
                    }

                    OnAggregateResult(argContext, searchItem);
                    yield return(null);
                }

                if (m_OnAggregateToSearchItem != null)
                {
                    yield return(m_OnAggregateToSearchItem(argContext, m_Aggregator));

                    continue;
                }

                if (m_OnAggregateToSearchItems != null)
                {
                    foreach (var searchItem in m_OnAggregateToSearchItems(argContext, m_Aggregator))
                    {
                        yield return(searchItem);
                    }
                    continue;
                }

                if (m_Aggregator is IEnumerable <SearchItem> searchItemAggregator)
                {
                    foreach (var searchItem in searchItemAggregator)
                    {
                        yield return(searchItem);
                    }
                }
            }
        }
Пример #25
0
 protected override void OnAggregateStart(SearchExpressionContext currentContext)
 {
     m_OnAggregateStart?.Invoke(currentContext, m_Aggregator);
 }
 public static IEnumerable <SearchItem> ToBoolean(SearchExpressionContext c)
 {
     return(c.args.SelectMany(e => e.Execute(c)).Select(item => SearchExpression.CreateItem(SearchExpression.IsTrue(item))));
 }
Пример #27
0
        public static IEnumerable <SearchItem> SceneName(SearchExpressionContext c)
        {
            var desc = TaskEvaluatorManager.EvaluateMainThread(() => EditorApplication.GetApplicationTitleDescriptor());

            yield return(SearchExpression.CreateItem(desc.activeSceneName ?? string.Empty, c.ResolveAlias("SceneName")));
        }
Пример #28
0
        public static IEnumerable <SearchItem> DataPath(SearchExpressionContext c)
        {
            var dataPath = TaskEvaluatorManager.EvaluateMainThread(() => Application.dataPath);

            yield return(SearchExpression.CreateItem(dataPath ?? string.Empty, c.ResolveAlias("DataPath")));
        }
Пример #29
0
 static void DefaultArgumentIteration(SearchExpressionContext c, SearchExpression e)
 {
 }
Пример #30
0
 protected override void OnAggregateResult(SearchExpressionContext currentContext, SearchItem currentItem)
 {
     m_Aggregator = m_OnAggregateResult(currentContext, currentItem, m_Aggregator);
 }