LINQ and Related Topics

Rx for WP7 on Telerik Wednesdays Webcast

windowsphonewednesdaysFor anyone who hasn’t had the opportunity to attend one of my in person presentations, or are frustrated by the audio quality of my MIX recording, join me on Wednesday, May 25 at 11:00 EST when I discuss using the Reactive Extensions on the Windows Phone as part of Telerik’s new Windows Phone 7 Wednesdays video series.

Here’s the session details:

Becoming an Rx Pusher on your Windows Phone
with Jim Wooley on May 25th at 11am EST
https://www1.gotomeeting.com/register/419991849

The Reactive Extensions are a set of libraries that shipped on the Windows Phone and allow you to compose asynchronous operations over observable collections. Learn how to use this amazing framework for turning pull-oriented apps into push-oriented apps. Find out why it is a mind-bending technology and how it improves your ability to make async calls on the Windows Phone 7 platform.

Update: This webcast was recorded and the screen cast is available on Telerik TV.

Posted on 5/11/2011 1:13:00 PM - Comments(0)
Categories: WP7 Rx

Geek Give TechEd Style

TechEd2011 - GeekGive is cleaning up!

Join Matt and I on Saturday, May 14th to help GeekGive make a difference in our local Atlanta community. We’re going to be picking up trash on streets and cleaning up a park. Not just any park, we’re going to be helping the Peopletown Revitalization Corporation to clean Atlanta’s first public beltline park on the day of its dedication ceremony!

Registration for volunteers is now open and we badly need volunteers!

Register at teched2011 - GeekGive

Posted on 5/6/2011 8:34:00 AM - Comments(0)
Categories: Code Camp

Rx Mock Accelerometer using Observable.GenerateWithTime

When people ask about resources to learn how to use Rx on the Windows Phone, I often point them to the How to guides, including the How to: Use Reactive Extensions to Emulate and Filter Accelerometer Data for Windows Phone. Unfortunately, I have a problem with the underlying implementation of the emulation method which returns values through an iterator (yield) and IEnumerable<T> and then cast the IEnumerable to IObservable. As I pointed out in a MSDN forum post, It would be better to recommend returning just an IObservable natively and replace the yield with OnNext(T).

In reviewing this for my MIX 2011 presentation, I decided to take another look at the implementation and found a much better solution. When mocking the accelerometer, we essentially want to issue new values at a regular interval. To start, let’s take a look at the mocking method from the original How to guide:


static IEnumerable<Vector3> EmulateAccelerometerReading()
{
    // Create a random number generator
    Random random = new Random();

    // Loop indefinitely
    for (double theta = 0; ; theta+=.1 )
    {
        // Generate a Vector3 in which the values of each axes slowly drift between -1 and 1 and
        // then normalize the vector
        Vector3 reading = new Vector3((float)Math.Sin(theta), (float)Math.Cos(theta * 1.1), (float)Math.Sin(theta * .7));
        reading.Normalize();
                
        // At random intervals, generate a random spike in the data
        if (random.NextDouble() > .95)
        {
            reading = new Vector3((float)(random.NextDouble() * 3.0 - 1.5),
             (float)(random.NextDouble() * 3.0 - 1.5),
             (float)(random.NextDouble() * 3.0 - 1.5));

        }

        // return the vector and then sleep
        yield return reading;
        Thread.Sleep(100);
    }
}

 

Essentially, this implementation sets up an infinite loop and issues new values using the yield return statement and then sleeps 100 milliseconds. As I wrote last year in the MSDN forum, a better option is to return an IObservable and use OnNext rather than yield return as follows:


public static IObservable<Vector3> GetEmulator()
{
     var obs = Observable.Create<Vector3>(subscriber =>
                {
                    Random rnd = new Random();
                    for (double theta = 0; ; theta += .1)
                    {
                        Vector3 reading = new Vector3(
                            (float)Math.Sin(theta),
                            (float)Math.Cos(theta * 1.1),
                            (float)Math.Sin(theta * .7));
                        reading.Normalize();
                        if (rnd.NextDouble() > .95)
                        {
                            reading = new Vector3(
                                (float)(rnd.NextDouble() * 3.0 - 1.5),
                                (float)(rnd.NextDouble() * 3.0 - 1.5),
                                (float)(rnd.NextDouble() * 3.0 - 1.5));
                        }
                        // return the vector and sleep before repeating
                        Thread.Sleep(100);
                        subscriber.OnNext(reading);
                    }
                });
      return obs;
}

In preparation for Mix, I decided to revisit this and replace the looping implementation with the native Observable.GenerateWithTime method as follows:


public static IObservable<Vector3> GetAccelerometer()
{
    var obs = Observable.GenerateWithTime<double, Vector3>(
                initialState: 0, 
                condition: _ => true,
                resultSelector: theta => new Vector3((float)Math.Sin(theta),
                                        (float)Math.Cos(theta * 1.1),
                                        (float)Math.Sin(theta * .7)),
                timeSelector: _ => TimeSpan.FromMilliseconds(100),
                iterate: theta => theta + .1)
                .ObserveOnDispatcher();

     return obs;
 }

Notice now we no longer have a loop in our code or a timer sleep. Those pieces are essentially handled for us inside the implementation of the GenerateWithTime. Let’s break this object instantiation down a bit to know what’s going on.

Observable.GenerateWithTime takes two generic type arguments, the double represents the type which we will increment as new values are generated. This allows us to set range values and incrementors similar to how we setup the “for” loop and potentially escape from the loop as necessary. The second generic type indicates the type of values that the observable will create. In this case, we return Vector3 types from the phone’s XNA libraries.

The first input parameter (initialState) sets the starting value of the for loop.

