Monday, March 17, 2008

Welcome Susan!

Susan


At a little before 11AM on March 15th, Wangdera Corporation welcomed its newest employee when our daughter Susan was born at our home in Virginia. Susan tipped the scales at a hefty 8 pounds, 14 ounces (4.03kg), and she and her mother are both doing extremely well. Big sister Ellen is very happy and proud as well.


More pictures available at our Flickr site.


In what may be a related event, Ellen has announced that she is changing her name to "Princess Ellen Ladybug".


Wednesday, March 12, 2008

Art Geek Zoo

At our house, the newspaper gets full coverage: I read only the comics and my wife reads everything else. I like comics. So I thought it was pretty cool when I found out my good friend Rob Stenzinger has started to publish Art Geek Zoo, his latest artistic effort, online. Check it out!

 

Tuesday, March 11, 2008

My First Trademark Violation

A few weeks ago, I posted a pair of little utilities that I wrote to help me play Falcon. They were just one of those spare-time, throwaway things most programmers do from time to time, so I didn't put a ton of thought into them. Well, last week, I got a phone call from a marketing guy at Sassafras Software…it seems I should have put a bit more though into at least the names.

 

See, one of the bits I published, I called KeyServer. I called it that because it's a little TCP listener that receives events and sends keystrokes to the active application. Of course, it's also a registered trademark of Sassafras Software. Oopsie.

 

The marketing guy was pretty nice about it. He never said anything about legal action. But here's the thing: US Trademark law says you have to actively defend a trademark, or you lose it. That means that if you don't sue the people who use your trademark, a competitor can come along and point to that behavior as proof that you don't want your trademark and that it should be taken away.

 

On the one hand, it was somewhat shortsighted of me to name my software "KeyServer". I mean, that was practically guaranteed to be trademarked. On the other hand - subjectively and emotionally - it's never fun to be threatened with legal action, even when it's done politely and when you know that the person delivering the news has no choice about it. Lesson learned, I guess.

 

On the bright side, it was good motivation to add a few features that I've been meaning to get around to. So I'm re-releasing the software under the name "Keylay" (it's a keystroke relayer - get it?). Here are the new features:

 


  • A name that won't get me sued!

  • Has a less-boring tray icon that changes colors based on whether or not a profile is loaded, whether or not a client is connected, and animates when keystrokes are being relayed.

  • Takes a command-line argument that is the path to a profile to be loaded at startup.

 

While I was at it, I also updated F4Panel a bit. In addition to the ICP and the MFDs, I also added an "Aux1" panel that gives access to touchscreen controls of a few miscellaneous things like landing gear, the autopilot, the ECM and RWR, the laser, and the master arm switch. In addition, I made it remember the last address it connected to, since that was driving me nuts.

 

You can download the updated binaries and the source here.

Friday, March 7, 2008

DebuggerStepThroughAttribute

Here's a good one I was reminded of the other day. I was writing some code of the form we've all seen a thousand times before:

 

public Foo Bar {
  get { return _bar; }
  set { _bar = value; }
}

 

Even with automatic properties in the latest version of C#, you still wind up writing code like this a lot. Unless you're fortunate enough to be writing code in a more advanced language…like Lisp. :) (Sorry, had to.)

 

Normally this is no big deal, but there is one time where this construct can get really annoying: when you're debugging and the property is frequently accessed as the means to get somewhere else. In my code that will often look like this:

 

public SomethingProvider SomethingProvider {
  get { return _somethingProvider; }
}

 

when I have some service that I've abstracted, maybe to make testing easier. As a result, my code has lots of calls in it like this:

 

SomethingProvider.PerformOperation(arg1, arg2, …);

 

When I hit that line, I want to debug into it, but of course when I hit "step into" I wind up on the property accessor. It's even worse when there are multiple properties involved, as for example in code like this:

 

SomethingProvider.PerformOperation(OtherProvider.RetrieveValue(), YetAnotherProvider.Calculate());

 

By the time I've finished stepping in and out of that, I'm all, "Aargh! Just take me to the code!" Luckily, there's an attribute that lets you skip all these piddly statements: DebuggerStepThroughAttribute. You use it like any other attribute - apply it to a method, a whole class, or a property accessor. Note that you can't apply it to a property as a whole - it has to go on the individual getters or settors, like so:

 

public SomethingProvider SomethingProvider {
  [DebuggerStepThrough]
  get { return _somethingProvider; }
}

 

Put enough of these in and stepping in to a compound expression becomes much less tedious. Yay!

 

I don't think I'd recommend generally putting this attribute on anything but simple one-line properties of the form I've shown here, and even then you want to be careful: debugging is complicated, and I know I can screw up even simple property access - sometimes stepping into those things is actually useful, as it shows you that you cut and pasted one too many times and wound up returning the wrong value.

 

That said, you can still set breakpoints on code you've applied the attribute to, and the breakpoints will still fire.

Tuesday, February 26, 2008

Design and Implementation - Episode 3

Update: Part 2 is now available here. I've also updated the links below.

 

I just got done mixing the first part of the third episode of Design and Implementation, the occasional podcast that Tim and I do. This time, we interviewed John Lam, who is a Product Manager at Microsoft on the DLR team. John has been working on IronRuby, an implementation of the Ruby language on the .NET platform.

 

Tim has been big into Ruby lately, so we had a good time talking to John. So good, in fact, that we ran fairly long. So I've split the episode in two - the first part is now ready. When I get done mixing the second part, I'll put that up too. Sorry to be a tease. :)

 

