Return to Snippet

Revision: 48741
at July 8, 2011 14:27 by PerryBirch


Initial Code
// Class private var
private ISubject<KeyboardState> _KeyboardStates;

// Setup in ctor
_KeyboardStates = new ReplaySubject<KeyboardState>();

// In the update event
_KeyboardStates.OnNext(Keyboard.GetState());

// Func to compare key states (there is probably a better solution for this)
public static Func<KeyboardState, string> KeyStateComparer
{
    get
    {
        return (ks) =>
        {
            var sb = new StringBuilder();
            ks.GetPressedKeys().ToList().ForEach((key) => sb.Append(key.ToString()));
            return sb.ToString();
        };
    }
}

// Extension method to make it easy to append this overload of distinct
public static IObservable<KeyboardState> DistinctUntilChanged(this IObservable<KeyboardState> target)
{
    return target.DistinctUntilChanged(KeyStateComparer);
}

// Now that the update event is feeding the _KeyboardStates Observable we can...

var keyPressed = from ks in _KeyboardStates.DistinctUntilChanged()
                    select ks;

var keyDowns = from ks in keyPressed
                    .Zip(keyPressed.Skip(1), (prev, cur) =>
                    {
                        return from k in cur.GetPressedKeys()
                                where !prev.GetPressedKeys().Contains(k)
                                select k;
                    })
                select ks;

var keyUps = from ks in keyPressed
                    .Zip(keyPressed.Skip(1), (prev, cur) =>
                    {
                        return from k in prev.GetPressedKeys()
                                where !cur.GetPressedKeys().Contains(k)
                                select k;
                    })
                select ks;

// And with those observables we can...

keyPressed.Subscribe((keys) =>
{
    if (keys.GetPressedKeys().Length > 0)
    {
        var sb = new StringBuilder();
        keys.GetPressedKeys().ToList().ForEach((key) => sb.Append(key.ToString()));
        Debug.WriteLine("Keys: " + sb.ToString());
    }
});

keyDowns.Subscribe((keys) =>
    {
        foreach (var key in keys)
        {
            Debug.WriteLine("Key down: " + key);
        }
    });

keyUps.Subscribe((keys) =>
{
    foreach (var key in keys)
    {
        Debug.WriteLine("Key up: " + key);
    }
});

Initial URL


Initial Description
Toying around with Rx in WP7, thought this was interesting...

Initial Title
Rx Keyboard Events in WP7

Initial Tags


Initial Language
C#