Thursday, October 28, 2004

A Dad Be I

If you haven't seen me for the last two days, it's for a very good reason...my daughter was born today after a long and difficult labor. “Woohoo!“ doesn't even start to describe it. :)


Details here.

Sunday, October 24, 2004

Book Review: Beginning .NET Game Programming in VB.NET

Let me get the full disclosure bit out of the way right up front: I was sent a free copy of this book by the publisher, I know two of the authors somewhat, and they mention this website in their references. That said, you can choose how large a grain of salt with which to take this review.


Frankly, I didn't think I was going to like Beginning .NET Game Programming in VB.NET. It's written in VB.NET (I'm a C# guy), it's a beginner's book, and most DirectX/gaming books suck. Fortunately, I was wrong.


I find that whenever I'm learning a technology, I generally want two books. I want to start with a good tutorial, and once I understand the basics, I want a good theory and reference book to help me explore in my own directions. Beginning .NET Game Programming in VB.NET makes absolutely no secret of the fact that it is very much the former, and not at all the latter. Frankly, had it tried to be a reference book, it probably would have failed, if for no other reason than that Tom Miller already wrote the best Managed DirectX reference/theory book.But David, Alexandre, and Ellen set out to write a tutorial work, and I think they did a pretty reasonable job.


The book starts off by writing a Tetris clone using only GDI+ (no DirectX), but builds up to a network multiplayer 3D game. Since the book is fairly short by computer text standards, it moves at a pretty good clip, presenting the material by writing and analyzing several different interesting games.


I'd have to say that this approach is the book's greatest strength: the fact that it is very much grounded in writing a game. That means it doesn't hand-wave over things like DirectPlay or DirectInput (although graphics does get the majority of the coverage). There's even some discussion of DirectDraw, which is fairly rare these days. And along with all the technology stuff, they constantly talk about the other factors for successful game development (e.g. “Source control is not optional” and “Write lots of small games first”). This is a goodness, as is the plethora of working game code.


The book isn't perfect, of course. I came across several errors, none too serious, that seemed to be largely related to the fact that much of the code in the book was ported from the C# companion work, which I haven't read. I also was a bit disappointed with the coverage of the issues around network play - I would have liked to have seen more discussion on this area. Still, it was arguably a good decision for them to cover less, not more.


Overall, I'd definitely recommend this book to anyone that had some VB.NET experience, and was interested in getting started with game programming.

Thursday, October 21, 2004

Longhorn Ship Date?


From the WinInfo Newsletter, (which is generally pretty good, IMO):



According to recent internal schedules I've seen, Longhorn and Office 12 are set to arrive concurrently on May 22, 2006. And the first Longhorn beta is set for February 16, 2005--the same beta 1 date I first reported in April. Naturally, this schedule could change--we're talking about Microsoft, after all--but the massive Microsoft infrastructure finally seems to be rumbling to life. For beta testers and Windows enthusiasts, 2005 looks to be a busy year.


Which I read as, “Don't worry about having to support Longhorn in the real world until at least 2008.” That's not an inidictment of the product. Just means that I'm going to go back to working on solving problems with technologies that my customers actually use - no sense getting too excited just yet.

Wednesday, October 20, 2004

Rewriting WSDL.EXE

The other day, I blogged about how easy it is to generate WSDL directly from a web service assembly, without having to set up an actual web service. Well, I decided to take it a step farther and see if I could generate the proxies directly, too. As it turns out, that's pretty easy, too.


The code turned out to be a bit long for a blog post, so I added it to my wiki instead. You can find the article here.


In addition to generating the proxy class without generating WSDL, I went ahead and added the code to walk over the generated code and strip out any type that isn't the proxy itself. Because we have several web services that share a set of types, and since we have defined these common types in a separate shared assembly to avoid type identity problems, this means the generated code looks just how we like it.


I haven't made the code bulletproof or terribly generic, since it's just for our use here at my client, but it should serve as a reasonable starting point for anyone that wants to produce custom proxies. One variation I can think of that would be useful would be to generate every type into its own file - that way if you had some types that you wanted to share and some that you didn't, it would be easy to automate which get tossed and which get kept.

Monday, October 18, 2004

Generating WSDL Without ASP.NET

Because wsdl.exe generates classes that don't look exactly like we want them to, I've set up a process at my client to generate custom proxies. Right now, we do this as a partly manual process - we've got a simple script that downloads the WSDL from a set of web services we've developed, then generates the default proxies by running wsdl.exe against them. Then we make some simple hand edits against them to make them look how we want them to.


There are two problems with this process:



  1. It requires hand editing the files every time we want to make a change.

  2. The turnaround sucks - we have to deploy the web service somewhere before we can get the WSDL.

The first one I'll fix later. It's pretty easy to do right now, since most of the changes are just removing code. At some point I'll cobble together some sort of sed script or something.


The second one is sort of a pain at the moment, though. We're using Continuous Integration, which is great because it means every time someone makes a change, we get a fully tested and installed version of the product running on a web farm about twenty minutes later. But because that's currently the only way we have of deploying (setup is somewhat complex), it means that if someone adds a [WebMethod], they have to wait 20 minutes for the deployment before they can download the wsdl and update the custom proxies.


I thought it would be pretty nice if instead there was some way to generate WSDL directly from the web service assemblies. Well, after poking around a bit with Reflector, and with a little help from Tim, I'd figured out the incredibly easy code to do exactly this. Assuming you have a web service class called MyService, the following code will spew the WSDL for it to the command line:


ServiceDescriptionReflector reflector = new ServiceDescriptionReflector();
reflector.Reflect(typeof(MyService), "http://localhost/vdir/Foo.asmx");



if (reflector.ServiceDescriptions.Count > 1){
  throw new Exception("Deal with multiple service descriptions later");
}


XmlTextWriter wtr = new XmlTextWriter(Console.Out);
wtr.Formatting = Formatting.Indented;
reflector.ServiceDescriptions[0].Write(wtr);
wtr.Close();


The URL that appears in the call to Reflect is not used except to populate the address element in the WSDL.


It'll be the work of minutes to roll this code up into a little EXE that takes the class name on the command line. I'll probably add an option to reflect over all classes in an assembly, looking for anything with a [WebMethod] attribute on it somewhere and emitting that, too.

Sunday, October 17, 2004

TDD Is Great...Except When It Isn't

I've been a big fan of Test Driven Development (TDD) ever since I first started using it to write FlexWikiPad (FWP) about a year ago. In fact, that was one of the reasons I wrote FWP in the first place, as an excuse to see what the fuss about TDD was. It turned out to be a huge win for FWP, and I've been using it for everything I write since then. Until now.


Having spent a good chunk of my free time in the last two months writing RichTextEditor, my first real WinForms control, I slammed headlong into a problem that many others have had before me: writing a test-driven component that has a complex relationship with its container. You see, the main tenet of TDD is based on the idea that you simulate the client of a component before you write the component. These simulations usually take the form of method calls, since usually what you're testing is a simple algorithmic class.


Sometimes what you're testing is a little more complicated, like a form. In cases like that, testing gets a bit more complicated too, because now you have to simulate a user clicking buttons and entering text. But even that isn't that bad if you separate out the windowy bits of the application (the view) from the bits that react to it (the controller). Then you just test the controller by making calls that simulate events in the view. That's how FlexWikiPad is developed, and I've been very happy with it.


But sometimes, what you're testing is a lot more complicated, like a WinForms control. There, the thing we have to simulate is the windowing system itself, since that's really the client of my control: Windows sends events to my control, and my control sends painting commands back. Making matters worse, at the time I didn't even know what messages to expect, and what should happen in response to them. As a result, I found myself at a loss to write tests for my control.


So I didn't. I tested it the old fashioned way: manually. Was it more error-prone? Yes. Does it make bug regression more difficult? Yes. Did I have any other choice given my time and resource constraints? Not really.


Note, however, what I am not saying here:



  1. That TDD doesn't work. It actually works very well when simulating the container isn't too hard. Which is most of the time.

  2. That TDD doesn't work in GUI scenarios. I've used it very succesfully when building applications. Just not RichTextEditor.

  3. That TDD never works for control development. The limiting factor is being able to simulate the exchange of messages between Windows and your control. If this is complex, at some point simulating it will be too much work. But if it's simple, you might manage it just fine.

  4. That you can't use TDD at all if you're writing a complex control. I actually still used it in RichTextEditor to develop the undo/redo logic of my control, since that stuff is decoupled from the rest of the control, and has a simple interface. It was very helpful for that portion of the development.

Another thing to be aware of is that I never really explored automating my testing process in other ways. For example. a macro recorder could be used to send keystrokes to my control, and possibly to test the results in one way or another. NUnitForms has a Recorder that might help in this regard.


Overall, I'm still a huge fan of TDD, and still plan to use it whenever I can. It's just that now I have a better idea of what “whenever I can” means.

Thursday, October 14, 2004

KDiff3 - a new favorite

Diff and merge tools are critically important to pretty much any real development effort. I've been using WinMerge for a few months, and have been mostly happy with it. It doesn't do three-way merge, but hey, it works.


Then the other day I ran across KDiff3 (which is free, same as WinMerge), and I like it a whole lot better. But some of the features it has that make me like it better than WinMerge:



  • Supports three-way merge

  • Supports directory merges

  • Seems to be faster than WinMerge

  • Will word wrap long lines at your option

But I think the nicest feature is that it shows you not just what lines differ, but actually what's different in those lines. That's really handy for long lines, or for those times where you're diffing an XML file that has no linebreaks in it.


On the downside, it's harder to use and uglier than WinMerge - it's clearly a developer power tool. Since I'm a developer, I don't mind.

Tuesday, October 12, 2004

RichTextEditor

Wangdera is my company (my wife's name is Wang - get it?), and I've set up a Source Forge project for us to publish whatever we feel like. Well, tonight I shipped the first release of the Wangdera Control suite. If you download Wangdera.Controls.dll, what you'll get is two Windows Forms controls:



  • RichTextBox2 - extends the Windows Forms RichTextBox control to allow you to do more types of formatting, as well as giving you a way to apply a whole bunch of formatting all at once in an efficient way.

  • RichTextEditor - extends RichTextBox2 with autocomplete lists and enhanced change notification.

I'm particularly excited about RichTextEditor, because autocomplete lists plus decent change notification plus advanced styling mean it's a pretty good basis for building simple (and perhaps not-so-simple) IDEs. I've already used it at work to write a lightweight SQL statement editor that turns keywords blue and strings green. I call it RichTextEditor not because I mean for it to edit Rich Text, but because I mean for it to be a text editor with rich display capabilities.


I wrote RichTextEditor with a particular goal in mind. You probably know that I've been working on FlexWikiPad for close to a year now. I've been using the scintilla control in it until now, via the ScintillaNET wrapper that makes it usable from .NET. For the most part, it's a pretty solid component, but I've always found the API to be a bit weird. And lately I've started to rub up against the edges of the styling model...nothing I couldn't work around, but it would make me do some stuff in a way I don't like.


Before running off to reinvent the wheel, though, I poked around a bit to see if I could find something else. The #develop IDE has an open source text editor component, but it's GPL, and that would make it hard for me to use in the places I want to use it. So I started looking at RichTextBox. It almost worked, and I figured if I could just tweak one or two things...two months later here I am, a shiny new invention I call “the wheel“ in my hand.


I could have just rolled RichTextEditor into the FlexWikiPad code, but I thought that this is the sort of thing that other people would want to use standalone. Hence the release in the Wangdera.Controls package. If you have a use for it, give it a try and let me know about any bugs or feature requests you might have.


My plan from here is to start integrating RichTextEditor into FlexWikiPad, while at the same time completely overhauling the formatting engine in FWP. I think I can increase performance, increase flexibility, and increase capabilities all in one go. Well see, of course; RichTextEditor works well enough in my tests but the true test is employing it in a real world application.


Here's a screenshot of the sample app I include with the Wangdera.Controls package. It shows some of the capabilities of RichTextEditor:


Tuesday, October 5, 2004

Disk Tray

I generally have no complaints with the computer I've been given to work on at my client. It's reliable, it's plenty fast, and they're good both about quickly fixing what goes wrong and not getting in my face with a bunch of arbitrary standards. However, the one complaint I have is that since I program with my headphones on, and since the computer actually sits under my desk and sort of behind me, I can't see or hear drive activity. Working on a laptop most of the time, I'm used to seeing the drive access light flicker as a sign that “something is going on”.


I knew I couldn't be the only person for whom this was a problem, and I was right. A few moments of Googling turned up Disk Tray, which seems (so far) to be a stable and capable little app for showing disk activity by blinking lights in the system tray.

Saturday, October 2, 2004

Pushing Towards a SolidRelease

David Ornstein is sending out a rallying call around FlexWiki.We're recruiting developers in an effort to fix the little things that are wrong with FlexWiki. It's pretty stable and fast now, but there are enough corner cases that an effort like this could really help. So check out David's post and sign up if you've got interest in contributing.