Learn Something New Every Day...

Recently I started jotting down anything new that made me say "oh cool!". Some are rarely used C# language features, some are API mechanics, and some are just random trivia. Here's what I've come up with so far:

C#'s stackalloc Keyword

stackalloc is basically handy way to allocate an array on the stack and can provide several conveniences.

Instead of allocating a locally scoped array (which is backed by the heap and managed by the garbage collector), you can get better "bare metal" performance by using stackalloc:

float SomeFunction(float[] input)
{
float dataResults;
float[] data = new float[3];
// we are calculating a result from input and storing interim results in data
return dataResults;
}

At the end of this method, a float array is sitting around waiting to be garbage collected. Instead, that function can become:

unsafe float SomeFunction(float[] input)
{
float dataResults;
float* data = stackalloc float[3];
// do something with the data and input
return dataResults;
}

In addition to taking the garbage collector and heap allocation out of the equation to eek out a little more performance, you also get a native float pointer. This can make interop with unmanaged code quite friendly, rather than a giant mess of fixed statements that would come about as a result of using float arrays.

 

C#'s ?? operator

Consider the following method:

Foo EnsureNotNull(Foo foo)
{
if (foo != null)
return foo;
return new Foo();
}

You can trim that down a bit by using a ternary operator:

Foo EnsureNotNull(Foo foo)
{
return foo == null ? new Foo() : foo;
}

But why use that when ?? is a binary null check operator; I.e., it returns the left if it is not null and the right otherwise:

Foo EnsureNotNull(Foo foo)
{
return foo ?? new Foo();
}

 

Hardware Graphics Acceleration and Asynchronous Calls

This is a tip I learned way back in my hay day of amateur game development. Many OpenGL/Direct3D may be just asynchronous calls on the hardware, and subsequent operations may end up resulting in them waiting for the previous operation to finish. The following is a very common pattern in drawing routines:

void OnPaint()
{
glClear(GL_COLOR_BUFFER_BIT);
// paint a bunch of stuff
// glDrawStuff();
glSwapBuffers();
}

Here, the code is immediately making paint operations following the clear. This results in those operations waiting until the clear has completed before executing. Restructuring the code as follows can squeeze out a little more performance:

void OnPaint()
{
// paint a bunch of stuff
// glDrawStuff();
glSwapBuffers();
// clear the buffer after the background and foreground are swapped
// this clear will take place asynchronously and be complete
// when we start to draw the next frame!
glClear(GL_COLOR_BUFFER_BIT);
}

I implemented this in GLMaps recently, and saw an FPS increase from 49 to 51. That's a ~4% increase! Using this technique, any static preprocessing/setup can actually just be run at the end of the drawing operations, rather than at the beginning. (Concurrently using the CPU and GPU between frames to get a net gain in FPS)

 

Handy C# 3.0 Shorthand

This tip didn't actually catch me by surprise, since I read through the C# 3.0 new features. However, old habits die hard, so I often forget to use them. Prior to C# 3.0, the following would be a standard class declaration:

class Foo
{
int myBar;
public int Bar
{
get
{
return myBar;
}
set
{
myBar = value;
}
}

double myMoo;
public double Moo
{
get
{
return myMoo;
}
private set
{
myMoo = value;
}
}

float myCool;
private float Cool
{
get
{
return myCool;
}
set
{
myCool = value;
}
}
}

With C# class declaration shorthand, developers can now eliminate much of the redundancy (the properties and backing fields are implicitly defined):

class Foo
{
public int Bar
{
get;
set;
}

public double Moo
{
get;
private set;
}

public float Cool
{
get;
set;
}
}

Also, when declaring an instance of that class, prior to C# 3.0, a common pattern is to set some initial properties:

void MakeFoo()
{
Foo foo = new Foo();
foo.Bar = 0;
foo.Cool = 0;
}

With C# 3.0, you get additional shorthand (less characters, not lines), and a more aesthetically pleasing syntax:

void MakeFoo()
{
Foo foo = new Foo()
{
Bar = 0,
Cool = 0
};
}

 

That's it for tips for now. Share 'em if you got 'em!

Blacklisted by Google's Geolocation Service

banned

Several months ago, I described how one could use Google Gears to easily add Geolocation and GPS to their Windows Mobile applications. Basically, this is a trick that would work with any embedded browser by adding and scripting a DOM element, or by using my unsavory window.location hack when that is not possible (as is in the case of Pocket IE).

I was recently trying to reuse this code, and I noticed that the Geolocation sample page I had hosted was not working on Windows Mobile anymore; the service seemed to be returning an invalid response. I navigated to that same URL in Google Chrome and Firefox and it worked fine. I then tried navigating to the Gears Geolocation sample in Pocket IE, and that worked as well. I verified that I still had the most up to date code hosted on my domain. Still no luck, as the code had not changed.

