Как получить последнее известное значение IObservable?

Предположим, я создаю графический редактор с использованием Rx.Net. Пользователь может манипулировать холстом с помощью мыши. Применяемые манипуляции зависят от выбранного в данный момент инструмента. Например, может быть инструмент "рисовать" и "стирать". Только один инструмент может быть выбран за один раз.

У меня есть три потока; один для событий мыши; один для команд, выдаваемых щелчком мыши; и еще один для выбора инструментов:

IObservable<ITool> toolSelection;
IObservalbe<MouseState> mouse;
IObservable<ICommand> commands;

commands Поток зависит от двух других: команды выдаются, когда пользователь щелкает мышью, а сгенерированная команда зависит от последнего выбранного инструмента. Обратите внимание, что команда не должна вводиться, когда пользователь меняет инструмент, только когда он щелкает мышью.

Теперь я могу сохранить последний выбранный инструмент в переменной следующим образом:

var selectedTool = defaultTool;
toolSelection.Subscribe(x => selectedTool = x);

я могу использовать selectedTool построить commands поток:

var commands = mouse.Select(x => selectedTool.CreateCommand(x));

Тем не менее, это не похоже на "реактивный" способ ведения дел. Могу ли я достичь этой же логики с помощью потоковых композиций?

Я смотрел на CombineLatest но это вызывает нежелательные события, которые генерируются, когда пользователь переключает инструмент. Я хочу, чтобы команды выполнялись только тогда, когда пользователь нажимает.

1 ответ

Решение

Похоже, вам нужно .Switch(),

Попробуйте этот код:

IObservable<ICommand> commands =
    toolSelection
        .Select(t => mouse.Select(m => t.CreateCommand(m)))
        .Switch();

Метод расширения .Switch() принимает, в этом случае, IObservable<IObservable<ICommand>> и превращает его в IObservable<ICommand> беря самую последнюю наблюдаемую, произведенную внешней наблюдаемой и производя из нее только ценности, и избавляясь от предыдущих.

Или, если говорить более английским языком, всякий раз, когда пользователь нажимает на новый инструмент, вы получаете поток команд мыши, созданный с использованием только самого последнего инструмента в одном интересном запросе.

Другие вопросы по тегам