My plan for this blog post was to introduce my preferred "front-end framework", Zurb Foundation. But then the folks over at Zurb saw fit to sabotage my effort by releasing a new version of Foundation. Can you believe the nerve? So instead I’ll just give a quick rundown of why I like Foundation better than that "other framework", and then show off what’s new in Foundation 4.
I assume that like many developers, I first became interested in computers while playing computer games. Our family owned a Commodore 64 and I can only wonder how many hours I wasted collecting cave artifacts, dodging neighborhood obstacles on my paper route, and conquering the new world. And the theme song to M.U.L.E. will forever be ingrained into my memory (side note: A really interesting article on the creation of M.U.L.E.).
Unfortunately, I spent all of my time playing games and not learning how to create them. My BASIC knowledge didn’t get past:
10 PRINT "SOME PHRASE FUNNY TO A 12-YEAR OLD"; : GOTO 10 RUN
I’ve always wanted to learn more about game development and decided to start learning some of the basics. I thought a good first step would be looking into collision detection. One quick Google search later and I came across a great post by Paul Firth on that exact topic. I only needed to get halfway through the article to learn how to animate balls bouncing in a box, animate balls bouncing in a rotated box, and to develop a simple game of Pong (source code can be found here). Paul’s blog contains a wealth of in-depth information about game creation and I hope to get through many more of his posts.
I’m currently making my way through Charles Petzold’s book The Annotated Turing. Petzold’s book, Code: The Hidden Language of Computer Hardware, is a must read for any software developer and is my favorite computer-related book. The Annotated Turing is proving to be just as interesting.
I’m only halfway through the book so I can’t provide a complete review. The first few chapters discuss Alan Turing’s educational background along with some introductory information on computability and number theory.
Petzold then breaks down Turing’s seminal paper, On Computable Numbers, With an Application to the Entscheidungsproblem. I started this book thinking much of the information would be over my head, but Petzold does a great job of breaking things down and providing easy-to-understand explanations.
Along with Petzold’s commentary, I decided it wold be helpful to create a Turing Machine simulator that I could use as I read through the book. The source code can be found here and a running demo can be found here. The demo includes some pre-configured Turing machine samples from the book, but allows you to define your own machine. Since I’m only halfway through the book, the simulator likely does not simulate the Universal Turing Machine that Turing ultimately designed. I’m hoping to continue updating the code as I finish the rest of the book.
So go out and grab the book, test out different machines on the simulator (or better yet, write your own simulator) and see how the computing age began. It’s a great way to learn about number theory, state machines, and is also a great reminder that we are all standing on the shoulders of giants.
Part 1 of this series can be read here.
In this post I’ll discuss the code that handles updating the UI.
Communication Line View
class DecoderView extends Backbone.View initialize: -> @model.bind('parsedCharacter', @render) render: (token) => messageBox = $('#messageBox') messageBox.val(messageBox.val() + token)
The CommunicationLineView class is a Backbone.js view class that handles the animation of signals sent across the communication line. In Part 1, I mentioned that the model representing the communication line fires a hasNewData event each time the tokens progress one step through the line. As you can see above, this view is bound to that event and rerenders itself every time it receives the event. The render method iterates over the current tokens and draws the appropriate token shape for each line position.
class MorseDecoder extends Backbone.Model initializeKey: => """ Omitting code that initializes the morse code key dictionary. """ initialize: => @inputTokens =  @numEmptyTokensInARow = 0 @initializeKey() processToken: (token) => if token == '' @parseTokens() if ++@numEmptyTokensInARow >= 10 else if token == kWordStopToken @parseTokens() if @inputTokens.length > 0 @trigger('parsedCharacter', ' ') else @inputTokens.push(token) @numEmptyTokensInARow = 0 parseTokens: => if @inputTokens.length > 0 token = @key[@inputTokens.join('')] @trigger('parsedCharacter', token) if token != undefined @numEmptyTokensInARow = 0 @inputTokens.length = 0
The Decoder model is responsible for determining what characters the user has sent across the line. The processToken function is called each time the tokens on the communication line progress one step through the line. The decoder processes the current tokens sent by the user anytime it sees 10 or more empty tokens in a row or receives a word-break token. If the decoder parses a known morse code sequence it fires a parsedCharacter event letting the message field know it needs to rerender itself.
class CommunicationLineView extends Backbone.View initialize: -> @model.bind('hasNewData', @render) render: (tokens) => context = document.getElementById( "communicationLineCanvas").getContext('2d') context.clearRect(0, 0, context.canvas.width, 29) tokenNum = 0 for token in tokens do (token) -> if kDotToken == token context.beginPath() context.moveTo((50 * tokenNum) + 15, 15) context.arc((50 * tokenNum) + 15, 15, 10, 0, Math.PI*2, false) context.closePath() context.fill() context.stroke() else if kDashToken == token context.fillRect((50 * tokenNum) + 15, 15, 25, 10) else if kWordStopToken == token context.fillRect((50 * tokenNum) + 30, 5, 10, 20) tokenNum += 1
The Decoder view is a Backbone.js view class that represents a simple text box to display the characters the user has sent across the line. Anytime the Decoder model emits a parsedCharacter event, the Decoder view appends the parsed character to the end of its text box.
In this post I’ll discuss the code that handles the user input.
init = -> decoder = new MorseDecoder communicationLine = new CommunicationLine( 'decoder': decoder) straightKey = new StraightKeyInput( 'el': $('#straight-key-div'), 'model': communicationLine) communicationLineView = new CommunicationLineView( 'el': $('#communication-line-div'), 'model': communicationLine) decoderView = new DecoderView( 'el': $('messageBoxDiv'), 'model': decoder) drawSignalLine() $(document).ready init
The init function sets up all of the Backbone.js model/view classes. Note that each Backbone view is initialized with both its corresponding HTML element and corresponding model object.
The init function also draws the "communication line" in a canvas element.
drawSignalLine = -> context = document.getElementById( "communicationLineCanvas").getContext('2d') context.clearRect(0, 0, context.canvas.width, context.canvas.height) context.moveTo(0, 30) context.lineTo(500, 30) context.strokeStyle = "#000" context.closePath() context.stroke()
The application processes user input using the StraighKeyInput class, a Backbone view class associated with an input button:
class StraightKeyInput extends Backbone.View initialize: -> @dashTimer = null @dashFlag = false @wordStopTimer = null @wordStopFlag = false events: 'mousedown #straight-key': 'startTimers', 'mouseup #straight-key': 'sendUserInput' startTimers: => @dashTimer = setTimeout(@dashTimerExpired, 250) @wordStopTimer = setTimeout( @wordStopTimerExpired, 1000) dashTimerExpired: => @dashFlag = true wordStopTimerExpired: => @wordStopFlag = true sendUserInput: => if @wordStopFlag @model.addToken(kWordStopToken) else if @dashFlag @model.addToken(kDashToken) else @model.addToken(kDotToken) clearTimeout(@dashTimer) clearTimeout(@wordStopTimer) @dashFlag = false @wordStopFlag = false
The class uses two timers to determine which "token" a user intends to send across the line. Using Backbone’s declarative style for event binding, I bind the mousedown event to a function that starts both timers. The mouseup event is bound to a function that pushes the appropriate token to the model based on how long the user held down the input button.
class CommunicationLine extends Backbone.Model initialize: (options) => @inputQueue =  @communicationLine = ['', '', '', '', '', '', '', '', '', ''] @decoder = options.decoder setInterval(@moveDataOneStep, 100) addToken: (token) => @inputQueue.push(token) moveDataOneStep: => @decoder.processToken(@communicationLine.pop()) nextToken = @inputQueue.shift() @communicationLine.unshift( if undefined == nextToken then '' else nextToken) @trigger('hasNewData', @communicationLine)
The CommunicationLine class is a Backbone model class that represents the tokens currently moving across the telegraph line. It also contains a queue that holds the input tokens generated by the user. The class also holds a reference to the object responsible for decoding the user input (more on that tomorrow).
Every 100 milliseconds, the communication line shifts its tokens over one spot. The token popped off the line is passed to the decoder. The model then checks the input queue to determine if a user-generated token is available to be pushed onto the line. If not, the model pushes a default token (an empty string). The model then triggers an event to indicate the communication line state has changed and that the object representing the communication line view needs to be re-rendered (more on that tomorrow).