Tuesday, June 16, 2009

XNA Game Studio 3.1

cco_shell_default_header_xna_logo_print[1]

XNA Game Studio 3.1 has just been released! Download XNA GS 3.1 and check out the walkthrough for upgrading your old projects to v3.1!

A quick overview of what is new:

  • Avatar Support: Render and animate Avatars to use in your game to represent gamers and other characters within your game.
  • Xbox LIVE Party Support: Enabling gamers to communicate, even when each gamer is not playing the same game in the same multiplayer session. LIVE Party supports up to an eight-way group voice chat for gamers and keeps gamers connected before, during, and after a gameplay session, persisting across title switches.
  • Video Playback: XNA Game Studio now supports the ability to play back video that can be used for such purposes as opening splash and logo scenes, cut scenes, or in-game video displays. This set of XNA Framework APIs supports the following features:
  • Full screen video playback
  • Video playback to simple textures in game
  • Control of playback such as pause/resume and stop
  • Retrieve properties of the video, such as playback time, size, and frame rate
  • Determine the type and usage of the audio track, such as if it has music, dialog, or music and dialog
  • Play back multiple video streams at the same time
  • Audio API: 3.1 has a new usage pattern of SoundEffect.Play. Sound instances created by Play calls are disposed automatically when playback ends, and SoundEffect.Play returns a Boolean to indicate success or failure.
  • Content Pipeline Enhancements: improvements making it much easier to add customer types (custom attributes for run-time of an object and run-time type version of an object, and the ability to determine if deserialization into an existing object is possible).
  • XACT3 Support: includes support for XACT3 with new features including the ability to enable a filter on every track, and support for the xWMA compression format.
  • Visual Studio Changes: XNA Game Studio 3.1 supports both 3.0 and 3.1 projects, and it includes support for upgrading projects from 3.0 to 3.1.
[This content is uploaded from my email.]

Thursday, May 21, 2009

Hello World!

A "Hello World" program is a computer program which prints out "Hello, world!" on a display device. It is used in many introductory tutorials for teaching a programming language. Such a program is typically one of the simplest programs possible in a computer language. Some are surprisingly complex, especially in some graphical user interface (GUI) contexts, but most are very simple, especially those which rely heavily on a particular command line interpreter ("shell") to perform the actual output. In an embedded system, the text may be sent to a liquid crystal display (LCD), or the message may be substituted by some other appropriate signal, such as a LED being turned on.

Purpose
A "hello world" program has become the traditional first program that many people learn. In general, it is simple enough that people who have no previous experience with computer programming can easily understand it, especially with the guidance of a teacher or a written guide. Using this simple program as a basis, computer science principles or elements of a specific programming language can be explained to novice programmers. Experienced programmers learning new languages can also gain a lot of information about a given language's syntax and structure from a hello world program.

In addition, hello world can be a useful sanity test to make sure that a language's compiler, development environment, and run-time environment are correctly installed. Configuring a complete programming toolchain from scratch to the point where even trivial programs can be compiled and run can involve substantial amounts of work. For this reason, a simple program is used first when testing a new tool chain.

"Hello world" is also used by computer hackers as a proof of concept that arbitrary code can be executed through an exploit where code should not be allowed to be executed, for example, on Sony's Playstation Portable. This is the first step into making home-made content ("homebrew") usable on such a device.

Wednesday, May 20, 2009

Thinking Like a Programmer

A few weeks ago, I was asked to participate in a webinar being done by AccuRev (the company) around the topic of continuous integration using AccuRev (the software) and CruiseControl.NET. One of the guys on the AccuRev team was preparing a video using Camtasia, and we agreed it would be easier for me to record my part using the same tool and we'd then stitch our two projects together to product the final video. I have used other screen-capture/recording tools in the past for some of our internal training needs, but I hadn't really done one in a while and I had never done one using Camtasia (though I knew of the software and probably tried a demo some years back). So, I grabbed the latest available demo version (5.0) and started playing.

First things first: great software. I found it very easy to use, and very easy to put a few "special touches" here and there. All-in-all, a good experience and I recommended to my boss that we switch to Camtasia whenever we get around to making some new training videos. There was, however, one problem I ran into which was a bit frustrating: no way to change a setting which positively had to be changed to make the software usable for my setup. The solution? Think like a programmer.