Download episode 3, part 1 (MP3, 30.4 MB).


 

Previous episodes:


Thursday, February 14, 2008

Announcing F4Panel/KeyServer

Update: The term "KeyServer" is a registered trademark, so I had to rename mine. Details and an updated version here. The download link in this entry is no longer active.

 

I've been a fan of the F-16 combat flight simulator Falcon 4 for a long time. As with most flight simulators, situational awareness (SA) can be a bit of a challenge - flying a flight simulator where your only view is the computer screen has been described as like trying to drive while looking through a drinking straw. Well, when I finished FlexWiki, as a reward to myself I bought a TrackIr. It's a head-tracking device that lets me change the view by simply moving my head. It's very intuitive and freakin' awesome - it's hard to imagine flying without it anymore.

 

The problem with using TrackIr is that you start living in the 3D view. That's a problem because in Falcon 4: Allied Force (F4AF), many of the gauges don't work in the 3D view. The biggest problem, though, is that the cockpit isn't clickable. So you wind up bouncing back to the 2D view all the time to toggle this or that with the mouse, which is slightly annoying.

 

I thought about building some sort of USB device (this sort of activity is called "cockpit building", and people spend literally tens of thousands of dollars on it), or maybe buying something, but everything I could find was either a bit on the expensive side or was going to stretch my extremely rusty electronics skills. And was going to take a hell of a lot of time. But wait! I'm a pretty good programmer! I can solve this with software. Hence were born F4Panel and KeyServer.

 

The basic idea I had was to transform my ancient PDA (it runs Pocket PC 2002 to give you some idea) into a touchscreen device that would emulate the major instrument panels in the F-16. It's not an original idea - you can buy a much nicer-looking version of what I wrote for $30 at http://www.pocketmfp.com/default.htm. But it requires Pocket PC 2003, and my device is so old it doesn't support that.

 

To make a long story short, I wrote my own. Here are some pictures of it:

 

F4Panel MFD F4Panel ICP

 

It works great, and I thought other people might like to make use of it, so I've posted a zipfile here.

 

There are two parts: F4Panel runs on the PDA, and KeyServer runs on the PC. Install F4Panel on the PDA by copying the appropriate F4Panel.cab file to your PDA and clicking it. KeyServer doesn't need to be installed - just run KeyServer.exe. When KeyServer starts, it'll put a very boring icon in the system tray. Right click it and choose "Load Profile". I've included a profile for F4AF, but the syntax is pretty simple and you should be able to figure out how to change it. Once you've got the profile loaded, go to the PDA and run F4Panel. Click Tools->Connect and enter the name of the computer where KeyServer is running. You'll obviously need to the PDA to be connected to the same network as the PC somehow - I just keep mine in its USB docking station.

 

The two programs communicate by means of a very simple HTTP-like protocol: F4Panel sends something like "CLICK ICP1" and KeyServer looks in a profile file for a command called ICP1 to figure out what keys to send to the foreground application. If it sends them okay, it returns "200 OK". I mention this, because I intended KeyServer to be general enough to be used with other games (or whatever) - you'd just need to write the PDA bit that sends "CLICK <commandname>" and the appropriate profile file that maps <commandname> to some sort of key sequence. The socket code is extremely simple - you can look at the F4Panel source to see it.

 

Because this was a fun-time project, and because quite honestly I'm momentarily burned out on full-scale open source projects, the zipfile is just a dump of the source and binaries. I'm sure you can cope. :) Consider it MIT-licensed, so feel free to go forth and improve it.

 

Update: The term "KeyServer" is a registered trademark, so I had to rename mine. Details and an updated version here. The download link in this entry is no longer active.

Wednesday, February 13, 2008

MTPS REST API Updates

