Rx Workshop: Reactive Coincidence

Play Rx Workshop: Reactive Coincidence

The Discussion

  • User profile image

    awsome stuff.. Smiley


  • User profile image

    Am I allowed to post the solution of the challange?


  • User profile image

    Here is what I came up with

                var query = Observable.Join(
                    _ => mouseUp, 
                    _ => Observable.Empty<Unit>(), 
                    (_, r) => r)
                    .Publish(evt => evt.Zip(evt.Skip(1), 
                        (previous, current) => Subtract(current, previous)));

    I am having difficulty translating this into query comprehension syntax.  Anyone figure that out?  Thanks.

  • User profile image

    Alright here is a working query comprehension version

    var query = from start in mouseDown
                join move in mouseMove
                on mouseUp equals Observable.Empty<Unit>() into moveGroup
                let drag = moveGroup.Zip(moveGroup.Skip(1),
                    (prev, curr) => Subtract(curr, prev))
                from delta in drag
                select delta;

    Still curious if this could be cleaner.  Thanks.


  • User profile image

    Here is my solution:

    var query = Observable.Join(
    _ => mouseUp,
    m => Observable.Empty<Unit>(),
    (_, r) => Subtract(r.Last(),r.First()));

  • User profile image

    I think my solution is close to the optimum!?

    But I had to modify the subscibtion from deltas to absolute points.

       var query = mouseDown.Join(mouseMove, l => mouseUp, r => Observable.Empty<Point>(),(l,r)=> Subtract(r,l));
                    Canvas.SetLeft(image, pos.X);
                    Canvas.SetTop(image, pos.Y);

  • User profile image

    I notied there is a bug when releasing the mouse button from outside of the window.  Here is a fix that will merge mouseUp and mouseLeave to accomplish the task.  What is normal UI guidance for drag and drop when going outside the window?  Thanks.

                var mouseLeave = from evt in Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>(h => MouseLeave += h, h => MouseLeave -= h)
                                 select evt.EventArgs.GetPosition(this);
                var query = from start in mouseDown
                            join move in mouseMove.Buffer(2)
                            on mouseUp.Merge(mouseLeave) equals Observable.Empty<Unit>()
                            select Subtract(move.Last(), move.First());

  • User profile image

    Hey what happened to the challenges.  They are showing up 404.  I was trying to dowload again.  Thanks.

  • User profile image

    Here is my (edited) suggestion:

    .Buffer(2, 1)
    .Select(b => b[1] - b[0])
    .Window(mouseDown, _ => mouseUp)

    The Subtract method is not needed.

  • User profile image
    What I ended up with in query and fluent:
                var query = from down in mouseDown
                            join delta in
                                from move in mouseMove.Buffer(2)
                                select Subtract(move.Last(), move.First())
                                on mouseUp equals Observable.Empty<Unit>() 
                            select delta;
    //            var query = Observable.Join(
    //                mouseDown,
    //                mouseMove.Buffer(2).Select(b => Subtract(b.Last(), b.First())),
    //                _ => mouseUp,
    //                _ => Observable.Empty<EventArgs>(),
    //                (_, r) => r);
    ...though interested if anyone came up with a way to buffer then collapse after the join (I battered my head against that approach for a while before going for this).
    Also ended up with the same sln as BennyG first time after missreading the subscribe lambda...

  • User profile image

    Here is a solution that uses the Scan method:

    var query = mouseDown.Join(
    .Scan(new { Prev = new Point(), Delta = new Point() },
    (current, next) => new { Prev = next, Delta = Subtract(next, current.Prev) })
    .Select(x => x.Delta),
    down => mouseUp,
    delta => Observable.Empty<Unit>(),
    (down, delta) => delta);

  • User profile image

    reopening comments

  • User profile image

    My solution was based on a similar handling by SelectMany().

    private void DragAndDrop()
                var mousedown = Observable.FromEventPattern<MouseButtonEventHandler, MouseButtonEventArgs>(h => image.MouseDown += h,
                                                                                                           h => image.MouseDown -= h)
                                          .Select(e => e.EventArgs.GetPosition(image));
                var mousemove = Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>(h => image.MouseMove += h,
                                                                                               h => image.MouseMove -= h)
                                          .Select(e => e.EventArgs.GetPosition(canvas));
                var mouseup = Observable.FromEventPattern<MouseButtonEventHandler, MouseButtonEventArgs>(h => image.MouseUp += h,
                                                                                                         h => image.MouseUp -= h)
                                        .Select(e => e.EventArgs.GetPosition(image));
                var query = Observable.Join( mousedown
                                            ,p1 => mouseup
                                            ,p2 => Observable.Empty<Point>()
                                            ,(p1, p2) => new { X = p2.X - p1.X, Y = p2.Y - p1.Y }
                                     .Subscribe(p => { Canvas.SetLeft(image, p.X); Canvas.SetTop(image, p.Y); });

Add Your 2 Cents