First off, let me say there is a very good chance I simply missed it; the setting exists, but I failed to find it.

My goal was simple: record a voice-over for the 10+ minutes of screen shots+slides+video I had spent hours laying out in my Camtasia project. The software made this ability obvious, so I never bothered to verify it was going to work (yes, I know - mistake number one). Of course, when it came time to use the feature I discovered it was not working: the button to actually begin recording audio was disabled, with no apparent way of enabling it or even viewing the cause of it being disabled. I assumed a problem with my setup: I had my Logitech USB microphone plugged in to the computer, which I had never used on this system before (or any system for that matter: I snagged it from my Rock Band pile in the living room) and figured the issue was either with the microphone itself or my sound card or my Windows setup or some other thing unrelated to Camtasia.

Then, while poking around the Camtasia docs and installed applications, I came across the "Camtasia Recorder" program. This is a separate application specifically for recording audio. I fired it up and, again, was unable to record anything. However, in this app, there is an easily accessible "audio options" link which, when clicked, displays the dialog shown below, which made me realize that either Camtasia or my system in general had decided that my default audio device was "Bluetooth Audio" - not my Logitech microphone.


Upon clicking the drop-down list and selecting the correct option, this application was perfectly happy to allow me to record audio using the USB microphone. I assumed my problem was solved, shut-down the "Camtasia Recorder" application, re-started the main "Camtasia Studio" application and...wait...I still can't record an audio track within my existing project. Hmm... No problem, really. I guess the two apps don't share settings and I just need to find the same "Audio Options" dialog I found in the other application. If you haven't guessed yet, the "Audio Options" dialog was nowhere to be found within the "Camtasia Studio" application. I looked pretty darn hard and no luck. Again: could just be me; maybe it's really there, but if it's that hard to find it's as good as non-existent to me.

