Freestyle Coding

Programming in the Real World

  Home  |   Contact  |   Syndication    |   Login
  49 Posts | 0 Stories | 38 Comments | 0 Trackbacks

News

Tag Cloud


Archives

Post Categories

Charity

Conferences

Professional

Projects

Social Networks

Wednesday, April 16, 2014 #

I, unfortunately and unwittingly, started a minor Twitter flame war earlier today. Of course, there is only one way that could turn out.

The subject was on the importance of JavaScript. The original tweet was:

“By 2017, JavaScript will be the most in-demand language skill in application development (AD).”

— Forrester Research 2014
I will leave out who provided the tweet. Yes, I will forward them a link to my article. If they post a reply, I will update this post with a link.

Before I begin, let me say a few things. First, I did not read the referenced article. This is because a) I couldn't find it, and b) every report on Forrester's site seems to cost 499USD. Second, I do actually like JavaScript and have been using it for a VERY long time. Finally, as longtime readers will know, I am a proponent of learning your language, not your extension framework.

My response to the comment was "if this comes true, we have failed our customers and users..." This spawned an epic, 3 hour conversation thread that I'm not going to fully recount. I will make sure all of their points are addressed.

My response was fueled by two primary things. The first was a couple "interactions" I've had with Douglas Crockford. The most important of these was the DevLink 2012 closing panel. During this panel, Crockford replied to a question about the longevity of JavaScript with the following response:

God, I hope not. If it turns out that JavaScript is the last programming language, that would be really sad. But unfortunately, because of its dominance in the web, it is now moving into virtually every place else. It has become a tragically important language, and we’re going to be stuck with it for a time...
This has, and still does, mirror my feelings. This took place at about the same time WinJS was starting to come into fashion. At that time, I had some informal numbers telling me that WinJS was not as prevalent as Microsoft was letting on. Unfortunately, I do not have current numbers as Microsoft doesn't publish this type of information.

That leads to my second point. I do NOT like the fact that the quote says "application development." Yes, web apps are apps. However, I am afraid that is not the intent of the statement. I fear that this statement is referring to JavaScript as a golden hammer. There are cases where JavaScript is the right tool for the job. However, JavaScript is not the only tool for the job.

I think back to the early 2000s. Perl was ALL the rage. It was used for everything, including webpages. The problem was that Perl was originally written for a specific purpose. It was written to be a VERY efficient string parser to enable Linux admins automate command line tasks that involved scrubbing log files. To this day, it still's still widely in use doing just that.

Soon, however, people said "PERL ALL THE THINGS!" We began to see webpages that were Perl scripts constructing a page in real-time. We began to see command-line apps that were Perl scripts that just automated calls to other command-line apps.

In the long run, Perl had this dirty little secret. It was made to be very easy to use, to be marginally forgiving, and to offer great flexibility. Larry Wall, the father of Perl, described a good programmer as being lazy. In the end, this led to bad habits, unmaintainable code bases, and large amounts of effort (and money) being spent to go back and do it right.

If, when reading that last paragraph, you didn't mentally swap Perl for JavaScript, go back and try again.

During all this talk, people professed the joy of all things JavaScript and how I was categorically WRONG. The biggest, recurring theme was "but what about node.js". Let me sum this up in 3 parts. First, it says .js. Thus, it's just JavaScript on the client. Second, the server side is a WHOLE bunch of C++. Third, It's not like it has a dependency to openssl or anything... (Too soon?)

As a bonus fourth, this argument would have been about Ember last year. Knockout the year before that. jQuery the year before that... If my timeline is wrong on the previous next-big-things, that's because I never used any of them. I wrote JavaScript, using the as is was defined in the ECMAScript spec. Interacting with the DOM in a method that was outlined in the DOM spec. Writing carefully engineered client code to do only want I needed without fragile, outside dependencies.

Guess what, that code had generally worked on all browsers, of all types, without side effects. I say generally because you do have to add CSS into the mix, and no browser universally uses it correctly.

