January 2004 - Posts
If you take a look at KB article 320348 you might think it was the holy grail if you were trying to figure out how to compare binary files using the .NET Framework. However, the code isn't really written all that well and to the less astute programmer, it might go straight into production use without so much as a code change to make sure the routine worked properly. So what am I worried about from this function?
1. Not checking the null string case. You really shouldn't pass a null string into a FileStream. Just not good coding practice.
2. Not checking for file existence before creating the FileStreams. “Try“ing for exceptional programming they are (without the try).
3. Not putting the FileStream's into a using statement or something that protects their closure if something goes wrong:
(for instance, if FileStream1 exists and FileStream2 throws an exception FileStream1 stays open a while.)
I can live with the rest of the code, it doesn't seem all that bad. But the question remains. Should KB articles that attempt to create non-existent technology do so with the mindset of LCS (least cost solution) or should they adopt a best practices approach? Should the code be usable out of the box, or should it simply be a technology sample that needs to be cleansed by the proper authorities before being used in an actual application? I welcome any comments, negative or positive, since I'm really curious what other people think.
http://support.microsoft.com/default.aspx?scid=kb;EN-US;320348
So I took the time to write some code today to process a flat file. The flat file didn't have too many rows, only about 1800, so I figured the routines would run farely fast. They did, at about 65 milliseconds on average parsing a CSV file with 8 or so fields into a strongly typed data structure, and then placing said structures into an array list.
I did some neat things with the structures, like making them sortable on any field in any direction, etc... But that wasn't the part that was hanging me up. I thought the darn code should be running a bit faster. Since the code is a basic string.Split, a couple of int, bool parses, and a datetime parse along with the object construction I figured the problem had to be in the parse routines. Now, I know that integer parses can't be that darn slow, so I left those in. I did, however, take out the datetime.Parse. to my surprise the speed came down to 23 milliseconds or less. I basically got a 200% performance increase by removing a single datetime.Parse line. I realize that parsing dates must be a fairly hard task, but I would think if the exact structure of the date is know, the parser could be very fast and very determinate.
Well, just figured I'd point out to beware of any DateTime fields since they tend to be slow in the parsing area. Maybe someone from the BCL team can comment on how to make better use of it. I did try taking some examples from the DateTime best practices guide and pass in a custom ParseExact format. It did get a little bit faster, and actually dropped me down to an average run time of 41 ms, so I guess I have to say it got a LOT faster than it was previously. I'm still thinking a custom formatter class run over top of the string might yield an even faster result because of the complex code used by the DateTime class in order to switch to specialized methods based on my custom parsing format. After all, DateTime is really a swiss army knife when all I really need is a sharp stick to poke someone in the eye with.
A friend of mine is getting into game programming. He is actually heading back to college and taking the necessary classes to break into the field. Since the first few semesters will be kind of bogus in terms of actual game development stuff I'm working with him on some various projects so that when he gets to the harder courses he is ready for them.
He kept mentioning that he had worked on a basic tic-tac-toe game in Visual Studio. I think everyone tries this out at some point. Almost like a challenge I'd say, “How fast can I code Tic-Tac-Toe!”. But I think everyone else that sits down to this task has a different goal than I do. When I sit down to a new game I think about the game engine design principles and how I can apply them to tic-tac-toe. Who cares how fast I plug it out, or even how pretty it is, IMO, but instead would you use the same principles in a larger commercial style game.
So I went over his Tic-Tac-Toe game (don't kill me for posting about this here John, others can learn by your example ;-) and he had taken the how fast approach. Then in the same email he had a large list of feature enhancements he wanted to work on. Basically things he couldn't do during the initial phase of development and so he wanted to figure each of them out in turn. The problem was, because of the initial engine design, everything he does is going to be a bolt-on, rather than an extension of the engine. He never separated his presentation layer from his input layer, or his input layer from his game engine layer, etc... Basic principles, that when in the game development field, you try almost always to follow (and when you don't you wind up as a post-mortem in Game Developer Magazine). So here is the contents of the mail I sent back since I think it might get people's thought processes going about how to organize code (even non game type code) to make it more extensible.
I'll run through some stuff for you. Basically what I need to point out is that Tic-Tac-Toe as a game really only has a single engine. I'll run through some basic concepts to define what a game engine is and how it works:
Fact: A game engine consists of a game state, methods to change that game state, and methods to report that game state.
Fact: A game engine should be independent of user input methods, display, and any other connection that doesn't have to do with a game state or the methods needed to change the state.
Fact: A game engine has a lifecycle that consists of setup, iteration, and conclusion.
So think of a tic-tac-toe engine (make it a class) that is independent of the UI (have the UI interact with the engine by using it to make moves and then displaying the results of those moves rather than allowing the UI to actually take part in storing the game state) and the user input (don't have the buttons pressed set game state directly, instead have them call methods on the engine that change game state in a protected manner).
So a tic-tac-toe game might have the following game engine layout:
Setup
Clear Game State
Select Piece that Moves First (X or O)
Iteration
If GameOver Throw Exception
Make Move by turning a click in the UI into a game engine method MakeMove(cellX, cellY, PiecesEnumeration.O)
If cellX or cellY is taken or PiecesEnumeration doesn't mesh with the current move piece Throw Exception
Else SetStateOfBoard
CheckForWinConditions
If WinConditions SetEndGameState Goto Conclusion
Else CheckForDrawConditions
SetEndGameState Goto Conclusion
Conclusion
ServeResults
So out of the things you wanted to add to your game. Most of them were UI items, not game engine items, but you don't actually have a game engine yet. Lets finalize a game engine, something cool that works well that can be played from a command line, a winforms UI, or a web page with relative ease. Thats the key to an awesome game design.
So what you should send me is:
a) A single class that I can compile into a library
b) I can link that library into a new application I'm writing and add the ability to play tic-tac-toe
As more and more places are setting up free wi-fi access points to bring in business, more and more people are grabbing wi-fi cards for their laptops and palm devices. Personally, I think the freedom of being able to freely connect to the Internet from the sidewalk very interesting, and I'm definitely enjoying the anonymity of surfing on a system that doesn't track my existence.
But what about modern day hackers, what kinds of benefits are they deriving from this? Well, in the 90's a lot of money was spent on protecting you via hardware and via tracing design patterns. Pretty much every ISP you work with now will give out your home information to the FBI in a second if requested due to you hacking someone over in Europe. There is simply too much of a paper trail with any home connection that you might achieve, even if you use the age old process of tunnelling through multiple intranet clouds, assuming you've already gained access to any. This means physically, you've been nailed down to a physical existence somewhere on earth, something that scares most virtual netphiles to death since they no longer have the privacy of logging off and removing themselves from *dangerous* situations.
Software firewalls are getting pretty prominent in the market as more people disconnect.and find they need more protection than the OS provides (or simply feel better with the increased security). Heck, Costco sells stacks of the new Norton Firewall, and they go through those stacks very quickly each day as people scramble to protect themselves. Hackers have been whacking hardware firewalls for years though, including those protecting some of the most advanced systems on the Internet. Systems where the design is kept so secret that only gentle black box probing is going to get them any information as to where the access points might be. With software they get the added benefit of spending 50 bucks and using a disassembler to learn the secrets of the program, a treasure trove of information on how to get through.
So what am I saying? Wi-fi access points are becoming a haven for hackers. They gain back all of the edge they had before the big push for security. The get anonymity, they get it for free (AOL used to do this for the inititated ;-), they generally get a decent connection, and they get to walk away when things get hot. Most importantly, they regain the ability to slowly probe systems over time, taking small steps, rather than the recent change where hacks need to be planned for months on end.
Note: This article does not apply to all the CSS hackers and script kiddies out there that don't know how to use a disassembler, cause a buffer overrun, or raise their security privs when logged in using a normal guest account. You guys are only prominent in news feeds because of click happy email freaks.
While helping someone with a DirectX problem I came across what I think might be a neat feature for Windows Forms. You can always gamma correct your UI to a lower brightness value by layering a transparent black from over the top. This as mentioned in the title is useful for telling the user the application is in a sleep state, and it means that you can control how they interact with the application when they come back (by say, making them click the transparent form). So what exactly am I saying? Well, first off create a new blank form without any borders or titles and attach a MouseUp handler so you can dismiss the form later.
this.FormBorderStyle = FormBorderStyle.None;
this.Text = "";
this.MinimizeBox = false;
this.MaximizeBox = false;
this.ControlBox = false;
this.BackColor = Color.Black;
this.TopMost = true;
this.ShowInTaskbar = false;
this.MouseUp += new MouseEventHandler(this.Form_MouseUp);
this.VisibleChanged += new EventHandler(this.Form_VisibleChanged);
Then you are going to want to set the opacity of the form to some value, like 20%. This darken the the controls on your form considerably.
this.Opacity = 0.2f;
Finally, you'll need to show this form using ShowDialog(this) from within the parent form. You might also set the Owner property to the current form, so you can set up your transparent dialog in the proper location. You may not actually need this, but do it just in case. If the main form is minimized, it will also minimize the owned form (dialog), so I think that is pretty cool.
GammaForm gammaForm = new GammaForm();
gammaForm.Owner = this;
gammaForm.ShowDialog(this);
Finally, you'll work through those events. The mouse event needs to close the gammaForm, and the VisibleChanged should position the gamma form over top of the parent.
private void Form_MouseUp(object sender, MouseEventArgs e) {
if ( (e.Button & MouseButtons.Left) == MouseButtons.Left ) {
this.Close();
}
}
private void Form_VisibleChanged(object sender, EventArgs e) {
if ( this.Visible ) {
this.Location = this.Owner.Location;
this.Size = this.Owner.Size;
}
}
Wooh, rest assured the code is functional, I just went ahead and used it. In order for the minimize to still work though, you'll need to use the Show() method instead of ShowDialog(this). The reason here is that when a dialog is shown you can't really interact with the main form's control features in the task bar. I'm sure some Windows APIs or spy utils could probably do it, but that doesn't count.
I have definitely wanted to get access to the gradient title colors a number of times. I'm sure some people have gone out and written their own calls to get these, but others I'm betting haven't. Out of all system colors, only two don't show up in the KnownColors and therefore SystemColors areas of System.Drawing. These happen to be GradientActiveCaption and GradientInactiveCaption. I'm including some source below that grabs colors just for these two items. You could probably do some work and have them automatically create linear gradient brushes too, but I'm not going to do all of the work for yah.
using System;
using System.Drawing;
using System.Runtime.InteropServices;
public class SystemGradientColors {
[DllImport("user32.dll")]
private static extern int GetSysColor(int nIndex);
// Constants for gradient colors
private const int COLOR_GRADIENTACTIVECAPTION = 27;
private const int COLOR_GRADIENTINACTIVECAPTION = 28;
private static Color colorGradientActiveCaption = Color.Empty;
private static Color colorGradientInactiveCaption = Color.Empty;
public static Color GradientActiveCaption {
get {
if ( colorGradientActiveCaption == Color.Empty ) {
int color = GetSysColor(COLOR_GRADIENTACTIVECAPTION);
colorGradientActiveCaption = FromWin32Value(color);
}
return colorGradientActiveCaption;
}
}
public static Color GradientInactiveCaption {
get {
if ( colorGradientInactiveCaption == Color.Empty ) {
int color = GetSysColor(COLOR_GRADIENTINACTIVECAPTION);
colorGradientInactiveCaption = FromWin32Value(color);
}
return colorGradientInactiveCaption;
}
}
private static Color FromWin32Value(int value) {
return Color.FromArgb(value & 0xFF, (value >> 8) & 0xFF, (value >> 16) & 0xFF);
}
}
I think the concept behind the ResourceManager is great, but I almost always find instances where it just isn't easy to get all of my resources formatted appropriately. What I've been doing lately is simply packing my resources into the assembly as binary streams. It seems this method I've been using for so long is actually unknown to most people, and they tend to find it quite useful. I namely use it for bitmaps since they have a Stream constructor overload, but I also use it whenever I have a boilerplate config file, template, or anything else that I might need to set up the user experience without having to ship a bunch of files. Here is a sample:
csc /t:exe /res:minimalConfig.config /res:defaultDocumentTemplate.template /res:superManUnderoos.bmp MyApplication.cs
The above results in a bunch of external files getting included right into my application. Then I can set these up right at the beginning (normally this will be a Windows Forms application) of the Main method or in the Load event if I'm using Windows Forms.
using System;
using System.Drawing;
using System.Diagnostics;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
public class SimpleAppForm : Form {
private Bitmap splashScreen;
private string docTemplate;
public SimpleAppForm() {
this.Load += new EventHandler(this.Form_Load);
}
private void Form_Load(object sender, EventArgs e) {
Assembly cur = Assembly.GetExecutingAssembly();
// Loading a bitmap
splashScreen = new Bitmap(cur.GetManifestResourceStream("superManUnderoos.bmp"));
// Loading a stringy template
using(StreamReader sr = new StreamReader(cur.GetManifestResourceStream("defaultDocumentTemplate.template"))) {
docTemplate = sr.ReadToEnd();
}
// Writing out a default configuration file
if ( !File.Exists("settings.config") ) {
using(StreamReader sr = new StreamReader(cur.GetManifestResourceStream("minimalConfig.config"))) {
using(StreamWriter sw = new StreamWriter("settings.config")) {
sw.Write(sr.ReadToEnd());
sw.Close();
}
sr.Close();
}
}
}
[STAThread()]
private static void Main(string[] args) {
Application.Run(new SimpleAppForm());
}
}
Remember to put the right types of security restrictions around the file writing if you plan on using that code-branch, but party as normal with the rest of the code since you are just pulling binary feeds out of your assembly and loading them up for use. Hopefully this little tip will help all those users wondering what they need to do to get their apps shipping without an installer because they are single file copy deployable.
I'm dense guys, and I'm pretty sure of it. I've been playing with .Text for a few days, and I still haven't managed to subscribe to any feed on my blog that feeds the articles. I'm assuming here that while it is nice to link long articles into your blog, it would also be nice to have all of my articles agg'ed down into my RSS reader so I can laugh at myself on planes, in coffee shops, or any other time I'm not connected to the Internet.
The admin interface to .Text seems to speak that the feature exists, hence a column saying Agg views in the Articles tab. However, it is always 0, with any number of web views based on click throughs from my blog posting where I talk briefly about the article. Would someone please smack me down and point out the RSS feed for the articles, or are others maybe thinking the same thing (hopefully not at 4:10 in the morning the way I do, but thinking it nonetheless).
This is the first article in a series of about 5-10 articles on a plug-in framework I'm developing. Don't run away and hide yet, the intent of the articles is to end with an intense study of providing a security system to allow arbitrary user code to run. I'll be borrowing ideas from the .NET Terrarium, existing plug-in architectures, and my own work on several image editor applications with plug-in interfaces.
The first article is a rather long-winded run-down of plug-in marking within an assembly. Most of the stuff may seem common sense, but I've seen a number of plug-in framework implementations and everyone is doing something different. This is the same thing that happens in the unmanaged world, but you would think there would be a more unified process using managed code. I really think there is, so I've defined all the ways you can mark types in an assembly as plug-ins and weighed the pro and cons of each method along with source code to demonstrate how you would use each, the performance, and how they can be used together to provide a rock solid marking implementation.
Plug-in Framework (Part1): Marking Types for Consumption
Wow, I got an email from a user (thanks for the heads up), that my posts couldn't be printed (I actually said something worthy of black letters on paper). Turns out most of the *styles* associated with .Text simply won't print out on a normal printer. Why? I'm not sure.
But I found that the cooler skins like Lighty with the neato graphics doesn't print at all. You simply don't get any message body, but you get to see the entire menu on the left hand side. Very strange. Any of the skins that has a right hand side border (marvin3) prints message bodies within about a 2 inch area of the center of the paper. Took a LOT of paper to print even a short message.
I wound up using the Marvin2 base style because it prints using a wide right portion of the paper for the message body and actually allows the message body text to present itself on a b/w printer. So a note to all, be nice to the printer, until .Text maybe gets better styles. Or take the personal time to write your own.
More Posts
Next page »