Unity 6.3
0 онлайн 78 гостей 3 в системе
Вход

QueryFilterOperator.AddHandler

Declaration

public Search.QueryFilterOperator AddHandler(Func<TFilterVariable,TFilterConstant,bool> handler);
public Search.QueryFilterOperator AddHandler(Func<TFilterVariable,TFilterConstant,stringComparison,bool> handler);

Параметры

Параметр Описание
обработчик Обратный вызов для обработки операции. Принимает TFilterVariable (значение, возвращаемое обработчиком фильтров, оно будет различаться для каждого элемента), TFilterConstant (правое значение оператора, которое является постоянным), и опцию StringComparison и возвращает логическое значение, указывающее, проходит ли фильтр или нет.

Возвращаемое значение

QueryFilterOperator Текущий QueryFilterOperator.

Описание

Добавление пользовательского обработчика оператора фильтра.

<TFilterVariable>: Тип левого операнда оператора. Это тип, возвращаемый обработчиком фильтров.

<TFilterConstant>: Тип правого операнда оператора.

Обработчик операторов — это функция, которая выполняется для определенного оператора (например, "=") с определенными требованиями к типу. Обработчик операторов выбирается по возвращаемому значению обработчика фильтров (см. AddFilter), которое идентифицируется при анализе запроса, и типу значения фильтра.

// Add a new modulo operator on this filter
var op = "%";
queryEngine.TryGetFilter("id", out var filter);
filter.AddOperator(op)
    .AddHandler((int ev, int fv) => ev % fv == 0)
    .AddHandler((float ev, float fv) => Math.Abs(ev % fv) < 0.00000001f);

Ниже пример, в котором мы переопределяем поведение оператора «=» для всех фильтров при работе со строками: вместо обычного сравнения выполняется поиск по регулярному выражению.

using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEditor.Search;
using UnityEngine;

static class Example_QueryEngine_RegexValue
{
    static QueryEngine<MyObjectType> SetupQueryEngine()
    {
        var queryEngine = new QueryEngine<MyObjectType>();
        queryEngine.AddFilter("id", myObj => myObj.id);
        queryEngine.AddFilter("n", myObj => myObj.name);
        queryEngine.SetSearchDataCallback(myObj => new[] { myObj.id.ToString(), myObj.name });

        // Override the = operators to do a regex match
        var op = queryEngine.GetOperator("=");
        op.AddHandler((string ev, string fv) => RegexMatch(fv, ev));

        return queryEngine;
    }

    static bool RegexMatch(string pattern, string source)
    {
        var match = Regex.Match(source, pattern);
        return match.Success;
    }

    static string[] s_Words = new[] { "bob", "cat", "car", "happy", "sad", "squirrel", "pizza", "dog", "over", "bing", "bong" };
    static IEnumerable<MyObjectType> GenerateData(int count)
    {
        for (var i = 0; i < count; ++i)
        {
            var wordCount = Random.Range(1, 6);
            var words = new List<string>();
            for (var j = 0; j < wordCount; ++j)
                words.Add(s_Words[Random.Range(0, s_Words.Length)]);

            var name = string.Join(" ", words);
            var id = $"{Random.Range(0, 1000)}-{s_Words[Random.Range(0, s_Words.Length)]}";
            yield return new MyObjectType() { id = id, name = name };
        }
    }

    static void FilterData(string text, QueryEngine<MyObjectType> queryEngine, IEnumerable<MyObjectType> data)
    {
        var query = queryEngine.ParseQuery(text);
        if (!query.valid)
        {
            foreach (var queryError in query.errors)
                Debug.LogFormat(LogType.Error, LogOption.NoStacktrace, null, $"Error parsing query at position {queryError.index}: {queryError.reason}");

            return;
        }

        var filteredData = query.Apply(data).ToList();
        var escapedText = text.Replace("{", "{{").Replace("}", "}}");
        Debug.LogFormat(LogType.Log, LogOption.NoStacktrace, null, $"Query \"{escapedText}\" yielded {filteredData.Count} result{(filteredData.Count > 1 ? "s" : "")}");
        foreach (var filteredObject in filteredData)
            Debug.LogFormat(LogType.Log, LogOption.NoStacktrace, null, filteredObject.ToString());
    }

    [MenuItem("Examples/QueryEngine/RegexValue")]
    public static void RunExample()
    {
        // Set up the query engine
        var queryEngine = SetupQueryEngine();

        var data = GenerateData(100);

        // Find all items with an id that match "^\\d{2}-c.+" (for example, "42-cat" or "99-car")
        // The quotes are required when using special characters like {}.
        FilterData("id=\"^\\d{2}-c.+\"", queryEngine, data);

        // Find all items with a name containing a duplicate (for example, "squirrel cat cat dog" or "pizza pizza dog")
        // The quotes are required when using special characters like {}.
        FilterData("n=(\\S+)\\s+(\\1)", queryEngine, data);
    }

    class MyObjectType
    {
        public string id { get; set; }
        public string name { get; set; } = string.Empty;

        public override string ToString()
        {
            return $"({id}, {name})";
        }
    }
}