So out of curiosity, I hosted the geolocation page on a separate domain and navigated to it within Pocket IE. 'Lo and behold, it starts working. So mentally, I constructed this chart in my mind:

  Pocket IE Google Chrome Firefox
code.google.com Works Works Works
koushikdutta.blurryfox.com Broken! Works Works
supersecretdomain.com Works Works Works

My conclusion? Google has blacklisted my domain! And, to be honest, I'm not really sure why. I'm using their sample code on my domain to get geolocation data, but using the results outside of the context of the browser.

Congratulations Google, you have earned the first honorary YouBastard tag on my blog!

 

Edit:

Google Gears EULA. I haven't violated it as far as I can see, but they do reserve the right to cut off access to the service at their whim.

ActiveSync? On GMail? It's More Likely Than You Think.

200px-Snakesonmyplane

Chances are, most Windows Mobile/iPhone user's don't have an Exchange Server sitting around for their own personal use. Well those people are now in luck! Google has released a new service called Google Sync that uses the ActiveSync protocol to deliver your Mail and Contacts from their services to your phone. This also works with Google Apps hosted domains! This is pretty awesome. Embrace, extend, extinguish?

WindowlessControls Tutorial - Part 4: Data Binding (continued)

contactlist

After rereading my previous post about data binding, I don't feel that my sample does justice to the overall flexibility/utility of WindowlessControls. So, I decided to write another sample: a template for a Windows Mobile contact list application.

Let's start out by deciding the basic behavior of the Contact List:

  • The contact list should show the name on the left of the item, and the contacts number below it.
  • The contact's picture will be to the right of the name and number.
  • When the contact is selected, it should expand and show the street address and email address.

Like the previous example, we populate our ItemsControl with the data we want to bind. To get the list of Pocket Outlook contacts, access the handy OutlookSession class:

myItemsControl.ContentPresenter = typeof(ContactPresenter);
myItemsControl.Control = new StackPanel();

OutlookSession session = new OutlookSession();
foreach (Contact contact in session.Contacts.Items)
{
if (contact.Picture != null)
myItemsControl.Items.Add(contact);
}

Now, let's set up the IInteractiveContentPresenter that will represent a contact. This ContactPresenter is a bit more complex than the previous Image Gallery example:

public class ContactPresenter : StackPanel, IInteractiveContentPresenter
{
// selection state rectangle
WindowlessRectangle myRectangle = new WindowlessRectangle();
// contact picture
WindowlessImage myImage = new WindowlessImage();

// obvious properties
WindowlessLabel myName = new WindowlessLabel(string.Empty, WindowlessLabel.DefaultBoldFont);
WindowlessLabel myNumber = new WindowlessLabel();
WindowlessLabel myAddress = new WindowlessLabel();
WindowlessLabel myEmail = new WindowlessLabel();
// this panel will house the email and address, and only be visible when focused
StackPanel myExtendedInfo = new StackPanel();

public ContactPresenter()
{
OverlayPanel overlay = new OverlayPanel();

// stretch to fit
overlay.HorizontalAlignment = WindowlessControls.HorizontalAlignment.Stretch;
overlay.VerticalAlignment = VerticalAlignment.Stretch;

// dock the picture to the right and the info to the left
DockPanel dock = new DockPanel();
StackPanel left = new StackPanel();
left.Layout = new DockLayout(new LayoutMeasurement(0, LayoutUnit.Star), DockStyle.Left);
myImage.Layout = new DockLayout(new LayoutMeasurement(0, LayoutUnit.Star), DockStyle.Right);
myImage.MaxHeight = 100;
myImage.MaxWidth = 100;

dock.Controls.Add(myImage);
dock.Controls.Add(left);
// 5 pixel border around the item contents
dock.Margin = new Thickness(5, 5, 5, 5);

// make the overlay fit the dock, so as to limit the size of the selection rectangle
overlay.FitWidthControl = overlay.FitHeightControl = dock;

// set up the rectangle color and make it fill the region
myRectangle.Color = SystemColors.Highlight;
myRectangle.HorizontalAlignment = WindowlessControls.HorizontalAlignment.Stretch;
myRectangle.VerticalAlignment = VerticalAlignment.Stretch;
// the rectangle does not paint by default
myRectangle.PaintSelf = false;

// add the extended info that is only visible when focused
StackPanel nameAndNumber = new StackPanel();
nameAndNumber.Controls.Add(myName);
nameAndNumber.Controls.Add(myNumber);
myExtendedInfo.Visible = false;
myExtendedInfo.Controls.Add(myEmail);
myExtendedInfo.Controls.Add(myAddress);

// set up the left side
left.Controls.Add(nameAndNumber);
left.Controls.Add(myExtendedInfo);

// add the foreground and the background selection
overlay.Controls.Add(myRectangle);
overlay.Controls.Add(dock);

// add the item
Controls.Add(overlay);

// this is the bottom border
WindowlessRectangle bottomBorder = new WindowlessRectangle(Int32.MaxValue, 1, Color.Gray);
Controls.Add(bottomBorder);
}

#region IInteractiveStyleControl Members

public void ApplyFocusedStyle()
{
// make the rectangle paint to denote that it is focused
myRectangle.PaintSelf = true;
myExtendedInfo.Visible = true;
}

public void ApplyClickedStyle()
{
}

#endregion

#region IContentPresenter Members

Contact myContact;
public object Content
{
get
{
return myContact;
}
set
{
// populate the various UI elements with the contact
myContact = value as Contact;
if (myContact.Picture != null)
myImage.Bitmap = new StandardBitmap(new Bitmap(myContact.Picture));

myName.Text = myContact.FileAs;
if (!string.IsNullOrEmpty(myContact.MobileTelephoneNumber))
myNumber.Text = myContact.MobileTelephoneNumber;
else
myNumber.Text = myContact.HomeTelephoneNumber;

myAddress.Text = string.Format("{0}\n{1} {2} {3}", myContact.HomeAddressStreet, myContact.HomeAddressCity, myContact.HomeAddressState, myContact.HomeAddressPostalCode);
myEmail.Text = myContact.Email1Address;
}
}

#endregion
}

