Tuesday, November 27, 2012

Background agent expiry in Windows Phone 8

In Windows Phone 7[.x] background agents would expire (stop working/running) if an app wasn't launched for 14 days. Today I noticed in MSDN that things are slightly different in Windows Phone 8:
There are a few cases where an app’s background agent will not expire or will be automatically renewed.
•   If the Tile for your app is pinned to the phone’s Start screen, the expiration time for your background agent schedule is automatically extended to two weeks whenever your background agent calls Update(ShellTileData) to update the Tile.
•   If your app is selected by the user to display notifications on the on the lock screen, the expiration time for your background agent schedule is automatically extended to two weeks whenever your background agent calls Update(ShellTileData) to update the lock screen.
•   If your app auto-uploads photos using a resource-intensive agent, the resource-intensive agent schedule will not expire as long as the user has enabled this feature for your app in the photos+camera settings page.

Monday, November 26, 2012

Spinning my nodes #AlphaLabsCC

Hold the phone. I've been actually having fun writing XNA!
Ok, there was some head scratching getting some of the maths right but I got there.

Circles were boring.
Now I have spirals. And although you can't see it in these pictures they spin.


It's quite hypnotic to watch when animated.

The spirals (nodes) vary in direction of rotation, size and speed of rotation.


Saturday, November 24, 2012

Node Garden + multiple colours + transparencies #AlphaLabsCC

I've been playing with transparencies and multiple colours of node.
The screenshot below gives an idea but when animated it can create some really nice effects.

Best of all this only required adding a few lines of code. Plus I got to delete a load of other code I didn't need. - Deleting code is always good. :)

I'm looking forward to exploring other visual ideas.

This was done with Silverlight, but as the HTML version of the demo code is now available, I might look at using that for my next itteration.


Thursday, November 22, 2012

Passing additional information between nodes #AlphaLabsCC

As promised, here's an example of how to pass additional information between nodes/devices as part of your AlphaLabs projects.

I'm going to show how to pass the color of the current node to other devices, along with it's position, so that instead of just having your own node coloured and all other nodes white, every node is represented by the theme colour of the device it is actually on.
I'm also going to show how to do this with the Silverlight version as I'm assuming that everyone will be able to follow along with that without issue.
Something like this:

Obviously this makes it harder to tell which is your own node (hint, in the base code it's slightly larger than the others) but I'm sure you can cope and come up with interesting and exciting ways of indicating this in your apps/experiments/art.

So how do we do this?

It's all down to the power of the Tag!
I'm sure you're familiar with the Tag property of a Control or FrameworkElement. It's a useful miscellaneous property for storing arbitrary information in an object. Well, NodeGardenLib.Node has one too. The only difference is that in the Node it's a string, not an object.

We can add anything (within reason) to this property and it can be passed between devices via the underlying messaging functionality.

We'll start by setting the Tag when we create the node.
In MainPage.xaml.cs:
        private void CreateOwnNode()
        {
            var myNode = new MyVisualNode(this.rand, MainCanvas, this.gardener);

            this.gardener.AddSelfNode(myNode.X, myNode.Y);

            myNode.Id = this.gardener.GetSelfNodeId();

            var accentColor = (Color)Application.Current.Resources["PhoneAccentColor"];
            myNode.Tag = accentColor.Serialize();

            this.nodes.Add(myNode);
        }

You'll notice I'm using a helper method to abstract the serialization. Here are all the helper methods I'm using:

    using System;
    using System.Windows.Media;

    using Newtonsoft.Json;

    public static class ColorExtensions
    {
        public static string Serialize(this Color source)
        {
            return JsonConvert.SerializeObject(source);
        }
    }

    public static class StringExtensions
    {
        public static Color DeserializeAsColor(this string source)
        {
            try
            {
                return JsonConvert.DeserializeObject<color>(source);
            }
            catch (Exception exc)
            {
                return Colors.White;
            }
        }

        public static Brush DeserializeAsBrush(this string source)
        {
            return new SolidColorBrush(source.DeserializeAsColor());
        }
    }

I'm using Json.Net for the serialization as it's already referenced (as a dependency of SignalR) but you could use whatever you want.
The other important point of note is that I have exception handling in the Deserialize[AsColor] method. This is REALLY important as we may be receive messages from apps on other devices and they may be sending different, or no, information in the Tag. Be sure to handle deserialization exceptions and never make assumptions about what you'll receive.
This is of minor issue when you're only connecting to your own devices as it's easy to tell when not all devices are running the same version of the app-that's why the version number is auto-generated and displayed on the debug/config page.
It becomes more of an issue when connecting to the internet and anyone else is running a version of the app and also connecting to the internet as you'll be notified of each others nodes.

BTW: Always connect via the web option unless you really, really have a good reason to use UDP.
This is for 2 reasons: 1. We get to track what you're doing as everything that goes via the web is logged. (We'll make all the logged data available at the end of the project.) And 2. It's cool when other nodes (representing real other people/devices) appear in your garden.