Given all that, I would never dream of writing an application in JavaScript. I consider it a tool that I can exploit in the correct circumstances. People say, “but, it’s ubiquitous. Why not use it?” Of course, their bosses said that two decades ago about Java.

Technology changes faster than we realize. I can’t tell you want language I will be using in 3 years. I can’t tell you want languages will still be around. People still make a fortune maintaining COBOL. What I can tell you is that technology is run by neither merit nor artistry. There is a little of both, but something else. Once the true engineers get a hold of JavaScript and make people do it right, the lemming will find the next easiest path.

My only hope is that this happens sooner, rather than later.


Thursday, April 10, 2014 #

As I was working on updates to The Krewe Windows Phone App, I ran into a very aggravating situation. I needed to blow away my Azure deployment project (more on a later date) and recreate a new one. When I did this, the project was named the ever-so-helpful "TheKreweAPI.Azure2". I know, pure poetry...

After this happened, I took the time to rename everything to something useful. I manually edited solution and project files. I scrubbed output directories. I made everything look pretty.

I my quest for glory, I removed something I didn't mean to remove. When the project was created, VS12 automatically added the project to source control. I had the little + next to the project name. After I renamed everything, my little + went away.

That made me a sad panda.

After a full day of shouting obscenities, I finally fixed it. Here is what I had to do to fix it:

  • Undo the "add" changes.
  • Remove the project from the solution
  • Rename the original directory
  • Manually create the directory in the Source Control Explorer
  • Copy the files into the new, correctly named directory
  • Re-add the project to the solution.
  • Add the files to source control
  • Check everything in
  • Party like it's 1999

I don't know if you realized this, but that's a LOT of steps for a simple rename. Hopefully, this will keep you from the same spew of obscenities that I was forced to use.


Monday, April 7, 2014 #

Greetings. I Have returned from the brink of madness. Of course, by madness, I mean academia...

It's time to kickstart this thing back into full swing. I have tasked myself to keep this thing updated on a semi-regular basis. What does semi-regular mean? Well, I'm hoping to hit at least on post about every 2 weeks.

Of course, the trick to this is that my role at work has significantly changed. I'm still coding and doing research and development. However, I am now in a much larger supervisory role. As such, topics may expand into these areas. Of course, I have always posted some soft skills topics. Those just seem to be the ones that nobody reads.

Any who, it feels good to be posting something into a public forum again. I hope to hear, read, or see you all soon.


Friday, October 25, 2013 #

The time has been flying by this year. It seems like only yesterday that I mentioned the gorillagator, a simple construct of confusion to try to draw attention to my message.

In reality, that message was sent over a month ago. During that time, the hours slipped to days and days to weeks. Many exciting things have happened to myself; I'm sure many exciting things have happened to you. I'm also sure that many terrifying things have happened to children and their families.

62 children enter treatment at a Children's Miracle Network Hospital every minute. That's nearly 60,000 children since I sent the last email. To put that number in perspective, that is more than the population of Greenland. If we expand that to the past year, they have been nearly 550,000 children treated. That is almost the population of Huntsville, Decatur, and all their suburbs combined.

Over the past 4 years, I have raised a little more than $3,000 for Children's Hospital of Alabama. As a result, I received a call from the organizers of Extra Life thanking me for my dedicated work and informing me that I was the top supporters for Children's Hospital of Alabama ... with my measly three grand.

We can do much better than that.

It may sound like I'm trying to have fun by playing games for 24 hours. It is more than that. It is me using my time and body as a catalyst. It is me putting my passion to work for a cause. It is me turning my love into something tangible.

I have been campaigning and fighting to give these children a chance for years. I have been asking you to help me support these children and families. I've been putting in countless hours of talking to people, impassioned emails, and carefully constructed tweets. I have been fighting with cutting edge, and sometimes expensive, technology to try to provide live streams of my marathons. I yearly put my body through 24 (and, this year, 25) hours of no sleep.

I do this to represent the countless hours these families sit awake at their children's side.

All I ask is a few minutes on a website and a few dollars. These few minutes and few dollars go a long way help people that are experiencing circumstances that only occur in our nightmares.