And the results of this tutorial can be seen in the video below.

This took me about 30 minutes to whip together, with a bit more time, this could easily be turned into a real Contact List application! Click here for the updated source code to this tutorial.

Mono/Dalvik Interop

I've been working away at getting Mono into a usable state on Android, and finally have something to show for it. I (mostly) completed the interop layer that allows code invocation of Mono from Dalvik, and vice versa. As a proof of concept test, I have my test verify reentrancy (i.e., you can invoke Mono method from Dalvik, which in turn invokes a Dalvik method from Mono).

Java code that calls into Mono:

String ret = (String)MonoBridge.invoke("MonoDalvikBridge.DalvikBridge, MonoDalvikBridge", String.class, "Echo", "hello");
Log.i("MonoActivity", ret);

And here's the C# method that was called. In turn, it calls back into Java:

public static string Echo(string echo)
{
DebugLog(echo);
string ret = Invoke<string>("com.koushikdutta.monodalvikbridge.MonoBridge", "echo", echo);
DebugLog(ret);
return echo;
}

And finally, this is the Java method that was called from C#:

public static String echo(String str)
{
DebugLog(str);
return str;
}

As shown, passing and returning "primitive" types between both runtimes works seamlessly. Passing complex types and calling methods on those objects works as well, by way of a runtime wrapper is created for it (MonoObject/DalvikObject).

The basic syntax for invoking a method from one runtime into another is:

Invoke(className | runtimeObject, methodName, returnType, params object[] arguments)

That said, I'm pretty excited for when Mono supports the upcoming C# "dynamic" keyword. That will make interop (at least from Mono to Dalvik) quite trivial.

There's still a bit of clean up and convenience functions I need to implement, but the majority of this is complete. The code is all open source, for those that are curious.

WindowlessControls Tutorial - Part 4: Data Binding

databind

A colleague of mind was asking me a few questions about WindowlessControls, which reminded me that I had been neglecting this tutorial series!

Anyhow... Data binding is all the rage in UI development these days. In short, data binding is a way to have your UI elements be "bound" to your internal data structures. Changes to the data will be reflected as changes in the UI. WPF does this quite nicely with the ItemsControl class. So, that provided a template for the implementation of WindowlessControl's version of ItemsControl. This tutorial will demonstrate how to create an image gallery/viewer application using a data binding technique.

We'll start out with the form template similar to the the previous tutorial. A form with a background image and a foreground which contains the ItemsControl object:

// set up the background bitmap and control
PlatformBitmap backgroundBitmap = PlatformBitmap.FromResource("Wallpaper.jpg");
WindowlessImage background = new WindowlessImage(backgroundBitmap);
background.Stretch = Stretch.Uniform;
overlay.Controls.Add(background);

// set up the foreground
StackPanel foreground = new StackPanel();
overlay.Controls.Add(foreground);

