Wednesday, April 6, 2011

Update: What Internet Explorer 9 needs in order to make me switch from Chrome

I may as well post an update now that I’ve used IE9 for a couple weeks now.  (Also, Dimitri hassled me about it.)

The verdict is that IE9 is a great improvement over IE8.  In fact, I don’t even need to follow that up with a “but I’m still not going to use it because…”  In fact, I use it about as often as I use Chrome now.  I generally switch back and forth depending on which happens to be causing me trouble at any given time.

But to address my criteria:

1. Spell-check

Still absent, annoyingly.  It’s 2011.  Supposedly it can be included via some plug-in which was not immediately obvious when I tried to find it.  If I open the “Manage Add-ons” window, I see nothing in the list that shows any indication that it’s spell-check-related.  Even when I click the link to find more add-ons online, I’m directed to some pretty-but-unusable web site which allegedly should allow me to search for add-ons, yet when I click the Search button, it merely opens to an unusable tiled list of addons (none of which I need) with no search text field to speak of.  I clicked Search, not Browse.

2. Tab-dragging/removal/insertion

Excellent, works well.

3. The ability to switch to another tab while the previous tab is loading/rendering content

Also excellent.  I was really skeptical about MS getting this one in.  It’s one of those features that rarely finds itself in a design spec, and yet is vitally important to user perception of performance.

4. More efficient URL auto-completion

It seems to work exactly as in Chrome now, which is excellent.

 

So there you have it.  I still use both Chrome and IE, and I may lean toward Chrome but whenever it fails for some reason, I don’t hesitate to switch to IE.  At any given time I seem to have tabs open in either browser.  Oh, and having Windows 7 jump-list preview-whatever-you-call-it support is nice, too.

Thursday, March 10, 2011

Performing a Simple Build Task with the Microsoft stack

First of all, I hate it when the term “stack” is used in this context.  Speak in plain English, people.

Now on to the issue at hand.  I have a Visual Studio 2010 solution I want to build.  Because of limitations in Visual Studio’s ability to customize builds of different configurations (e.g. Debug vs Release), I have to execute a custom build step to mess with some of my project files before they get built, and do some custom stuff depending on whether I’m running the Production or Development configuration.

This is fine; at this point I’ve come to terms with Visual Studio’s limitations and will gladly write some hacktastic pre-build step.  So, being the good citizen that I am, I consider alternatives for approaching this:

1) I can write a custom C# console app to do whatever it is I need to do.

2) I can use the BATCH language or some ancient WScript script or something.

3) I can use this newfangled PowerShell thing I keep hearing about (I say “newfangled” despite it being several years old).

#1 would work fine, but the nice thing about scripts rather than built executables is that you can modify them on-the-fly; the source code is right there at your fingertips.  In short they’re transparent.

#2 might also work fine, but this is an older and more convoluted technology and the solution may be more roundabout.

#3 PowerShell sounds like the perfect combination!  I can allegedly execute .NET code in a script!

So, after wading through the horrendously over-complex MSDN documentation which takes about 10 minutes of wading through links before you can see a concrete code example, I gave up and utilized my handy-dandy Safari Books Online subscription to virtually crack open a book about PowerShell.  The explanations were clear and I was finally ready to test out a simple code example, written into a custom .ps1 file that I created.

So, I tried running it and… FAIL. 

File [myscriptfile].ps1 cannot be loaded because the execution of scripts is disabled on this system. Please see "get-help about_signing" for more details.

Oh, that’s just great.  I read the wall of documentation.  Not only is the execution of scripts disabled, but to enable them in a way that wouldn’t unduly molest other people’s systems when they ran this step would require me to actually sign my script with a certificate.  In short, are you F’ing kidding me?  I want to run a script on the systems of a handful of people who assumedly trust me, and I’ve got to go through convoluted steps of signing my script, having my coworkers manually allow this thing to run, likely introducing extra confusing steps in the build process?  No.  Not acceptable.  Once again, #1 is looking like the best option despite its drawbacks.

Monday, November 15, 2010

What Internet Explorer 9 needs in order to make me switch from Chrome

As I regularly switch between IE8 and Chrome, I’m constantly reminded of the features which IE9 will need in order to make me switch.  I know the particular needs are different for different people, but here are mine:

1. Spell-check