I also ask that you take one extra step. Forward this plea to those that you know. I can only reach a small fraction of a percentage of the people that may be able to help. Together, we can reach the world. I raise money for Children's Hospital of Alabama. As this message branches out, people may wish to support a hospital closer to their area. I have included a link to the list of people that have dedicated their time and have received no donations. Find someone on the list supporting your local hospital and give them a donation. Let them know that their time and effort are appreciated.

Together, we can do something great.

Together, we can make a difference.

Together, we all stand tall.

Thank you.

You can get more information at http://www.extra-life.org and http://childrensmiraclenetworkhospitals.org/"

My donation page is http://www.extra-life.org/participant/cgardner

The list of participants without donations is http://www.extra-life.org/index.cfm?fuseaction=donorDrive.eventParticipantList&page=629&eventID=512


Saturday, September 14, 2013 #

As many of you know, I participate in a 24-hour gaming marathon every year to raise money for a charity named Extra Life. All the money I raise goes directly to Children's Hospital of Alabama through the Children's Miracle Network. To date, I've raised $2,799.28 to help make sick children's lives a little better.

This year, the marathon will be on November 2nd. Yes, that is the day the clock falls back. Yes, that means this year will be a 25-hour gaming marathon. I'll be pushing myself even harder to help those that are pushing hard every day.

Unfortunately, there is one area in which I have been slacking a bit. This is the area of fundraising / solicitation. I raised my personal goal to a new time high of $1,200, but I've waited the longest I've ever waited to start my fundraising campaign.

I'm not happy about this.

Neither is the feral platypus.

The feral platypus called me the other day to remind me of this. The feral platypus said he's sending over an enforcer to get me in gear and keep my straight. I thought he was just trying to use his old scare tactics to get me in line. Then, I got a knock at the door.

It was the gorillagator. The gorillagator was not happy, either. The gorillagator informed me that I will get back in gear for these kids. The gorillagator reminded me that I don't have a choice because these children don't have a choice. Finally, the gorillagator reminded me that he is an official agent of the feral platypus, and that, well, I probably shouldn't repeat the rest of what he said in a post to help children...

A few bucks out of your own pocket is not too much to ask. Every donation you make is 100% tax deductible. You'll even get a nifty receipt you can print out to keep the feds off your back. Most importantly, you'll get the peace of mind knowing that you eating leftovers for lunch one day turned into a slight improvement in the quality of life for a child in a dire situation.

You'll also get the gorillagator off my back.


Friday, June 21, 2013 #

Everyone seems to be putting their 0.00237 cents into the wishing well over Microsoft's recent decision to reverse the DRM policy on the Xbox One. However, there have been a few issues that nobody has touched. As such, I have decided to dig 0.00237 cents out of my pocket.

First, let me be clear about this point. I do not support the decision to reverse the DRM policy on the Xbox One. I wanted that point to be expressed first and unambiguously. I will say it again. I do not support the decision to reverse the DRM policy on the Xbox One.

Now that I have that out of the way, let me go into my rationale. This decision removes most of the cool features that enticed me to pre-order the console. No, I didn't cancel my pre-order. There is still five months before the release of the console, and there is still a plethora of information that we, as consumers, do not have. With that, it should be noted that much of the talk in this post is speculation and rhetoric. I do not have any insider information that you do not possess.

The persistent connection would have allowed the console to do many of the functions for which we have been begging. That demo where someone was playing Ryse, seamlessly accepted a multiplayer challenge in Killer Instinct, played the match (and a rematch,) and then jumped back into Ryse. That's gone, if you bought the game on disc. The new, DRM free system will require the disc in the system to play a game.

That bullet point where one Xbox Live account could have up to 10 slave accounts so families could play together, no matter where they were located. That's gone as well.

The promise of huge, expansive, dynamically changing worlds that was brought to us with the power of cloud computing. Well, "the people" didn't want there to be a forced, persistent connection. As such, developers can't rely on a connection and, as such, that feature is gone. This is akin to the removal of the hard drive on the Xbox 360.

