UPDATE: Sandy responded below and it’s official: I am a jerk for jumping the gun. 😛
A while ago, I blogged about my obsession with Guitar Hero (GH). I really just can’t get enough of that game, but the lack of owning an XBOX 360 has hindered my playing to about once a month when I go over to my friend’s house.
I’ve been wanting to go out and purchase my own XBOX 360, but the fact that I’m constantly hearing horror stories about the “red ring of death” is scaring me off. What am I suppose to do at this point?!? I need something to cure my addiction while Microsoft works out the kinks (if they ever do work them out). My only alternative was to find another way to play GH without having to get an XBOX 360 for the moment.
This is when my geekiness kicked in: “Hey dumbass…. you’re probably not the only one wanting to play GH. How much you want to bet someone has created an open source clone.” God I love it when I have these moments! With that I quickly Googled “guitar hero clones” and found the answer: Frets on Fire!
If you’ve never heard of Frets on Fire (FOF), allow me to tell you about it. It’s a GH clone written in Python by some really creative people. You use you keyboard to play by holding it upside-down and mimicking a guitar. Just like GH, you pick a song to play and you strum along when the little blocks tell you to.
Some of really nice features of FOF is that you can import songs from GH directly into it (in the spirit of the internet there is a torrent available on thePirateBay for the songs). You can also hook up a GH guitar and use that if you don’t want to use your keyboard (although using the keyboard isn’t all that bad, it just looks dumb). There is also a tutorial that show you how to play the game for the first time and how to hold the keyboard correctly.
To add props to the game, I will say that it look extremely professional. I personally think that it look better then GH itself and you can tell that the developers really took their time with the interface. The songs that come with the game are really good and as I’m typing this I still have Bang Bang, Mystery Man in my head.
To say the least I was up until 3 a.m. this morning with my wife playing this thing and I’m just counting down the hours until I can get out of work. I can’t wait to get out of here so I can go purchase the GH guitar and hook it up!
If you’ve visited Digg over the last couple of hours, you have probably have seem the new and improved comment system.
Ok… Personally I liked the old comment system better and I think the new comment system sucks big time!
Any who, in a post about the technical aspects behind the new comment system, it was revealed that the new system is now powered by jQuery instead of Scriptaculous. To me this is a big deal since I’ve a huge fan of jQuery and I’m hoping that one day it will over take that crap that is Prototype and Scriptaculous.
Who doesn’t like user defined functions (UDFs)? If you have done any programming, chances are that you have used them extensively. The biggest problem that people have with them is how to include and organize them in your application.
What I’ve found that most people do is create a Utils.cfc or UDFs.cfc and cut and paste their UDFs that they want to use into the component as demostrated below:
<!— UDFs.cfc —>
<cffunction name=”init” access=”public” returntype=”Any” output=”false”>
<cffunction name=”myUDF1″ access=”public” returntype=”Any” output=”false”>
<cffunction name=”myUDF2″ access=”public” returntype=”Any” output=”false”>
Once you have all the UDFs that your application will be using pasted into your component, you will need to make the UDFs available to your application. Almost everyone I’ve seen does this loading by the component into the application scope. The following line is placed into the onApplicationStart() if your using Application.cfc or by just adding it into the Application.cfm if you’re using that:
<cfset application.functions = CreateObject(“component”, “udfs”).init()>
Whichever one your using, Application.cfc or Application.cfm, the results are the same; all your UDFs are available to your application and you can use them freely throughout. The only difference is what variable name you use. I use application.functions, some use application.utils or application.udfs; doesn’t matter, again, the results are the same.
There is one problem that I have with this approach though, it’s cumbersome and the UDFs component will get huge. The problem with having such a huge component file is editing it becomes a nightmare since scrolling through thousand of lines of code is very fun and also I’ve noticed that CFEclipse bogs down on huge files. Sure code collapse does provide some relief but there has to be a better way.
What I wanted was to just have one file for each UDFs I was using and a way for my application to load them automatically. Reason behind this was so that if I needed to edit myUDF1, I could just open the file myUDF1.cfm and edit what I needed. I also wanted to be able to grab UDFs from CFLib.org and just drop them into my application without having to edit anything. If I ever needed to remove a UDF from my application, it would be as easy as deleting the UDF file and reinitializing my application.
To accomplish what I wanted, I modified my UDFs.cfc to 11 lines of code:
<!— UDFs.cfc —>
<cfset variables.udfdir = GetDirectoryFromPath(GetCurrentTemplatePath()) & “udfs”>
<cfset variables.q = “”>
<cffunction name=”init” access=”public” returntype=”Any” output=”false”>
<cfdirectory action=”list” directory=”#variables.udfdir#” filter=”*.cfm” name=”variables.q”>
So what exactly is going on?
In a nutshell, here’s what’s happening. I have a directory called udfs in the same directory that I have my UDFs.cfc. This is the directory that I put all of my UDF CFM files. What the UDFs.cfc does is scan this directory when it is called and automatically includes each CFM file it finds. Thus it automatically loads any UDFs in the UDFs folder into itself.
So my goal is reached! I have each UDF in it’s own file so I don’t have to scroll through a huge component file to find it. I can now open and edit it easily. By just looking at the directory, I know what UDFs my application is using. I can automatically add a UDF from CFLib.org by just saving the text from browser into a file in the directory. Plus if I no longer need to use the UDF in my application, I simply delete the file from the directory and it’s removed from my application during the next reinit. All this is done without having to touch the main UDFs.cfc file.
Below is an example of what one of the UDF CFM files looks like. The file is called fullLeft.cfm and resides in the UDFs directory.
<!— fullLeft —>
<cffunction name=”fullLeft” access=”public” displayname=”fullLeft” returntype=”string” output=”false”>
<cfargument name=”str” type=”string” required=”true”>
<cfargument name=”count” type=”numeric” required=”true”>
<cfif not refind(“[[:space:]]”, arguments.str) or (arguments.count gte len(arguments.str))>
<cfreturn Left(arguments.str, arguments.count)>
<cfif count-refind(“[[:space:]]”, reverse(mid(arguments.str,1,arguments.count)))>
<cfreturn Left(arguments.str, (arguments.count-refind(“[[:space:]]”, reverse(mid(str,1,arguments.count)))))>
No.. not me, Tony Soprano.
If you didn’t watch the Sopranos’ final episode last night, stop reading.
Like about 80% of America last night I watched the final episode of the Sapronos and thought that my TV went stupid on me. I couldn’t figure out what happened and it left me pissed beyond belief. “Did he die or not”, was the only question on my mind.
So if you’re wondering if Tony died last night, the answer is “yes he did” and below is the reason why:
“It was pretty clear to me that he died. Remember the flashback in the previous episode, where Bobby says “You never even hear it when it happens, do you?” Implying everything just goes black – you’re dead before you even hear the gun being fired. Well, that’s exactly what happened. The last thing Tony say was Meadow walking in the door.
Earlier in the episode, he was eating an orange, which is a reference to the Godfather files that has been made before in the series. They signify death, don’t they?”
I’ve been trying to get the time in the last couple of weeks to work on ICEGen. Sorry to say though that work both regular and side have been very busy. Hopefully I’ll finish what I need to do this week and be back on track by June 11th.
My first order of business is to get some documentation online via the wiki that RIAForge provides. Along with explaining what ICEGen is and how to run it, I want to give some really world example of it’s use.
After that I would like to create some screen casts that I can throw onto YouTube so I can show it in action. The only thing is that I don’t know what to use to create the screen casts, so any suggestions on software would be great. Free and open source are the best options, but I have no problems paying for something if it’s good.
After the documentation and screen casts I need to start concentrating on getting some other database support built in, especially Oracle since more than one person has emailed me about it. If anyone is willing to help me test other databases, please leave a comment below. I don’t have or know Oracle or MySQL and those are the first ones I want to concentrate on.
I’m very happy with the path it’s taken. I’m currently using it in a project I’m working on right now and I have to say that it has saved me a lot of time and thinking. The kewlest feature has to be the before and after methods for CRUD operations. It’s really nice to be able to use them like triggers and perform referential integrity with them.
If you haven’t given ICEGen a test drive, I don’t blame anyone since there is almost no documentation online, but it should be pretty easy to use. I you have used it, please leave some sort of comment below telling me what you think it needs.
I promise I will start posting some more technical articles soon. I’m just having a rough couple of weeks with work and some outside projects that have kept me from posting
It’s Friday!!!! You know what that means… BASH baby!