Well, I warned you that we'd be updating the MTPS REST API (located at http://lab.msdn.microsoft.com/restapistubs/). And we did. A bunch of things have changed. Mostly, I've added new functionality. I did, however, change the way one thing works in a fairly significant way, but it just makes for a good opportunity to talk a bit about how the service works.

 

If you visit the content section of the service, you'll be given a list of all the content item IDs in the system. (A content item is an atom of information - for example the documentation for one of the overloads of System.Xml.XmlReader.Read.) Right now that list is very short, because we're still not hooked up to the live database, so the bits that I can't get from the MTPS SOAP service, I just make up. You can tell because they all have "fake" somewhere in the URL. Eventually, we'll list all the content items here. Not because I think that a list of all the content items is inherently useful in and of itself (although you never know), but rather because I believe that every URL in the system ought to be reachable by traversing links from the service root.

 

Clicking on the only non-fake content item ID takes you here. This is what we call the alternates list for the content item, which happens to be the System.Xml.XmlReader content item. "Alternates" because it lists all of the available versions/locales pairs. See, every content item can exist in multiple versions and in multiple languages. So you can click here to get the German, .NET 2.0 version of the System.Xml.XmlReader content item, or you can click here to get the US English, .NET 3.5 version of the same document.

 

Once you click one of those links, you arrive at the content item page. (You can always tell what type of page you're on by examining the class of the <body> tag.) Here, you get links to all the various pieces of information that make up the content item. One of the most interesting is the Mtps.Xhtml primary document. This document contains most (but not all) of the information you're used to seeing on the MSDN2 website when you look up a class or method. And here's where one of the changes came in.

 

In the first version of the service that I posted, if you were to look at an Mtps.Xhtml document (for example, this one), you'd find that clicking in the links it contains would jump you to the other Mtps.Xhtml documents. At first blush, this is a fairly natural thing to do, as it mirrors what happens on the MSDN2 website. However, there was a subtle problem lurking that came up, and now the service no longer behaves that way. Now, if one content item links to another in the Mtps.Xhtml document, that link takes you to the list of alternates for the target document.

 

This has a number of implications. First of all, it means that if you want to use the MTPS REST API as a (really ugly) documentation browser, you're going to do a lot more clicking. To navigate from one Mtps.Xhtml document to another, you're going to have to click once to get to the list of alternates, again to pick a particular version/locale combo, and then again to get to the Mtps.Xhtml primary document. Not optimal from a human standpoint it's worth mentioning that the REST API is not designd to be navigated by a human…except developers who want to get an idea of how it works.

 

No, there's a good reason for this change. You see, it turns out that the underlying MTPS database doesn't actually contain version or locale information. You can see this if you use the SOAP service - that document that comes back is linked solely via something called an asset ID, which is basically like the "b8a5e1s5" (we call that form a "short ID") part of the URL for a content item. In the initial release, I actually wound up just using the locale and version of the linking document to synthesize a link to the target document. Obviously, this would break if the target document happens to be of a different locale and/or version. And it did.

 

But that's not the reason we changed it. The real reason is that it's not clear that the service should be defining what the correct behavior should be. Should we always send links to the latest version? To the same version? If you think you know the answer for your scenario, let me assure you that someone else will have a different one. On the MSDN2 website, we can make assumptions about which way it should go because it's not an API, it's an application. But the REST interface is an API. So we have to leave it to the client, which means linking to the alternates page, so the client can implement whatever policy they want - pick the latest, pop up a dialog, whatever.

 

I mention this because to me, it's really characteristic of the RESTian nature of the interface in two ways. First, we leverage links, rather than expecting clients to synthesize URLs based on knowledge of how the system works. It emphasizes the view of the system as a directed graph of linked resources. That has more of the "of the web, not just on the web" flavor that (IMO) characterizes good REST interfaces.

 

The other thing that it brings home is that the REST API is not a website in the traditional sense. That is, it's not that I've just built a website and decided that all my .aspx pages now have .xml siblings or whatever: the system is fundamentally designed in a different way - to expose as much of the information available in the database as possible, not to present it for human consumption. Which goes part way towards explaining my decision not to include stylesheet links in the head, too. (A post for another day, perhaps.)

 

So this has turned into a somewhat long (and perhaps somewhat rambling) post about a service that - as far as I know - no one is using yet (tell me if you are). But as the first major REST system that I've implemented "for real", I've found the issues that come up to be enormously helpful towards my understanding of the advantages and limitations of REST. Hopefully some of you will, too.

 

I hope to occasionally post more information about the design and implementation of the MTPS REST API, and about the things I'm learning from it, as we move forward.