The list continues, but the enthusiast press has enumerated the list far better than I wish. All of this is because the Xbox team saw the HUGE success of Steam and decided to borrow a few ideas. Yes, Steam. The service that everyone hated for the first six months (for the same reasons the Xbox One is getting flack.) There was an initial growing pain. However, it is now lauded as the way games distribution should be handled.

Unless you are Microsoft.

I do find it curious that many of the features were originally announced for the PS4 during its unveiling. However, much of that was left strangely absent for Sony's E3 press conference. Instead, we received a single, static slide that basically said the exact opposite of Microsoft's plans. It is not farfetched to believe that slide came into existence during the approximately seven hours between the two media briefings.

The thing that majorly annoys me over this whole kerfuffle is that the single thing that caused the call to arms is, really, not an issue. Microsoft never said they were going to block used sales. They said it was up to the publisher to make that decision. This would have allowed publishers to reclaim some of the costs of development in subsequent sales of the product. If you sell your game to GameStop for 7 USD, GameStop is going to sell it for 55 USD. That is 48 USD pure profit for them.

Some publishers asked GameStop for a small cut. Was this a huge, money grubbing scheme? Well, yes, but the idea was that they have to handle server infrastructure for dormant accounts, etc. Of course, GameStop flatly refused, and the Online Pass was born. Fortunately, this trend didn’t last, and most publishers have stopped the practice.

The ability to sell "licenses" has already begun to be challenged. Are you living in the EU? If so, companies must allow you to sell digital property. With this precedent in place, it's only a matter of time before other areas follow suit. If GameStop were smart, they should have immediately contacted every publisher out there to get the rights to become a clearing house for these licenses. Then, they keep their business model and could reduce their brick and mortar footprint.

The digital landscape is changing. We need to not block this process. As Seth MacFarlane best said "Some issues are so important that you should drag people kicking and screaming." I believe this was said on an episode of Real Time with Bill Maher about the issue of Gay Marriages. Much like the original source, this is an issue that we need to drag people to the correct, progressive position. Microsoft, as a company, actually has the resources to weather the transition period. They have a great pool of first and second party developers that can leverage this new framework to prove the validity. Over time, the third party developers will get excited to use these tools.

As an old C++ guy, I resisted C# for years. Now, I think it's one of the best languages I've ever used. I have a server room and a Co-Lo full of servers, so I originally didn't see the value in Azure. Now, I wish I could move every one of my projects into the cloud. I still LOVE getting physical packaging, which my music and games collection will proudly attest. However, I have started to see the value in pure digital, and have found ways to integrate this into the ways I consume those products.

I can, honestly, understand how some parts of the population would be very apprehensive about this new landscape. There were valid arguments about people with no internet access. There are ways to combat these problems. These methods do not require us to throw the baby out with the bathwater.

However, the number of people in the computer industry that I have seen cry foul is truly appalling. We are the forward looking people that help show how technology can improve people's lives. If we can't see the value of the brief pain involved with an exciting new ecosystem, than who will?


Friday, June 14, 2013 #

When I was working on my C#/XAML game framework, I discovered I wanted to try to data bind my sprites to background objects. That way, I could update my objects and the draw functionality would take care of the work for me. After a little experimenting and web searching, it appeared this concept was an impossible dream.

Of course, when has that ever stopped me?

In my typical way, I started to massively dive down the rabbit hole. I created a sprite on a canvas, and I bound it to a background object.

<Canvas Name="GameField" Background="Black">
<Image Name="PlayerStrite" Source="Assets/Ship.png" Width="50" Height="50" Canvas.Left="{Binding X}" Canvas.Top="{Binding Y}"/>
</Canvas>

Now, we wire the UI item to the background item.

public MainPage() {
this.InitializeComponent();
this.Loaded += StartGame;
}
 
void StartGame( object sender, RoutedEventArgs e ) {
BindingPlayer _Player = new BindingPlayer();
_Player.X = Window.Current.Bounds.Height - PlayerSprite.Height;
_Player.X = ( Window.Current.Bounds.Width - PlayerSprite.Width ) / 2.0;
}

