System.Reactive puzzle
After working on the Reactive Framework with Erik, Wes and the rest of our team for over a year, it is great to see that the word about System.Reactive is out (as described here, here, here and here).
I thought it might be fun to post a little puzzle challenge showing the power of the Reactive Framework. I asked the same question to my team members a while back and everyone got a different solution, from very declarative to very imperative.
here is the puzzle:
A while back, if found a jQuery implementation of tripple click of course this can be done very elegantly in Rx.
The first question is: can you implement this using Rx (for the Silverlight Button)?
the second question is: can you generalize it like this:
public
static IObservable<RoutedEventArgs> GetMultiClickScan(this ButtonBase button, int count, int multiClickSpeedInMilliSeconds)
The third and final question is: Can you implement this without timers?
To give you a head start, here is the code to get an IObservable<RoutedEventArgs>that fires for each click:
var
click = Observable.FromEvent<RoutedEventHandler, RoutedEventArgs>
(i => i.Invoke, i => button.Click += i , i => button.Click -= i).Select(e => e.EventArgs);
Rules:
-feel free to ask questions in the comments if you're stuck, can't promise I'll be able to answer you immediately or give everything away though :)
-feel free to post answers in the comments, if you don't want to be spoiled, don't read the comments :)
-No prizes, only eternal satisfaction with an awesome implementation can be won here :)
I'll post some of our teams answers to this puzzle in a couple of days..
Comments
- Anonymous
August 12, 2009
amazing Rx, hier are my first solutions
- solution with Scan return click .Scan(new { e = new RoutedEventArgs(), t = DateTime.Now, c = 0 }, (a, e) => new { e, t = DateTime.Now, c = ((DateTime.Now - a.t).TotalMilliseconds < multiClickSpeedInMilliSeconds) ? (a.c + 1) : 1 }) .Skip(1) .Where(a => a.c % count == 0) .Select(a => a.e);
- solution without Scan return click .Skip(count) .Zip(click.Select(_ => DateTime.Now), (e, t) => new { e, t = DateTime.Now - t }) .Where(e => e.t.TotalMilliseconds < multiClickSpeedInMilliSeconds) .Select(e => e.e)
Anonymous
August 12, 2009
Jeffrey: Spoke too soon. :-) Your solutions work - and very well too. Very nice! Wish I'd thought of them :-).Anonymous
November 18, 2009
My solution: http://snipt.org/pYj