The condition parameter takes a lambda expression allowing us to evaluate if we should continue issuing values. In this case, we’ll keep issuing values as long as something is subscribed to us, thus we return “true”.

The resultSelector parameter takes a input value which is the current value of our iteration and returns some new value based on that input value. Here is where we generate our new vector value based on the current value.

The timeSelector parameter allows us to specify how often we want to issue new values. This would be the same as our sleep value from the original examples.

The iterate parameter allows us to increment our looping value. This is the same as the final portion of the original “for” loop declaration.

Before we return the observable, I add a method to ObserveOnDispatcher to make sure that we delegate back to the dispatcher thread. If we didn’t do this, the GenerateWithTime moves our execution context to the timer’s thread that it generates rather than leaving us on the calling thread.

Using the GenerateWithTime method allows us to abstract the looping implementation details and provides a more declarative/functional mechanism for generating the observable values. The nice thing is that we can consume this just as we would any other observable.

If you want to see this example in action, download my Rx for WP7 samples from MIX and try out the WP7 accelerometer sample. You will see that the mock value is used when you are inside the emulator and the actual accelerometer values are used when connected to a device. Regardless of how the values are generated, we process them with the same Rx subscription pipeline:


subscribed = accelReadings.Subscribe(args =>
             {
                 Single multiplier;
                 if (Single.TryParse(this.MoveMultiplier.Text, out multiplier))
                 {
                     ButtonTransform.X = args.X * multiplier;
                     ButtonTransform.Y = args.Y * multiplier;
                 }
             });
Posted on 4/27/2011 3:15:00 PM - Comments(1)
Categories: WP7 Rx C#

Presenting Rx and Windows Phone 7 at Mix

MIX11_BB_I'mSpeakingAt_1I’m happy to have been selected to speak at MIX this year. This is an exciting conference combining developers and designers and focusing on increasing application User Experiences. The focus of my talk will be to show some practical uses of Rx in the context of the Windows Phone 7. If you’re going to attend MIX, I would love to see you at this session. Otherwise, the sessions are typically recorded. I’ll add a link to the recording once it becomes available. Here’s the session description as it’s listed on the Mix website.

Rx: A Library for Managing Asynchronous Data and Events in your Windows Phone 7 Application

Lagoon B on Tue, Apr 12 3:30 PM - 4:30 PM

How do you manage the dizzying array of input sources, ranging from traditional UI events and external service requests to new user interface touch gestures and device sensor detections, while keeping your Silverlight and Phone applications responsive? In this session, you’ll discover how the Reactive Extensions (Rx) library simplifies the programming model by letting you declaratively compose increasingly complex asynchronous operations over these diverse data sources. We will demonstrate some practical uses of Rx for Windows Phone 7 by building a dice playing game including responding to user interactions, creating gestures from the device’s sensors, and making Asynchronous service calls. In the end you’ll learn how to coordinate pushing data around using Rx.

Posted on 4/4/2011 3:34:00 PM - Comments(0)
Categories: WP7 Rx

Using RX to detect shake Gestures

Part of the power of RX lies in it’s ability to compose complex operations  and keep the resulting code maintainable. I previously showed how to perform Drag-Drop operations with RX. This time, I want to take a look at a slightly more complex operation: Detecting “Shake” gestures on the Windows Phone 7.

The phone includes the ability to detect motion in 3D space through the built-in Accelerometer in the Microsoft.Devices.Sensors library. This sensor raises events when the phone is moved with information about how forcefully it was moved in the EventArgs. Detecting shakes is more complex than just knowing if the device was moved. We need to make sure that the user’s motion was aggressive enough to warrant a shake detection.

In addition, we need to know if the user moved the phone aggressively enough multiple times within a small enough time span. Simply monitoring the ReadingChanged event doesn’t fill the needs of detecting a real “Shake”. To manage all of these state changes and the times that each change occurs with traditional imperative code, we would either need to set up a number of queues remembering each motion that exceeds the tolerance and the times each happens and then act upon them when a sufficient number of these movements happen within a given time threshold. GoogleBinging this finds a number of sample implementations including Joel Johnson’s article and the recently released Shake Gesture Library. Both of these versions work with traditional events and manage the state internally.

If we use RX, we can simplify the code a bit by taking advantage of Observable.FromEvent to create an observable collection from the Accelerometer.ReadingChanged event, and the TimeInterval method to track the amount of time that passes between each accelerometer reading that exceeds the given tolerance (MinimumOffset).


Imports System.Linq
Imports Microsoft.Devices.Sensors
Imports Microsoft.Phone.Reactive

Public Module ShakeObserver
    Const MinimumOffset = 1.44
    Const TimeThreshold = 200

    Public Function GetObserver(ByVal accel As Accelerometer) As IObservable(Of IEvent(Of AccelerometerReadingEventArgs))

        Dim readingChangedObservable = Observable.FromEvent(Of AccelerometerReadingEventArgs)(accel, "ReadingChanged")

        Dim query = From knocks In
                    (From startEvent In readingChangedObservable
                     Where (startEvent.EventArgs.X ^ 2 + startEvent.EventArgs.Y ^ 2) > MinimumOffset).
                    TimeInterval
                    Where knocks.Interval.TotalMilliseconds < TimeThreshold
                    Select knocks.Value

        Return query
    End Function
End Module

We can then consume this ShakeObserver in client code as we would any other Observable collection.


Dim accel As New Accelerometer
accel.Start
Dim query = From shake in GetObserver(accel)
            Select shake

query.Subscribe(Sub(_) DoSomething())

Of course, if we are composing even more complex interactions, the power of using Observables here would be even greater as that’s where RX truly shines.

Posted on 2/22/2011 9:08:00 PM - Comments(1)
Categories: Rx VB Dev Center WP7