Of course, now we need to actually have our background object.

public class BindingPlayer : INotifyPropertyChanged {
private double m_X;
public double X {
get { return m_X; }
set {
m_X = value;
NotifyPropertyChanged();
}
}
 
private double m_Y;
public double Y {
get { return m_Y; }
set {
m_Y = value;
NotifyPropertyChanged();
}
}
 
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged( [CallerMemberName] string p_PropertyName = null ) {
if( PropertyChanged != null )
PropertyChanged( this, new PropertyChangedEventArgs( p_PropertyName ) );
}
}

I fired this baby up, and my sprite was correctly positioned on the screen. Maybe the sky wasn't falling after all.

Wouldn't it be great if that was the case?

I created some code to allow me to move the sprite, but nothing happened. This seems odd. So, I start debugging the application and stepping through code. Everything appears to be working. Time to dig a little deeper.

After much profanity was spewed, I stumbled upon a breakthrough. The code only looked like it was working. What was really happening is that there was an exception being thrown in the background thread that I never saw. Apparently, the key call was the one to PropertyChanged. If PropertyChanged is not called on the UI thread, the UI thread ignores the call.

Actually, it throws an exception and the background thread silently crashes. Of course, you'll never see this unless you're looking REALLY carefully.

This seemed to be a simple problem. I just need to marshal this to the UI thread. Unfortunately, this object has no knowledge of this mythical UI Thread in which we speak. So, I had to pull the UI Thread out of thin air.

Let's change our PropertyChanged call to look this.

public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged( [CallerMemberName] string p_PropertyName = null ) {
if( PropertyChanged != null )
Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync( Windows.UI.Core.CoreDispatcherPriority.Normal, new Windows.UI.Core.DispatchedHandler( () => {
PropertyChanged( this, new PropertyChangedEventArgs( p_PropertyName ) );
} ) );
}

Now, we raised our notification on the UI thread. Everything is fine, people are happy, and the world moves on.

You may have noticed that I didn't await my call to the dispatcher. This was intentional. If I am trying to update a slew of sprites, I don't want thread being hung while I wait my turn. Thus, I send the message and move on.

It is worth nothing that this is NOT the most efficient way to do this for game programming. We'll get to that in another blog post. However, it is perfectly acceptable for a business app that is running a background task that would like to notify the UI thread of progress on a periodic basis.

It is worth noting that this code was written for a Windows Store App. You can do the same thing with WP8 and WPF. The call to the marshaler changes, but it is the same idea.


Friday, May 17, 2013 #

You know those seemingly random Guids? Guess what? They're not random.

I'll give your head a moment to recover from that bombshell.

Ok, back with me? Good.

I was digging DEEP in some hardcore specs when I stumbled upon this. I had a situation where I have a Guid as a unique identifier. This identifier had some subsequent child data that needed to refer to the global object but required different handling. Yes, I'm being slightly vague. I do have to respect company proprietary data.

Due to this dilemma, I had a really weird "hash table" to quickly find the identifier from the child object. While this solution worked, and was REALLY fast, it was very messy and complex. I decided I needed to hack something to reduce this complexity.

I know. I just said I wanted to reduce complexity, and that my solution was to hack Guids. The sick humor of this is not wasted on me. You knew what you're getting into when you read my blog.

Turns out, there is a status field in the Guid. I was scouring the Wikipedia article on Guids when I read the Binary Encoding section. Turns out 3 of the bits have a special meaning. More specifically, if you were dealing with the Guid 00000000-0000-0000-x000-000000000000, part of the hex value of x means something. Guids in .NET, generated by the System.Guid structure, are all "standard" Guids. As such, they will always have the bit mask of 00000000-0000-0000-8000-000000000000.

If you don't believe me, go do a select on your largest database column. That hex value will always be either 8, 9, A or B.

If we exploit this, we now have 2 bits in our 128 bit number which we can control. We know those 2 bits being 10 will refer to our master identifier. However, since they are fixed, we can use 00, 01 and 11 as attached, but still unique, child Guids. This child Guids will always point back to the parent Guid by restoring those 2 bits to 10.

