I'm currently working on an application that combines many streams of data through equations. What I'd like to be able to do is something like:
var result = (stream1 + stream2) / stream3 + stream4 * 2;
Where result
updates whenever any of the streams update. At the moment the only way I can express this in Rx is as:
var result = stream1.CombineLatest(stream2, (x,y) => x+y)
.CombineLatest(stream3, (x,y) => x / y)
.CombineLatest(stream4, (x,y) => x + y*2);
Which isn't nearly as clear.
My current idea is as follows:
Public class ArithmeticStream : IObservable<double>
{
public static ArithmeticStream operator +(ArithmeticStream xx, ArithmeticStream yy)
{
return Observable.CombineLatest(xx,yy, (x,y) => x + y);
}
...
}
The problem is that CombineLatest returns an IObservable<double>
instead of an ArithmeticStream.
Two possible questions:
How can I transparently convert an IObservable<double>
into an ArithmeticStream?
Is there an alternative route that will get me the result I want?
Hmm...I think you could do it DSL-style relatively easy (no fiddling about with operators):
public static class Ext
{
public static IObservable<double> Const(this double constant)
{
return Observable.Return(constant);
}
public static IObservable<double> Plus(this IObservable<double> left, IObservable<double> right)
{
return left.CombineLatest(right, (l,r) => l + r);
}
public static IObservable<double> Minus(this IObservable<double> left, IObservable<double> right)
{
return left.CombineLatest(right, (l,r) => l - r);
}
public static IObservable<double> Times(this IObservable<double> left, IObservable<double> right)
{
return left.CombineLatest(right, (l,r) => l * r);
}
public static IObservable<double> Over(this IObservable<double> left, IObservable<double> right)
{
return left.CombineLatest(right,(l,r) => l / r);
}
}
So your query would be:
var result = (s1.Plus(s2)).Over(s3)
.Plus(s4)
.Times(2.0.Const());
Or, for a very chatty variant:
var verboseResult =
(s1.Do(Console.WriteLine).Plus(s2.Do(Console.WriteLine)))
.Over(s3.Do(Console.WriteLine))
.Plus(s4.Do(Console.WriteLine))
.Times(2.0.Const())
.Do(x => Console.WriteLine("(s1 + s2) / s3 + s4 * 2 = " + x));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With