// set up the ItemsControl which will hold the images
myItemsControl.BackColor = Color.Transparent;
// the images will be contained in a wrap panel
myItemsControl.Control = new WrapPanel();
// this tells the ItemsControl what is used to represent the content items
myItemsControl.ContentPresenter = typeof(ImageResourcePresenter);
foreground.Controls.Add(myItemsControl);
An ItemsControl contains 3 properties of interest:
  • ContentPresenter - This is the type of WindowlessControl that will represent your data. It must implement IInteractiveContentPresenter.
  • Control - This is the panel that will lay out your ContentPresenters.
  • Items - This is the collection of objects that will be bind to the UI.
// set up the ItemsControl which will hold the images
myItemsControl.BackColor = Color.Transparent;
// the images will be contained in a wrap panel
myItemsControl.Control = new WrapPanel();
// this tells the ItemsControl what is used to represent the content items
myItemsControl.ContentPresenter = typeof(ImageResourcePresenter);
foreground.Controls.Add(myItemsControl);

Let's start out by implementing the content presenter. Let's set the following goals for our presenter:

  • Display the image (obviously).
  • Show a highlight border around the image when it is focused.
  • The image should have a grow/shrink animation when clicked.

Here's the implementation of the content presenter:

// an ImageResourcePresenter will be shown as a WindowlessImage
// with a WindowlessBackground that is visible when it is selected
class ImageResourcePresenter : OverlayPanel, IInteractiveContentPresenter
{
WindowlessRectangle myRectangle = new WindowlessRectangle();
WindowlessImage myImage = new WindowlessImage();

public ImageResourcePresenter()
{
// spacing between images
Margin = new Thickness(5, 5, 5, 5);
// limit the maximum size of an item
MaxWidth = 100;
MaxHeight = 100;
// stretch to fit
HorizontalAlignment = WindowlessControls.HorizontalAlignment.Stretch;
VerticalAlignment = VerticalAlignment.Stretch;

// allow a 5 pixel border between the image and the rectangular selected background
myImage.Margin = new Thickness(5, 5, 5, 5);
myImage.VerticalAlignment = VerticalAlignment.Center;
myImage.HorizontalAlignment = WindowlessControls.HorizontalAlignment.Center;

// set up the rectangle color and make it fill the region
myRectangle.Color = SystemColors.Highlight;
myRectangle.HorizontalAlignment = WindowlessControls.HorizontalAlignment.Stretch;
myRectangle.VerticalAlignment = VerticalAlignment.Stretch;
// the rectangle does not paint by default
myRectangle.PaintSelf = false;

Controls.Add(myRectangle);
Controls.Add(myImage);
}

#region IInteractiveStyleControl Members

public void ApplyFocusedStyle()
{
// make the rectangle paint to denote that it is focused
myRectangle.PaintSelf = true;
}

public void ApplyClickedStyle()
{
// when clicked, remove the margin, so the image can "grow"
myImage.Margin = Thickness.Empty;
}

#endregion

#region IContentPresenter Members

string myName;
public object Content
{
get
{
return myName;
}
set
{
myName = value as string;
// see if this image is a file or a resource, and load it
if (!File.Exists(myName))
{
myImage.Bitmap = PlatformBitmap.FromResource(myName);
}
else
{
myImage.Bitmap = PlatformBitmap.From(myName);
}
}
}

#endregion
}

 

So to create this presenter, start with an OverlayPanel, which houses a background (the focused state rectangle) and a foreground (the WindowlessImage). The interesting bit of the code is the implementation of the Content property. Let's come back to that later.

So, next is to populate the Items on the ItemsControl with images. The follow code will search for all image resources in the assembly and also any image files that maybe in \My Documents\My Pictures.

// let's get a list of image resources
Assembly ass = Assembly.GetCallingAssembly();
string[] names = ass.GetManifestResourceNames();
foreach (string name in names)
{
foreach (string extension in imageExtensions)
{
if (name.EndsWith(extension, StringComparison.CurrentCultureIgnoreCase))
{
myItemsControl.Items.Add(name);
break;
}
}
}

// now let's search the file system for images
foreach (string name in Directory.GetFiles("\\My Documents\\My Pictures"))
{
foreach (string extension in imageExtensions)
{
if (name.EndsWith(extension, StringComparison.CurrentCultureIgnoreCase))
{
myItemsControl.Items.Add(name);
break;
}
}
}

Now, rewinding to the Content property. Behind the scenes, when an object is added to the Items collection, the ItemsControl creates an instance of the given ContentPresenter and sets the Content property to the item to which it is bound. When the Content value changes, the IInteractiveContentPresenter should update the UI representation accordingly. As you can see above, the ContentPresenter determines if the Content is a image file or an image resource, and then loads the image from the appropriate source.

That's all there is to data binding! Changing your to add or remove images is as simple as updating the Items collection. By using data binding and a proper custom WindowlessControls, rich and flexible user interfaces can be quickly developed for Windows Mobile.

Source code to the updated WindowlessControls tutorial.