After searching Google for a bit and finding no information specific to Camtasia version 5.x, I finally decided to think like a programmer. (I play Mr. Manager role for 85% of my day, so I'm a little slow to come up with bright ideas when needed.) It seemed to me that there must be a setting stored somewhere which Camtasia Studio is using to determine the audio device to use for voice-overs. I just needed to find it. At first, I gave them too much credit: I searched the "Documents and Settings" area on my machine looking for nicely formatted config files. Then I decided it was time to try the registry and, low and behold, I found the culprit.


I jumped back into the Camtasia Recorder application to check the "Audio Options" dialog again, noted the exact name it displayed for my USB microphone and then changed the "WaveInDeviceName" value to match. I re-started Camtasia Studio, loaded up my project and, whaddya know, it was perfectly happy to allow me to record audio using my microphone. Problem solved.

Lesson learned: all software is created by humans, and most of us are not breaking new ground. If you're having trouble getting some third-party software to do what you want, step back and think about how you would have made the software work if you were the one who had written it. You might just come up with a way around your problem.

Tuesday, May 19, 2009

Great Hacker != Great Hire


I thoroughly enjoyed reading Paul Graham's recent essay Great Hackers. His sermon is well-written, and I assume it played very well when he preached it to the choir at OSCON.

Graham describes the notion of a "great hacker", which he seems to roughly define as a programmer who is several times more productive than average. (Please note that some people use the word "hacker" to describe programmers who engage in illegal activity. That connotation is not applicable here or in Graham's essay.) He then asks the following questions:

How do you recognize [great hackers]? How do you get them to come and work for you?"

Note carefully: Graham proceeds from the assumption that we do in fact want to hire these great hackers, but he never explains why.

I concede that this assumption is intuitive. After all, doesn't every company want the most productive employees they can hire?

But this assumption deserves to be examined and challenged.

For the love of the code

Graham begins his description of great hackers by explaining the intrinsic motivation and passion they have for writing code:

Their defining quality is probably that they really love to program. Ordinary programmers write code to pay the bills. Great hackers think of it as something they do for fun, and which they're delighted to find people will pay them for.

On this point, we agree. The best developers simply love to create software. They get paid, and their compensation is important, but it isn't really the primary reason why they write code. They wrote code before they were getting paid for it. They would continue to write code even after winning the lottery. When I hire developers, I am looking for this quality.

However, the remainder of Graham's essay does a pretty good job of explaining why many small ISVs might not want to hire a "great hacker". In a nutshell, great hackers are often very fussy people.

Fussy about tools and platforms
Graham explains the well-known fact that great hackers are extremely picky about the tools, platforms and technologies they use:

Good hackers find it unbearable to use bad tools. They'll simply refuse to work on projects with the wrong infrastructure.

Bad tools? Wrong infrastructure? Graham sounds like he is right on the money. Nobody could object to the idea that great hackers care deeply about these kinds of choices, right?

Unfortunately, Graham goes on to explain what great hackers mean by "bad tools" and "wrong infrastructure". Painting with a very wide brush, he observes that great hackers don't use technologies like Windows and Java. They prefer languages like Python and Perl. They prefer to use open source technologies whenever possible.

I'm not saying I am a great hacker, but I do sympathize with this fussiness. I have similar religious preferences about technologies. I really do like Python. My personal server runs Debian. The first things I install when I repave my Windows machine are emacs and cygwin.
However, I work at an ISV. I love building software, but SourceGear is not my hobby -- it is my profession. We sell products to users. We have learned to value the needs of the users over our own preferences.

Graham seems to suggest that if we choose to build our products on the technologies that great hackers prefer, then it is more likely that we will be able to hire them. This opinion may be true, but it ignores the fact that technology choices have marketing implications. I've written about this topic several times now:

Law #21: "These may not seem like marketing decisions, but they are. Technology choices have big marketing implications. When you choose a platform, you define the maximum size of your market."

Geek Gauntlets: "We need to talk about what customers want, but our own preferences get in the way. We bring our technology prejudices and biases to the discussion, often without ever being aware of the problems they can cause."

Be Careful Where you Build: "As developers in a small ISV, our productivity is important, but it must be secondary to the comfort and preferences of our users."
The higher productivity of a great hacker is a big advantage, but probably not big enough to overcome our attempts to sell something that users don't want.
If Graham is right, a great hacker is someone who believes that his own preferences are more important than doing what is best for the users. Small ISVs don't need people like that.
Fussy about doing interesting projects

Graham goes on to explain how important it is for great hackers to be doing interesting projects:
Along with good tools, hackers want interesting projects. It's pretty easy to say what kinds of problems are not interesting: those where instead of solving a few big, clear, problems, you have to solve a lot of nasty little ones. One of the worst kinds of projects is writing an interface to a piece of software that's full of bugs.
Here again, I am sympathetic. I like interesting stuff too. My To-Do list tells me that I am supposed to be working on some enhancements to our online store website. Frankly, that programming task doesn't interest me very much. I'll confess that I'm procrastinating on that particular task.

However, I work at an ISV. I love building software, but SourceGear is not my hobby -- it is my profession. We sell products to users. The reality is that lots of highly profitable software development tasks are just not very interesting.

Graham strikes particularly close to home when he says, "One of the worst kinds of projects is writing an interface to a piece of software that's full of bugs." Our SourceOffSite product provides an Internet-based interface to a piece of software that's full of bugs (SourceSafe). That same product supports integration with IDEs by means of a piece of software that's full of bugs (the MSSCCI API). If we had been great hackers and refused to do this work because it is not interesting, we would have missed out on millions of dollars of revenue.

If Graham is right, a great hacker is someone who is not willing to do any of the un-fun things that need to be done. Small ISVs don't need people like that.

Fussy about interacting with users

Graham characterizes great hackers as people don't want to be involved with users:
Bigger companies solve the problem by partitioning the company. They get smart people to work for them by establishing a separate R&D department where employees don't have to work directly on customers' nasty little problems.

You may not have to go to this extreme. Bottom-up programming suggests another way to partition the company: have the smart people work as toolmakers. ... This way you might be able to get smart people to write 99% of your code, but still keep them almost as insulated from users as they would be in a traditional research department.

This kind of attitude is a big problem in a small ISV. I concede that it is frustrating to be interrupted when I'm working on a coding problem. I concede that users sometimes ask dumb questions. I concede that writing a great piece of code is more fun than figuring out how somebody screwed up their Web.config file.

However, I work at an ISV. I love building software, but SourceGear is not my hobby -- it is my profession. We sell products to users. Nothing here is more important than our users. Nothing.
Last year I wrote an article in which I claim that small ISVs should only hire "developers", which I define as "programmers who also contribute in non-coding ways". The thesis statement of this article said:

"For the purpose of this article, a "programmer" is someone who does nothing but code new features and [if you're lucky] fix bugs. They don't write specs. They don't write automated test cases. They don't help keep the automated build system up to date. They don't help customers work out tough problems. They don't help write documentation. They don't help with testing. They don't even read code. All they do is write new code. In a small ISV, you don't want any of these people in your company."

If Graham is right, a great hacker is someone who is not willing to help the people who use the software he creates. Small ISVs don't need people like that.
Bottom Line

Like I said, I enjoyed Graham's essay very much. He describes great hackers by enumerating all of their worst qualities, and yet, the essay still makes us want to admire these super-productive people. That's good writing.

But the essay causes concern. I worry that lots of small ISVs will read his article and believe that they need to hire great hackers. When great hackers are as fussy as Graham says they are, they're not worth the trouble. We want the super-productivity, and we want the innate love of software development, but we don't want all the extra baggage. Instead:



  • Hire people who care about users.

  • Hire people who understand the difference between a job and a hobby.

  • Hire people who want to contribute in lots of different ways to the success of the product.


It's okay to be in awe of these great hackers. But as a practical matter, small ISVs would be much better off hiring professionals.

Why is programming fun?


The below is an extract from Fred Brooks' (Frederick P. Brooks, Jr.) book, The Mythical Man-Month. This is one of the best explanations of why programming is so interesting. It touches on all aspects of the mystique of programming. If you haven't read the book, go out, buy it, and read it. The book was first published in 1974 and then republished in 1995. What Fred Brooks had to say then based on his experiences with the development of the OS/360 system is still relevant today.

"
Why is programming fun? What delights may its practioner expect as his reward?

First is the sheer joy of making things. As the child delights in his mud pie, so the adult enjoys building things, especially things of his own design. I think this delight must be an image of God's delight in making things, a delight shown in the distinctness and newness of each leaf and each snowflake.

Second is the pleasure of making things that are useful to other people. Deep within, we want others to use our work and to find it helpful. In this respect the programming system is not essentially different from the child's first clay pencil holder "for Daddy's office."

Third is the fascination of fashioning complex puzzle-like objects of interlocking moving parts and watching them work in subtle cycles, playing out the consequences of principles built in from the beginning. The programmed computer has all the fascination of the pinball machine or the jukebox mechanism, carried to the ultimate.

Fourth is the joy of always learning, which springs from the nonrepeating nature of the task. In one way or another the problem is ever new, and its solver learns something: sometimes practical, sometimes theoretical, and sometimes both.

Finally, there is the delight of working in such a tractable medium. The programmer, like the poet, works only slightly removed from pure thought-stuff. He builds his castles in the air, from air, creating by exertion of the imagination. Few media of creation are so flexible, so easy to polish and rework, so readily capable of realizing grand conceptual structures. (...)

Yet the program construct, unlike the poet's words, is real in the sense that it moves and works, producing visible outputs separately from the construct itself. It prints results, draws pictures, produces sounds, moves arms. The magic of myth and legend has come true in our time. One types the correct incantation on a keyboard, and a display screen comes to life, showing things that never were nor could be.

Programming then is fun because it gratifies creative longings built deep within us and delights sensibilities we have in common with all men.

"

Tips on writing clean code

Over the years I've found that there are some problems that tend to recur again and again. The idea with this blog entry is to write up some tips on this once and for all, in the hope that it can help people out there who struggle to write clean code.

The main goal with these tips is readability. This is important because usually your code has to be changed or reviewed by other people, and writing readably makes these people's jobs a lot easier. That may be obvious. What's less obvious is that it also makes your own job easier, because working on simple code is a lot easier than working on complex code, even while you are writing it, and the more readable code is always simpler.

An important part of making your code readable is to always work to communicate your intent. The basic idea is that it's usually not difficult to see what a single line of code does. The tricky thing is to see why it's doing what it does. So the more you can make your code communicate the thinking behind the code, the better it is. You'll see this point recurring repeatedly below.
I should add that most people seem to be aware of most of these rules, in a general kind of way. The main point of this posting is really to convince people that these rules are important. So important, in fact, that you should try to always follow them, and that you should have a really bad conscience about any code that breaks them. So bad that you just never write any such code. Some of these rules require you to write a little extra code, but I think I can claim that none of them cause you to actually lose time, on any project.

1. Always know why you are catching an exception
This has to be the most common mistake I see people make, and it seems to me that exceptions is a feature many people haven't really learned how to use yet. One of the reasons for this is probably that before the advent of Java the languages people used at university did not have exceptions, and so no rules were taught about this. It's not a trivial feature to use, so it's hardly surprising that people struggle.

Anyway, the cardinal rule is: if you catch an exception you need to have a good reason. Reporting an expected error condition to the user in a more friendly way is a good reason. Handling an expected, but unusual, condition is another. But very often people just swallow the exceptions with an empty catch block (this is a real nono), or they do like this:

private static List readLines(String fileName) {
String line;
ArrayList file = new ArrayList();
try {
BufferedReader in = new BufferedReader(new FileReader(fileName));
while ((line = in.readLine()) != null)
file.add(line);
in.close();
} catch (Exception e)
{
System.out.println(e);
return null;
} return file;
}

The catch block here does nothing useful. In fact, it hides useful information if the program were to crash. If you don't catch the exception, you get a traceback. If you do catch it you get much less. Plus, it takes up 5 lines, and it makes the method almost twice as big as it needs to be. Doing without is just a lot better.

That would give us this:

private static ArrayList readLines(String fileName) throws IOException {
String line;
ArrayList file = new ArrayList();
BufferedReader in = new BufferedReader(new FileReader(fileName));
while ((line = in.readLine()) != null)
file.add(line);
in.close();
return file;
}

2. Never declare implementation types
This is another thing I see very often: parameters, variables, or even return types that are really implementation types. You can see this in the code above, where ArrayList is used where List would do. There are several problems with this: ArrayList is longer, and you have to do a lot of work if you want to change what list implementation you are using.
The main thing, however, is that just using List communicates your intent that this be a list much more clearly. It says "I thought about this, and I really intend this collection to be a List, and not just any sort of collection". In other words: it tells the reader that you care about the order in this collection.

Another round of simplification brings us this:

private static List readLines(String fileName) throws IOException {
String line;
List file = new ArrayList();
BufferedReader in = new BufferedReader(new FileReader(fileName));
while ((line = in.readLine()) != null)
file.add(line);
in.close();
return file;
}

3. Use descriptive variable names
This is a rule that can be hard to follow, but in general variables should be named so that they make it clear what a variable contains. Sometimes this is blindingly obvious, and in these cases short names like i for loop indexes, in for files is perfectly OK. But if you use a longer name, try to make it meaningful.

In the case of the method above, what does file really contain? Yes, it does contain the file, but what it really is is a list of all the lines in the file. So why not call it lines? That would give us:

private static List readLines(String fileName) throws IOException {
String line;
List lines = new ArrayList();
BufferedReader in = new BufferedReader(new FileReader(fileName));
while ((line = in.readLine()) != null)
lines.add(line);
in.close();
return lines;
}

Still not perfect, but arguably a lot more readable than the original.

4. Cut-and-paste code
One simple approach that's suggested quite often as a way to improve people's code is to disable the paste function on every developer machine. While the idea may be a little over the top, the basic thought is sound. If you have a snippet of, say, 7 lines of code that do one thing, and you want to do it again to a different set of variables, don't copy and paste the code. Instead, make a function (or a method, if you're stuck with Java).

There are several reasons for this. One is simple brevity. Another is that it makes your code much easier to read, since you would effectively be replacing 14 lines of code with just 2. This would obviously be at the expense of an additional function/method, but since these stand alone and isolated from the rest of the code, their impact on readability is very low. The main reason, however, is that by doing this you make life much easier for yourself. Even if this is a one-time script, you are still going to change the code around. This is easier if it's broken up into parts, like functions/methods.

5. Variables and communication
One of the hardest things to pick up when reading code is to understand the flow of values through the variables in the code. (This is one reason why functional programming is popular.) This has several implications for how the code should be written.

For one thing, this means that you should try to declare variables as close to where they are used as possible. Let's say you write the following:

String tmp = null;
// 50 lines that don't touch tmp
tmp = whatever;
// ...

This means the reader has to scan 50 lines to see if tmp is used anywhere in there. Merging the assignment and the declaration would remove this problem completely, and would lose you nothing.
Another thing this means is that if a variable is only used inside a block (if statement, while loop, or whatever), then it really should be declared in there. Imagine you write this:

int tmp;
for (...) {
// code that uses tmp
}
// no more mentions of tmp below this point

In this case, you could have declared tmp inside the for loop. Not doing it sends the signal that "I'm going to keep using this variable" and forces the reader to try to figure out what happens with it later. Moving the declaration inside the loop means that you can't use the variable after the loop, which makes the code much easier to read.
A third consequence is that you should really work hard to keep your functions/methods short. If you have a function/method that's, say, 400 lines long it becomes almost impossible to track the data flow through it. There will just be too many variables and too many assignments to keep track of. So this is a real no-no. Just don't do it. And as usual with these rules, this is a rule that will also help you get the code right the first time, so this is worth doing even if you will just write the code and then discard it.

In fact, if you really do keep your methods short, a lot of the other rules here become less important, because the impact of breaking them will be lessened. The reason is of course that it's very hard for a short method to be really difficult to read. There's so little code in a short method that you can almost always digest it quite easily. So you could think of this as being the most important rule.

6. Don't preserve return values you don't use
This is also related to making it easier to track data flow. Let's say you write something like this:

boolean present = myCollection.remove(object);

You could have written it like this, however:

myCollection.remove(object);

You can safely assume that any reader of your code will know this, and therefore using the first form is a signal that "I care about this return value, and I'm going to use it for something". If you don't, you'll be confusing the reader, because they are assuming that they now need to figure out what you're going to do with this variable.
Of course, leaving it out saves space, too, so there's really no reason not to drop these variables.

7. Omit needless code!
It's quite common to find code that's commented out, but still hanging around. This is mainly bad because it bloats the code unnecessarily. People seem to do this because they want to have the possibility to bring the code back, either because they are writing an alternative they are not sure about, or (and this seems quite common) because they don't dare to delete it. However, in nearly all cases there is no real reason to keep such code around. You should be using version control, and that means you could always find any deleted code again.

Also, since this code is no longer compiled or executed there is no real difference between commenting it out or deleting it. You've still made the change. The difference is that now it's quite likely that this code will slowly move out of sync with the code around it, so that by the time you find you want it again it will no longer work. That actually makes the code dangerous, because it tempts you to include code without understanding what it does. (If you really understood it you could retype it quite quickly even if it was deleted.)

Of course, commenting out code while you are working on the code is fine. I do that a lot. However, I never check in code that is commented out, and whenever I find such code I delete it, without asking anyone or telling them. If they wanted the code they shouldn't have commented it out. And it will be in the version history, anyway.

Nested Gridview Using C#

Gridview control in ASP.Net 2.0 can be nested in other Gridview control to display the related items of any item retrieved from relational SQL database using C# code. To work with nested Gridview control in ASP.Net 2.0 using C# you must be familiar with Type casting of control objects, Gridview DataKeyNames and DataKeys array collection of datakey values for each row of GridView and FindControl function.


GridView DataKeyNames:
DataKeyNames is an array collection of data key fields or you can say primary keys specified in the GridView control retrieved from the SQL database table that can used to uniquely identify the record. For example you want to edit any record using Gridview control then to pass the unique id to sql command to execute and edit the requested record, you can retrieve that id from the DataKeyNames collection of the GridView.




GridView DataKeys:
To get the value of data key field for any particular row of GridView control using C# code you can use DataKeys array by passing the rowIndex of GridView control to get the unique identity of that record.



GridView FindControl:
FindControl function is used to find any control by its server ID reference. Using FindControl function you can find the nested GridView control from the ItemTemplate cell of any row of ASP.Net GridView control.



To work with nested GridView Control you can use the Northwind database of SQL Server 2000. Consider the sql database tables categories and products to display the records. For example, you can display the category names as Title and related products in the nested GridView.