sdgfsdh
sdgfsdh

Reputation: 37045

How do I get the last known value of an IObservable?

Suppose I am building an image editor using Rx.Net. The user can manipulate the canvas using the mouse. The manipulation that is applied depends on the currently selected tool. For example, there might be a "draw" tool and an "erase" tool. Only one tool can be selected at a time.

I have three streams; one for mouse events; one for commands issued by clicking the mouse; and another for tool selections:

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

The commands stream depends on the other two: commands are issued when the user clicks the mouse and the command generated depends on the last selected tool. Note that a command should not be issued when the user changes tool, only when they click the mouse.

Now, I could store the last selected tool in a variable like this:

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

I can use selectedTool to build the commands stream:

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

However, this doesn't seem like the "reactive" way of doing things. Can I achieve this same logic using stream compositions?

I have looked at CombineLatest but it causes unwanted events to be generated when the user switches tool. I only want commands to be issued when the user clicks.

Upvotes: 5

Views: 912

Answers (1)

Enigmativity
Enigmativity

Reputation: 117027

It sounds like you need .Switch().

Try this code:

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

The extension method .Switch() takes, in this case, an IObservable<IObservable<ICommand>> and turns it into an IObservable<ICommand> by taking the latest observable produced by the outer observable and only producing values from it and disposing of previous ones.

Or, in more English terms, whenever the user clicks on a new tool you get a stream of mouse commands built using only the latest tool in one nice query.

Upvotes: 4

Related Questions