Happy Friday, people.


Wednesday, April 17, 2013 #

Hi, guys. I know I've been in hiding lately. I'm not dead. That status is saved for XNA (oops, did I say that out loud?)

I'm juggling quite a few project right now; all these projects have fixed deadlines. As such, I haven't had time to create the blog posts on them. Add that to my attempts to move all my old XNA sample code to new technologies.

In mid-May, my schedule should free a little. At that time, you should start seeing posts on the following topics:

  • Using an Xbox 360 controller in a managed code Windows Store App
  • "Recreating" the XNA game loop in a Windows Store App
  • Data binding to attached properties (ie: Canvas.Left)
I'm sure there are more, but my mind is temporarily drawing a blank. Took much late night coding over the past month...

I also wanted to give you a quick heads-up over some of the events coming up.

  • Code PaLOUsa : April 25 - 27 (Kinect and my last XNA talk...)
  • Tampa, FL: May 7 (Games for Windows Phone)
  • Tallahassee, FL: May 8 (Games for Windows Store Apps)
  • Mobile, AL: May 9 (Games for Windows Store Apps)
  • DevLink : Aug 28 - 30 (Schedule not finalized yet)
I should know it I'm working at TechEd North America on Friday. I have sessions submitted for That Conference and CodeStock. I should know about That Conference on May 1st. You can help me get to CodeStock. If you go and register on the Early Bird Special, you can vote for the sessions you want. Not saying you have to pick one of mine, but pick one of mine...

Speaking of CodeStock, there is a special engagement going during the event. While I'm up there, Michael Neel and I are going to give a joint session to the Knoxville Tech Co-op. It will be a post-mortem on XNA. We're going to talk about what it did right, what it did wrong, and what's next. As soon as I have details I'll post them here.

That's all for now. Keep the good comments and feedback coming. I love hearing from you guys.


Wednesday, February 20, 2013 #

Last night, I was playing around with my port. I was having a bit of a problem getting the mouse click to behave as I expected. In a fit of inspiration, I solved that problem in such a way that it allowed me to dramatically improve the keyboard buffer. With the popularity of the keyboard buffer, I thought I'd share right away.

As I stated in the original post about the keyboard buffer, WinRT doesn't route keyboard events unless there is a valid target. This forced me to have a control that required focus. This wasn't really a problem, unless the control lost focus.

Of course, we have to place our control on the screen. Furthermore, we have to place it on some sort of monolithic control that handles everything. Thus, why don't we just ask the Canvas to pass us these events?

public class KeyboardBuffer : Control {
private List<VirtualKey> PressedKeys;
 
public KeyboardBuffer() {
PressedKeys = new List<VirtualKey>();
this.Loaded += ControlLoaded;
}
 
private void ControlLoaded( object sender, RoutedEventArgs e ) {
FrameworkElement _Parent = this.Parent as FrameworkElement;
while( !(_Parent is Canvas) )
_Parent = _Parent.Parent as FrameworkElement;
 
_Parent.KeyDown += KeyDownEvent;
_Parent.KeyUp += KeyUpEvent;
}
 
void KeyDownEvent( object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e ) {
if( !PressedKeys.Contains( e.Key ) ) {
PressedKeys.Add( e.Key );
switch( e.Key ) {
// HANDLE KEYS HERE
}
}
}
 
void KeyUpEvent( object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e ) {
while( PressedKeys.Remove( e.Key ) );
 
switch( e.Key ) {
// HANDLE KEYS HERE
}
}
}

Now, I just go up the chain and find the Canvas. At that point, I attach to its events. This way, I always get them. Mouse clicks, screen manipulation, throwing your Surface across the room? Doesn't matter. The events are bound so far up the chain that you always get them. You don't have to focus on the focus.

If you are reading this article without ever reading the original article, there are a few other things I'm leaving out. Check out the original post about the keyboard buffer if it seems like I'm not mentioning something.