Once we've got the color information in the tag we have to make sure we send it. So update MyVisualNode.cs:
this.gardener.UpdateSelfNodePosition(this.X, this.Y, this.Tag);

Then we need to make sure that we use the received color when drawing nodes.
In the Draw method of VisualNode.cs add:
this.NodeSize = Map(normalisedConnectedness, 0, 1, NodeSizeMin, this.NodeSizeMax());

this.Center.Fill = this.Tag.DeserializeAsBrush();
this.Center.Width = this.NodeSize;
this.Center.Height = this.NodeSize;


Simples.
Now just fire up a couple of emulators and voila:

If you try this over Web comms you'll notice that other nodes don't show up until they're moved. I think this is because of the way the WIEB (Where Is EveryBody) message is handled. Let me know if this is a big issue for you. Or fix it and send me a patch. ;)



But what if we want to test this easily without deploying to lots of devices? We'll just update the default nodes-that's what they're there for.

So in MainPage.xaml.cs

private void CreateDefaultNodes(int numberOfNodes)
{
    for (int i = 0; i < numberOfNodes; i++)
    {
        var visualNode = new VisualNode(this.rand, MainCanvas);
        visualNode.Tag = this.RandomAccentColor(this.rand).Serialize();

        this.nodes.Add(visualNode);
    }
}

private Color RandomAccentColor(Random random)
{
    // via http://chemicaloli.net/2011/10/01/windows-phone-7-accent-colour-list/
    switch (random.Next(1, 10))
    {
        case 1: return new Color { A = 255, R = 27, G = 161, B = 226 }; // Blue
        case 2: return new Color { A = 255, R = 160, G = 80, B = 0 }; // Brown
        case 3: return new Color { A = 255, R = 51, G = 153, B = 51 }; // Green
        case 4: return new Color { A = 255, R = 230, G = 113, B = 184 }; // Pink
        case 5: return new Color { A = 255, R = 162, G = 0, B = 255 }; // Purple
        case 6: return new Color { A = 255, R = 229, G = 20, B = 0 }; // Red
        case 7: return new Color { A = 255, R = 0, G = 171, B = 169 }; // Teal
        case 8: return new Color { A = 255, R = 162, G = 193, B = 57 }; // Lime
        default: return new Color { A = 255, R = 216, G = 0, B = 115 }; // Magenta
    }
}

The above is all quite trivial but hopefully shows how easy it is to send additional information. You can send ANYTHING so don't let yourself be limited by just thinking you're limited to accent colours.

Now go. And be creative...

Wednesday, November 21, 2012

Important #AlphaLabsCC update

If you're involved in the current Alphalabs project (The Always-on Telephone Club) then you'll need to go grab the latest code from codeplex as I've just pushed an important fix. (changeset 17283)

This changeset includes the ability to include additional, arbitrary, information in the message that is sent between devices. Without this it's much harder to do interesting things.

I'll post an explanation of how to use it shortly.

The fact I shipped this and hadn't spotted it until now was a big error on my part.
I'm sorry.
Please forgive me.