I’m a good speller.  But I still make typos, and there’s still the occasional word that I’m unsure of.  Having to look up unknown words in an online dictionary is an annoyance I shouldn’t have to deal with in 2010.

2. Tab-dragging/removal/insertion

Now that I’ve been spoiled with Chrome’s ability to drag tabs in and out of browser windows into new instances, I’m annoyed when I don’t have this.  I am an unapologetic “tab whore”, and organizing them is important.

3. The ability to switch to another tab while the previous tab is loading/rendering content

Microsoft likes to defend IE’s speed versus Chrome, conveniently measuring only those situations which favor such comparisons.  But here’s a common situation you’ll never see quantified:

I load a page in a tab (either by clicking a link or typing a URL manually).  The page is taking forever to load, so I click to open a new tab (or switch to a currently open tab).  In Chrome, this happens effortlessly.  In IE, however, I’m blocked until the page loads completely.  This is gets old very quickly, and every time it happens, it serves as a reminder for why I prefer Chrome.

4. More efficient URL auto-completion

In Chrome, if I want to visit Facebook, I commonly follow these steps:

1. Click in the address bar.

2. Type the letter ‘f’.

3. Press [Enter].

In IE, it’s these:

1. Click in the address bar.

2. Type the letter ‘f’.  See that the History list has brought up a bogusly-entered URL “http://fa/” from a prior failed attempt to visit Facebook.com.

3. Type the letter ‘a’.  “Facebook” now appears in the History list, underneath “http://fa/”.

4.  Press the down-arrow key twice to select the History entry for Facebook.

5. Press [Enter].

Now, if I know you as well as I think I do, you’re going to launch all sorts of counter-arguments:

You:

“It’s your fault you typed ‘http://fa’ and expected it to work, causing the invalid History entry.”

Me:

One, this would have worked in Chrome, so it just illustrates that Chrome is simpler; and two, Chrome is smart enough not to save bogus URLs in its history, so even if I manually typed http://fa/ in Chrome, it won’t create a History entry for it.  Another strike against IE.

You:

“You can just hit Shift+Enter to load the top URL in your History.”

Me:

So in other words, it’s more complex than Chrome.  Thank you for proving my point.  And I still have to type more characters to eliminate http://fa/ as a history option.

Friday, November 5, 2010

I’ve found that one of the best ways to find a solution to a technical problem at work is to write a lengthy, passive-aggressive email to your coworkers, explaining in detail what you’re trying to do and what’s going wrong.  9 times out of 10, you’ll figure out what’s wrong before you embarrass yourself by hitting the Send button.

Thursday, July 15, 2010

Objective-C MIN and MAX #define wonkiness

Here’s a little odd thing I discovered when trying to use the MIN and MAX macros defined in NSObjCRuntime.h.  I had the following code (simplified):

const int MAX_OBJECTS = 10;
int numObjectsToRemove = MAX(0, myObjectArray.count - MAX_OBJECTS);


Let’s say myObjectArray.count is 1.  What would you expect numObjectsToRemove to become?

0, right?  Because (myObjectArray.count – MAX_OBJECTS) == (1 – 10) == –9, and 0 is clearly greater than –9.  But you’d be wrong.  And so was I.

You see, apparently, since the count member of NSArray is an unsigned int, the entire expression gets treated like an unsigned int.  So, since –9 in unsigned form is actually a very large number, it’s considered greater when compared to 0.  But as if that wasn’t bad enough, when it gets assigned to numObjectsToRemove, it gets treated like a normal signed int again, so its value becomes –9 again.  And you’re left wondering why –9 is considered greater than 0.

The simple fix is to force the macro to treat the whole expression like an int with a simple cast:

int numObjectsToRemove = MAX(0, (int)myObjectArray.count - MAX_OBJECTS);

Tuesday, July 13, 2010

Permission confusion in MS SQL Server 2008

I’m singling out MS SQL Server 2008 though I’m sure this appears in previous versions as well.

Have you ever run into a situation in which, for some reason, you just couldn’t grant someone certain permissions in SQL Server?  If you’re irresponsible like me, you’ll generally just try to give them as much access as possible to make the problem go away sooner.

But there are an insane number of ways you have available to you to change permissions.  Do they all do the same thing?  Are they different windows into the same data, or do they affect different permissions?  Who the heck knows, except the SQL Gods.  Here’s an example of the overwhelming number of ways to assign permissions:

1. Select the Security->Users folder under your database item, and add/modify the property of users from there:

sqlhell_step01

2. Select the Security->Roles folder under your database item, right-click and select Properties on a database role and assign a user to that role.  Bewilderingly, this doesn’t appear to correspond to method #1!  In other words, if I assign a user to the dbowner role using method #1, they won’t be listed in the role membership listing of method #2!

sqlhell_step02

3. Right-click the database object itself, click Properties, then select the Permissions page.  OMG, now there’s a completely separate list of users and very fine-grained permissions which you can “Grant”, “With Grant” (whatever on Earth that means), or “Deny”.  Huh?  Why is there a completely different set of permissions?  Do these override the role memberships?

sqlhell_step03

4. Select a user from Security->Logins of the database server item, edit their User Mapping properties to assign them to a particular database, and from there modify their "Database role membership”.  This seems to correspond to the values in step 1 or 2.

sqlhell_step04

5. RIght-click the database server item and choose Properties, then click the Permissions page.  This allows you to select logins or roles and explicitly assign permissions similar to Step 3.  But you’re assigning these to Logins instead of Users?  Wha?  Does that override the User permission, or does the User value override the Login permission?

sqlhell_step05

 

I’m sure there are many more ways to modify permissions but I’d just be belaboring the point.  I have nothing against having multiple places from which to modify user permissions, but I’d like if there was some semblance of correlation to one another.  As it stands, when I assign someone permissions, I’m mostly just guessing.  I realize that this is a tool for hardcore administrators, but in reality it’s used by a lot of everyday programmer-users like myself.  We aren’t administrators nor do we want to be; we just need to do what we need to do to get our job done.

I have something I want to do and a cryptic way to accomplish this through the administration tool.  What I want is an easier way to specify what I want, and have the system be smart enough to guide me through (possibly multiple) options for making this happen.

Wednesday, June 9, 2010

2D Line segment intersection detection in C#

For a previous game project, I needed a nice line segment intersection detection algorithm.  It was surprisingly difficult to find a good one in C#, but I found one in C++ that I converted. 

As it turns out, my upcoming game makes heavy use of this algorithm as well.  So here it is in case anyone else needs it.  This version is a little sloppy in that it uses 3D constructs despite checking 2D intersections, but it would be simple to convert this to its 2D counterpart.

Line segment intersection C#
  1. // Returns true if the lines intersect, otherwise false. If the lines
  2.         // intersect, intersectionPoint holds the intersection point.
  3.         public bool Intersects2D(LineSegment3 otherLineSegment, out Vector3 intersectionPoint)
  4.         {
  5.             float firstLineSlopeX, firstLineSlopeY, secondLineSlopeX, secondLineSlopeY;
  6.  
  7.             firstLineSlopeX = this.Point2.X - this.Point1.X;
  8.             firstLineSlopeY = this.Point2.Y - this.Point1.Y;
  9.  
  10.             secondLineSlopeX = otherLineSegment.Point2.X - otherLineSegment.Point1.X;
  11.             secondLineSlopeY = otherLineSegment.Point2.Y - otherLineSegment.Point1.Y;
  12.  
  13.             float s, t;
  14.             s = (-firstLineSlopeY * (this.Point1.X - otherLineSegment.Point1.X) + firstLineSlopeX * (this.Point1.Y - otherLineSegment.Point1.Y)) / (-secondLineSlopeX * firstLineSlopeY + firstLineSlopeX * secondLineSlopeY);
  15.             t = (secondLineSlopeX * (this.Point1.Y - otherLineSegment.Point1.Y) - secondLineSlopeY * (this.Point1.X - otherLineSegment.Point1.X)) / (-secondLineSlopeX * firstLineSlopeY + firstLineSlopeX * secondLineSlopeY);
  16.  
  17.             if (s >= 0 && s <= 1 && t >= 0 && t <= 1)
  18.             {
  19.                 float intersectionPointX = this.Point1.X + (t * firstLineSlopeX);
  20.                 float intersectionPointY = this.Point1.Y + (t * firstLineSlopeY);
  21.  
  22.                 // Collision detected
  23.                 intersectionPoint = new Vector3(intersectionPointX, intersectionPointY, 0);
  24.  
  25.                 return true;
  26.             }
  27.  
  28.             intersectionPoint = Vector3.Zero;
  29.             return false; // No collision
  30.         }