views:

79

answers:

1

I have 2 touch enabled Canvas' in a Silverlight App. What I need to do is when a person Holds (presses and keeps pressing) both canvases at the same time increment a value on the screen once. This should happen for every "double" hold. I can do that fine using normal events but tried writing the same thing using RX and I am getting stuck.

Currently my code looks identical to the separate events approach (using global variables and global method) but I think there must be a better way to compose this. Can anyone suggest a better approach?

        var leftHold = Observable.FromEvent<TCanvas.HoldHandler, GestureHoldEventArgs>(
                h => new TCanvas.HoldHandler(h),
                h => HoldLeft.Hold += h,
                h => HoldLeft.Hold += h
            );

        var rightHold = Observable.FromEvent<TCanvas.HoldHandler, GestureHoldEventArgs>(
                h => new TCanvas.HoldHandler(h),
                h => HoldRight.Hold += h,
                h => HoldRight.Hold += h
            );

        var rightRelease = Observable.FromEvent<TCanvas.ReleaseHandler, EventArgs>(
                h => new TCanvas.ReleaseHandler(e => { }),
                h => HoldRight.Release += h,
                h => HoldRight.Release += h
            );


        var leftRelease = Observable.FromEvent<TCanvas.ReleaseHandler, EventArgs>(
                h => new TCanvas.ReleaseHandler(e => { }),
                h => HoldLeft.Release += h,
                h => HoldLeft.Release += h
            );

        leftHold.Subscribe(e =>
        {
            _leftHeld = true;
            DoCheck();
        });

        rightHold.Subscribe(e =>
            {
                _rightHeld = true;
                DoCheck();
            });

        rightRelease.Subscribe(e =>
        {
            _rightHeld = false;
            DoCheck();
        });


        leftRelease.Subscribe(e =>
        {
            _leftHeld = false;
            DoCheck();
        });

And the very basic DoCheck function looks like this....

    private void DoCheck()
    {
        if (_rightHeld && _leftHeld)
        {
            MyTextBox.Text = (Convert.ToInt32(MyTextBox.Text) + 1).ToString() ;
        }
    }

Hopefully you can see what I am trying to do. Each canvas has a hold and release event so when HoldLeft and HoldRight are both held do something until either HoldRight or HoldLeft are is released.

Any help would be appreciated.

+2  A: 

I believe I have solved my own problem.

Rather than the multiple subscribes I went for this.

        leftHold.Zip(rightHold, (a,b) => true)
            .TakeUntil(leftRelease.Amb(rightRelease))
            .Subscribe(_ => TextOutput.Text = (Convert.ToInt32(TextOutput.Text) + 1).ToString());

It appears to do what I want but I am open to further suggestions/improvements.

kouPhax
That's close to what I was going to recommend, really simple and nice.
Richard Hein