Author Archives: David Thompson

Jump to Jasmine Specs with Rinari

I use the rinari Emacs mode to assist me when working on rails
projects. One of rinari’s most useful features is the ability to
quickly jump from one file to another related file. I use this
feature almost exclusively for jumping between a ruby class file and
its associated rspec file, but lately I’ve been spending most of my
time writing javascript. At VHL, we use jasmine for our unit testing
framework and the jasmine ruby gem to integrate it with our rails
projects. Rinari doesn’t have any built-in jump settings for jasmine
test files, so I wrote this quick hack to make it work:

;; Make rinari jump to/from javascript source files and specs.
(setcdr (assoc 'javascript rinari-jump-schema)
        '("j"
          (("app/assets/javascripts/\\1.js" . "spec/javascripts/\\1_spec.js")
           ("spec/javascripts/\\1_spec.js"  . "app/assets/javascripts/\\1.js")
           (t . "spec/javascripts/.*")
           (t . "app/javascripts/.*"))
          t))
(rinari-apply-jump-schema rinari-jump-schema)

Now I can press C-c ; f j to jump between a javascript file in
app/assets/javascripts/ and its jasmine test file in
spec/javascripts/. Perhaps I shouldn’t be overwriting the
predefined (but not very useful) javascript jump settings, but I
really wanted to use the j key.

From the blog dthompson by David Thompson and used with permission of the author. All other rights reserved by the author.

First GNU Guile Patch and More Guix Packages

I have spent some of the last month working on contributing to GNU
Guile and now I can finally say that I have contributed code to the
project. Guile has several hash table implementations: a Guile native
one, SRFI-69, and R6RS. SRFI-69 contains a handy procedure,
alist->hash-table, which allows for a sort of hash literal-like
syntax:

(alist->hash-table
 '((foo . 1)
   (bar . 2)
   (baz . 3)))

However, I prefer to use Guile’s native hash implementation, and
SRFI-69 is incompatible with it, so I decided to port
alist->hash-table. Unfortunately, it was not as simple as writing
just one procedure. The native hash tables actually have 4 different
ways of doing key comparisons: Using equal?, eq?, eqv?,
and user-defined procedures. This is a design flaw because the user
must make sure to use the right procedures at all times rather than
simply set the hash and assoc procedures when creating the
hash table instance.

Below is the final implementation. Since 3 of the 4 variations were
essentially the same, I wrote a short macro to reduce code
duplication.

;;;; Copyright (C) 2013 Free Software Foundation, Inc.
;;;;
;;;; This library is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU Lesser General Public
;;;; License as published by the Free Software Foundation; either
;;;; version 3 of the License, or (at your option) any later version.
;;;;
;;;; This library is distributed in the hope that it will be useful,
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
;;;; Lesser General Public License for more details.
;;;;
;;;; You should have received a copy of the GNU Lesser General Public
;;;; License along with this library; if not, write to the Free Software
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
;;;;

(define-syntax-rule (define-alist-converter name hash-set-proc)
  (define (name alist)
    "Convert ALIST into a hash table."
    (let ((table (make-hash-table)))
      (for-each (lambda (pair)
                  (hash-set-proc table (car pair) (cdr pair)))
                (reverse alist))
      table)))

(define-alist-converter alist->hash-table hash-set!)
(define-alist-converter alist->hashq-table hashq-set!)
(define-alist-converter alist->hashv-table hashv-set!)

(define (alist->hashx-table hash assoc alist)
  "Convert ALIST into a hash table with custom HASH and ASSOC
procedures."
  (let ((table (make-hash-table)))
    (for-each (lambda (pair)
                (hashx-set! hash assoc table (car pair) (cdr pair)))
              (reverse alist))
    table))

Not only did I manage to get my code into Guile, I was given commit
access to GNU Guix by the lead developer, Ludovic Courtès. I have
never had commit access to any free software project repositories
besides my own. I feel quite honored, as cheesy as that may sound.

Packages for SDL and SDL2 have been merged into master, and packages
for SDL_gfx, SDL_image, SDL_mixer, SDL_net, and SDL_ttf for SDL 1.2
are pending review.

I like to show off the elegance of Guix package recipes, so here’s
some code:

;;; Copyright Β© 2013 David Thompson <dthompson2@worcester.edu>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define sdl
  (package
    (name "sdl")
    (version "1.2.15")
    (source (origin
             (method url-fetch)
             (uri
              (string-append "http://libsdl.org/release/SDL-"
                             version ".tar.gz"))
             (sha256
              (base32
               "005d993xcac8236fpvd1iawkz4wqjybkpn8dbwaliqz5jfkidlyn"))))
    (build-system gnu-build-system)
    (arguments '(#:tests? #f)) ; no check target
    (inputs `(("libx11" ,libx11)
              ("libxrandr" ,libxrandr)
              ("mesa" ,mesa)
              ("alsa-lib" ,alsa-lib)
              ("pkg-config" ,pkg-config)
              ("pulseaudio" ,pulseaudio)))
    (synopsis "Cross platform game development library")
    (description "Simple DirectMedia Layer is a cross-platform development
library designed to provide low level access to audio, keyboard, mouse,
joystick, and graphics hardware.")
    (home-page "http://libsdl.org/")
    (license lgpl2.1)))

(define sdl2
  (package (inherit sdl)
    (name "sdl2")
    (version "2.0.0")
    (source (origin
             (method url-fetch)
             (uri
              (string-append "http://libsdl.org/release/SDL2-"
                             version ".tar.gz"))
             (sha256
              (base32
               "0y3in99brki7vc2mb4c0w39v70mf4h341mblhh8nmq4h7lawhskg"))))
    (license bsd-3)))

Much help is needed to package the GNU system for Guix. If you are
interested in helping, please drop by #guix on freenode, we are
friendly. πŸ™‚

From the blog dthompson by David Thompson and used with permission of the author. All other rights reserved by the author.

My First GNU Guix Patch

Over the weekend, I decided to try out GNU Guix: A fully functional
package manager based on Nix and a distribution of the GNU system. I’m
a big proponent of GNU Guile, thus I was excited to see a DSL for
package management written with Guile.

I was told that libtheora would be pretty easy to package, and it
was. Here’s what the package definition looks like:

(define libtheora
  (package
    (name "libtheora")
    (version "1.1.1")
    (source (origin
             (method url-fetch)
             (uri (string-append "http://downloads.xiph.org/releases/theora/libtheora-"
                                 version ".tar.xz"))
             (sha256
              (base32
               "0q8wark9ribij57dciym5vdikg2464p8q2mgqvfb78ksjh4s8vgk"))))
    (build-system gnu-build-system)
    (inputs `(("libvorbis" ,libvorbis)))
    ;; The .pc files refer to libogg.
    (propagated-inputs `(("libogg" ,libogg)))
    (synopsis "Library implementing the Theora video format")
    (description
     "The libtheora library implements the ogg theora video format,
a fully open, non-proprietary, patent-and-royalty-free, general-purpose
compressed video format.")
    (license license:bsd-3)
    (home-page "http://xiph.org/theora/")))

Pretty slick, eh? Now, I’m starting to work on packaging SDL (1.2
and 2) and the SDL extensions (gfx, ttf, etc.), which are not quite as
easy. I hope to package all of the dependencies that guile-2d will
need to be available as a Guix package.

From the blog dthompson by David Thompson and used with permission of the author. All other rights reserved by the author.

Guile-2D 0.1 Release

To celebrate the GNU Project’s 30th anniversary, I have decided to
make the very first release of my 2D game development framework for
GNU Guile. GNU Guile is a Scheme implementation, and has the honor
of being the official extension language of the GNU project. Guile-2D
is a layer above SDL, OpenGL, FreeImage, and FTGL that provides
abstractions for common 2D game programming requirements such as
sprites, tilesets, animations, scripting, and collision detection.

There is a lot of work to do in order to get Guile-2D up to snuff with
the game libraries for more popular languages like Python and Lua. I
am looking for contributors who share my vision of creating a fully
featured, easy to use game library in Scheme.

Guile-2D currently supports GNU/Linux distributions. I am looking for
help to get it running on OS X and Windows.

Please refer to the INSTALL.org, README.org, and texinfo files to
learn how to install Guile-2D, run example programs, and write your
own games.

Download the release tarball
Browse the source code on GitHub

From the blog dthompson by David Thompson and used with permission of the author. All other rights reserved by the author.

Liberating a Thinkpad X220

I had been looking for a suitable replacement to my old, slow Compaq
laptop that I purchased during my freshman year of college when I had
very little money. What I liked about my old laptop was that it played
well with free software. I had no trouble getting all of my hardware
to work out-of-the-box with fully free GNU/Linux distributions such as
Trisquel, and I wanted any future laptops of mine to play nicely, too.

I have heard much praise for Thinkpads over the years. Solid build
quality, utilitarian design, and cheap to buy used. However, upon
further reading, I realized that most newer Thinkpads require nonfree
software in order to the drive the Intel wireless chip. Furthermore,
there was DRM present in the BIOS that would prevent the installation
of PCIe wireless chips that weren’t in the whitelist.

This really bummed me out, but I bought a Thinkpad anyway. I found a
great deal on a used X220 on ebay for $400. In order to liberate it, I
had to make a small deal with the devil: Use the pre-installed Windows
7 to flash a hacked BIOS that removes the whitelist. I could only find
the needed BIOS as a Windows executable, so I didn’t have much
choice. This process left me hoping that coreboot gains wider
adoption.

Once I had verified that I didn’t brick my Thinkpad, I installed the
new wireless card. I purchased a Wireless N, half-height, mini PCIe
card from Thinkpenguin. It uses an Atheros chipset and is free
software compatible. I met Chris, the owner of Thinkpenguin, at this
year’s Northeast GNU/Linux Fest at Harvard. He is doing some great
work and I wanted to support his business. It was nice to buy from
someone who could assure me that the hardware I purchased is fully
supported on a libre GNU/Linux distribution.

Now that my Thinkpad was free (sans BIOS, of course), it was time for
the final touch. I replaced the hard drive with a 128GB SSD and
installed Debian testing. It takes roughly 9 seconds to get from GRUB
to the GDM login screen. It feels very nice to have a device that
boots so quickly.

Now that everything had been installed and configured, I was able to
start hacking and get a feel for things. The keyboard is the nicest
I’ve ever used on a laptop. The TrackPoint is quite a nice way to
move around once you get used to it. The ThinkLight is pretty neat
when you’re in a dark area. The battery life is extremely
impressive. I don’t know exactly how long it lasts yet but I never
have to charge it while I am using it. I was lucky if I got 2 hours of
battery life out of my old laptop, which caused me to be constantly
tethered to an AC adapter. The screen is matte, which is awesome
because it’s very difficult to use a laptop outdoors when the screen
is glossy. 1366×768 is not an ideal resolution (16:9 be damned), but I
can live with it on a 12.5" screen. Last but not least, I honestly
like the aesthetics. A lot of people are enamored with the brushed
aluminum designs by that fruit company, but I love the flat black,
functional design of the Thinkpad.

I hope to really break this thing in over the weekend at the GNU 30th
Anniversary
hackathon. πŸ™‚

From the blog dthompson by David Thompson and used with permission of the author. All other rights reserved by the author.

Font Rendering in OpenGL with Pango and Cairo

I am working towards a 0.1 release of my game development framework
for GNU Guile, guile-2d. One of the few remaining blockers on my
to-do list is font rendering. A reddit user, Madsy9, pointed me in
the right direction with this comment. There are two libraries needed
to perform nice font rendering with proper internationalization
support: Pango, "a library for laying out and rendering of text, with
an emphasis on internationalization," and Cairo, "a 2D graphics
library with support for multiple output devices."

It took me awhile to put together all of the pieces and build a
working sample program. The goal of this post is to help others that
may be trying to accomplish a similar task that have no prior
knowledge of Pango and Cairo. I will assume basic knowledge of C, SDL, and
OpenGL throughout this post.

Let’s get the basic SDL and OpenGL initialization out of the way:

#include <pango/pangocairo.h>
#include <SDL.h>
#include <SDL_opengl.h>

#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
#define FONT "Sans Bold 18"
#define TEXT "The quick brown fox is so かわいい!"

void
init_sdl ()
{
    SDL_Init (SDL_INIT_EVERYTHING);
    SDL_SetVideoMode (WINDOW_WIDTH, WINDOW_HEIGHT, 0, SDL_OPENGL);
}

void
init_gl ()
{
    glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
    glDisable (GL_DEPTH_TEST);
    glEnable (GL_BLEND);
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable (GL_TEXTURE_2D);
    glViewport (0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    glOrtho (0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, -1, 1);
    glMatrixMode (GL_MODELVIEW);
    glLoadIdentity ();
}

create_texture simply creates an OpenGL texture given an array of
pixel data and the texture dimensions. Our Cairo surface will use BGRA
color.

unsigned int
create_texture (unsigned int width,
                unsigned int height,
                unsigned char *pixels)
{
    unsigned int texture_id;

    glGenTextures (1, &texture_id);
    glBindTexture (GL_TEXTURE_2D, texture_id);
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexImage2D (GL_TEXTURE_2D,
                  0,
                  GL_RGBA,
                  width,
                  height,
                  0,
                  GL_BGRA,
                  GL_UNSIGNED_BYTE,
                  pixels);

    return texture_id;
}

draw_texture clears the screen, renders a simple textured quad
using OpenGL’s immediate mode, and then swaps buffers.

void
draw_texture (int width,
              int height,
              unsigned int texture_id)
{
    /* Render a texture in immediate mode. */
    glMatrixMode (GL_MODELVIEW);
    glLoadIdentity ();
    glClear (GL_COLOR_BUFFER_BIT);
    glPushMatrix ();
    glBindTexture (GL_TEXTURE_2D, texture_id);
    glColor3f (1.f, 1.0f, 1.0f);

    glBegin (GL_QUADS);
    glTexCoord2f (0.0f, 0.0f);
    glVertex2f (0.0f, 0.0f);
    glTexCoord2f (1.0f, 0.0f);
    glVertex2f (width, 0.0f);
    glTexCoord2f (1.0f, 1.0f);
    glVertex2f (width , height);
    glTexCoord2f (0.0f, 1.0f);
    glVertex2f (0.0f, height);
    glEnd ();

    glPopMatrix ();
    SDL_GL_SwapBuffers();
}

create_cairo_context is used to make a new Cairo context that
draws to a raw data surface. The return value, a cairo_t, is the
main object in Cairo. All drawing is done via a cairo_t object. A
context needs a surface to draw on.
cairo_image_surface_create_for_data creates a raw data surface for
us. We will be translating the surface into a texture later on.

cairo_t*
create_cairo_context (int width,
                      int height,
                      int channels,
                      cairo_surface_t** surf,
                      unsigned char** buffer)
{
    *buffer = calloc (channels * width * height, sizeof (unsigned char));
    *surf = cairo_image_surface_create_for_data (*buffer,
                                                 CAIRO_FORMAT_ARGB32,
                                                 width,
                                                 height,
                                                 channels * width);
    return cairo_create (*surf);
}

create_layout_context also makes a new Cairo context, but this
context is for PangoLayout objects. In Pango, a layout describes the
style of a paragraph of text. The layout needs a context in order to
function. We use cairo_image_surface_create with dimensions of 0x0
because we won’t actually be rendering to this surface. Instead, we
will layout our text and use create_cairo_context to build a
context with a surface that is the size of the rendered text. Cairo
uses reference counting for dynamically allocated objects, so we need
to call cairo_surface_destroy when we’re done with the temporary
surface. The context still maintains a reference to the surface, so
the memory for the surface will not be freed until the context is.

cairo_t*
create_layout_context ()
{
    cairo_surface_t *temp_surface;
    cairo_t *context;

    temp_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
    context = cairo_create (temp_surface);
    cairo_surface_destroy (temp_surface);

    return context;
}

get_text_size tells us the size of the text that’s in the layout,
in pixels. Pango’s units are not in pixels, so we must divide by
PANGO_SCALE in order to get pixel units.

void
get_text_size (PangoLayout *layout,
                unsigned int *width,
                unsigned int *height)
{
    pango_layout_get_size (layout, width, height);
    /* Divide by pango scale to get dimensions in pixels. */
    *width /= PANGO_SCALE;
    *height /= PANGO_SCALE;
}

render_text is where all of the magic happens. First, we create a
layout with a layout context and set the text that we will render with
this layout. TEXT is defined earlier in the program as "The quick
brown fox is so かわいい!"

Then we create a PangoFontDescription object. This object
represents the font that we want to render. Earlier in the program,
FONT is defined as "Sans Bold 18". Pango is able to figure out
how to load a font from a string in this format. Your system must be
able to recognize the font family and font face, though. I haven’t
yet figured out how to have Pango render an arbitrary font from a
*.ttf file.

Next, we create a rendering context by getting the layout’s size and
creating a context with a surface big enough to show all of the
rendered text.

Finally, we set the font color to white, render the text to the
surface with pango_cairo_show_layout, and create an OpenGL texture
from the surface. We also clean up all the objects that we no longer
need before returning.

unsigned int
render_text (const char *text,
             unsigned int *text_width,
             unsigned int *text_height,
             unsigned int *texture_id)
{
    cairo_t *layout_context;
    cairo_t *render_context;
    cairo_surface_t *temp_surface;
    cairo_surface_t *surface;
    unsigned char* surface_data = NULL;
    PangoFontDescription *desc;
    PangoLayout *layout;

    layout_context = create_layout_context ();

    /* Create a PangoLayout, set the font and text */
    layout = pango_cairo_create_layout (layout_context);
    pango_layout_set_text (layout, text, -1);

    /* Load the font */
    desc = pango_font_description_from_string (FONT);
    pango_layout_set_font_description (layout, desc);
    pango_font_description_free (desc);

    /* Get text dimensions and create a context to render to */
    get_text_size (layout, text_width, text_height);
    render_context = create_cairo_context (*text_width,
                                           *text_height,
                                           4,
                                           &surface,
                                           &surface_data);

    /* Render */
    cairo_set_source_rgba (render_context, 1, 1, 1, 1);
    pango_cairo_show_layout (render_context, layout);
    *texture_id = create_texture(*text_width, *text_height, surface_data);

    /* Clean up */
    free (surface_data);
    g_object_unref (layout);
    cairo_destroy (layout_context);
    cairo_destroy (render_context);
    cairo_surface_destroy (surface);
}

main is pretty simple. We initialize SDL and OpenGL, render text
to a texture, and enter the rendering loop. The program will run
until you click the close button, press "enter", or press "q".

int main (int argc, char **argv)
{
    SDL_Event event;
    int keep_running = 1;
    unsigned int texture_id;
    unsigned int text_width = 0;
    unsigned int text_height = 0;

    init_sdl ();
    init_gl ();
    render_text(TEXT,
                &texture_id,
                &text_width,
                &text_height);

    /* Update/render loop */
    while (keep_running) {
        SDL_PollEvent (&event);

        switch (event.type) {
        case SDL_QUIT :
            keep_running = 0;
            break;

        case SDL_KEYDOWN :
            if (event.key.keysym.sym == SDLK_ESCAPE)
                keep_running = 0;
            if (event.key.keysym.sym == SDLK_q)
                keep_running = 0;
            break;
        }

        draw_texture (texture_id, text_width, text_height);
        SDL_Delay (16);
    }

    /* Clean up */
    glDeleteTextures (1, &texture_id);

    SDL_Quit();

    return 0;
}

And we’re done! You should now be able to render some text in an
OpenGL context. I hope this brief tutorial was helpful. Font rendering
isn’t easy, and it’s not really my area of interest. I’m glad that
Pango exists to do all of the real work for me so that I can more
quickly move on to the parts of graphics programming that I actually
enjoy.

You can download the full source code here.

From the blog dthompson by David Thompson and used with permission of the author. All other rights reserved by the author.

The Little Schemer

Yesterday, I took a trip to the MIT Press Bookstore and picked up a
copy of The Little Schemer. I’ve only spent a few hours reading and
coding along with it, but I’ve had a lot of fun. The following is a
mini-review based on my experience thus far.

"The Little Schemer" teaches you to think recursively using an
interesting and comedic writing style and the Scheme programming
language. While Scheme is the language of choice, the real goal is to
teach you problem solving rather than the details of a specific
language. The book starts off simple, explaining what atoms, lists,
and S-expressions are. Rather than providing the definition and then
showing examples, it first gives examples in the form of a question
and answer.

Example:

Is it true that this an atom?

atom

Yes, because atom is a string of characters beginning with a
letter.

From the examples given, a definition is created. In later examples, a
Scheme procedure is written that produces the correct answers for all
of the questions stated before it. It’s fun to build the procedure,
verify that it works for all cases, and compare your implementation
with the book’s.

"The Little Schemer" defines ten commandments that are essential to
correctly solving the problems in the book. Some commandments are
first given in an incomplete form, and expanded later when a greater
level of understanding has been achieved. The problems that you solve
reinforce the commandments. You might notice that you start writing
procedures without thinking much about it, much like the muscle memory
earned from using Emacs a lot. Gerald J. Sussman was right when he
said that this book "can perform the same service that Hanon’s finger
exercises or Czerny’s piano studies perform for the student of the
piano." I have no idea who Hanon and Czerny are, but I get it. For the
drummers out there, you could liken this book to Stick Control.

The writing style is very informal, comedic, and food themed. Page 13
has a space reserved for jelly stains, and page 52 tells you to "go
cons a piece of cake onto your mouth." I have laughed a number of
times while reading. Oh, and let’s not forget about the cute elephant
drawings. This is definitely not your average boring, dry computer
science book. If you are interested in a unique and enjoyable learning
experience, then I highly recommend reading "The Little Schemer".

From the blog dthompson by David Thompson and used with permission of the author. All other rights reserved by the author.

AngularJS Post-mortem

AngularJS is the new popular client-side Javascript application
framework developed by Google. We have recently adopted it at Vista
Higher Learning for building our latest features that require a lot
client-side logic. Now that I have a few applications under my belt,
it’s time to talk about my experience.

If you want a quick TL;DR: I think AngularJS is good, but it has a
steep learning curve and there’s no well defined set of best
practices.

Note: I will be using plenty of terms that will probably only make
sense for people that have used AngularJS.

The Good Stuff

These are the things that went well. The things that made me glad that
we chose to use AngularJS.

Easier Testing

Our Javascript test suite uses Jasmine. AngularJS is built with test
frameworks like Jasmine in mind. AngularJS could tends to be easily
testable due to dependency injection. When the components of an
application don’t rely on global state, it is easier to mock services
for unit tests.

Separation of Concerns

AngularJS stresses separating the view from the data structures and
logic behind it. I think everyone that’s written a somewhat complex
JQuery application can relate to the mess of CSS selectors and click
callbacks that the code quickly degenerates into.

AngularJS allows you to break up the DOM into logical chunks that are
handled by separate controllers. Treating the application as many
small pieces working together rather than one giant DOM blob keeps the
code clean. Message passing via $emit and $broadcast keeps
controllers loosely coupled to each other.

No More JQuery Spaghetti

Directives, the strategy for encapsulating DOM manipulation, are
wonderful. It is an elegant solution to the mess that was JQuery
selectors and event callbacks. AngularJS comes with a lot of
directives out of the box to handle the most common stuff like
showing/hiding elements, handling clicks, dynamically setting CSS
classes.

More Maintainable Code

AngularJS is feature-rich. It does a lot on your behalf, which greatly
reduces the amount of boilerplate code needed to get a prototype up
and running. I had the opportunity to essentially rewrite an existing
JQuery application using AngularJS. The results were clear: The
AngularJS version had fewer lines of code, was more readable, and
was easier to debug.

Bumps in the Road

These are the things that didn’t go smoothly. They boil down to
AngularJS having a steep learning curve and ill-informed software
design decisions on my part.

Understanding the Magic

A lot of things seem to happen by magic. For example, it is possible
to make a asynchronous request and get a promise object in
return. When the promise is assigned to a variable on $scope,
AngularJS not only knows to ignore it while the request hasn’t
finished, but it will re-assign to that variable the value of the
asynchronous call when it completes. It is a nice feature, but it
takes some digging to find out what is really going on.

Poor Documentation

I know I’m not the only one that hates the official AngularJS
documentation. The documentation is getting more complete, but it’s
still not very useful. Functions frequently have a blurb describing
what they do, but no explanation of the parameter list. It’s hard to
use a function that doesn’t describe what it expects for input.

When the documentation confused us, which it did frequently, we turned
to the AngularJS book from O’Reilly for help. I need to get around
to reading more of it.

RESTful Resources and Rails

AngularJS claims to be targeted at CRUD applications, but using the
HTTP backend and the Resource abstraction that sits on top of it was
particularly difficult. A good amount of time was spent on trying to
get the HTTP requests from resources to conform to what our Rails
backend expects, like root-wrapping.

Bloated Controllers

I frequently made controllers that had too much state and logic that
should have been extracted into services/factories/etc. A controller
would start out slim but would quickly grow to several hundred lines
of code as features were added. Controllers should be the middle man
between the view and the model and that’s it.

Some tell-tale signs that a controller is becoming bloated:

  • There are a lot of private functions (not defined on $scope)
  • Functions are defined on $scope just so you can unit-test them,
    but are never used in the template

I attribute controller bloat to a lack of knowing the appropriate uses
for other AngularJS components. It was easy to just keep adding to the
controller.

Conclusion

Overall, I think things went well, but I (and the rest of my team)
made a lot of beginner mistakes. But that’s the learning process,
isn’t it?

Now that I know more about AngularJS, it will be easier to make better
design decisions moving forward.

I believe that as AngularJS continues to mature, some concensus in the
community about best practices will emerge that will make things
easier for beginners.

From the blog dthompson by David Thompson and used with permission of the author. All other rights reserved by the author.

guile-2d – A 2D Game Development Framework for GNU Guile

This is the very first devlog entry for my pet project, guile-2d. As
the title suggests, guile-2d is a 2D game development framework for
GNU Guile, a Scheme implementation that has the honor of being the
official extension language of the GNU project. Guile is a language
with a growing number of features, but it still lacks a large
assortment of libraries. I like to do 2D game programming, and I saw a
niche that needed to be filled. Python has Pygame, Lua has Love, but
there’s no fun and accessible game programming library for
Guile. Guile-2d is working to correct that.

The goal of Guile-2d is to create an easy to use 2D game programming
framework. Libraries like SDL give the programmer a rather low-level
set of tools that they can use to build a game, guile-2d will provide
high-level tools over low-level SDL and OpenGL for commonly used
elements of 2D games: tile maps, sprite animation, particle systems,
collision detection, vector math, A* pathfinding, etc. Such features
will allow a game developer to very quickly produce a working
prototype with guile-2d.

Guile-2d is a framework, which means that it has some opinion about
what the right way to do things is. The most apparent example of this
is the game loop. The game loop runs at 60 frames-per-second and uses
fixed timestep updates. Those that have read Fix Your Timestep will
know that this decision is a good thing.

Perhaps the most important feature of guile-2d is the ability to do
"live coding". When the game loop starts, a REPL
(read-eval-print-loop) server is started. Using the great Geiser
extension for Emacs to connect to the REPL server, one can modify
their game as it is running. This gives users the power to evaluate
some new code and see the changes reflected immediately in the game
window. No need to restart the game unless you crash it!

This has been a brief overview of some of the features and goals of
guile-2d. If this project interests you, you can check out the source
code on Github.

From the blog dthompson by David Thompson and used with permission of the author. All other rights reserved by the author.

StumpWM on Debian Wheezy

Everyone that’s ever talked to me about software development knows
that I am in love with Emacs. Emacs has a wonderful keyboard driven
interface and is almost infinitely customizable via Emacs Lisp. I’ve
done a lot of programming in Emacs from my not-so-great laptop
lately. My laptop has a rather poor 1280×800 resolution and low
performing integrated graphics chip. Until today, I was running the
GNOME 3 desktop environment on it. Unlike most people (or perhaps just
a loud minority), I like GNOME 3. However, I wanted something that was
both less graphics intensive and more keyboard driven than GNOME
Shell and Mutter.

Someone on IRC told me about StumpWM, a window manager written
entirely in Common Lisp. I had heard of StumpWM before, but back then
I wasn’t an Emacs user and I’ve never really stuck with any tiling
window manager that I’ve tried (DWM, Awesome). Now that I know the
power of a fully programmable environment thanks to Emacs, I decided
to give StumpWM a try. After some initial pains trying to get it to
run, I am now using it very happily.

Here is what I had to do to get StumpWM running on Debian Wheezy.

  1. Install StumpWM

    sudo apt-get install stumpwm
    
  2. Create an .xinitrc file in my home directory with the following
    text

    exec stumpwm
    
  3. Workaround clisp "component not found" errors

    I could not get StumpWM to start until I created the following
    symbolic links:

    ln -s /usr/share/common-lisp/source/stumpwm/stumpwm.asd /usr/share/common-lisp/systems/stumpwm.asd
    ln -s /usr/share/common-lisp/source/cl-ppcre/cl-ppcre.asd /usr/share/common-lisp/systems/cl-ppcre.asd
    
  4. Start the X server

    startx
    

I use the GNOME Desktop Manager, so I also created a session file for
StumpWM in /usr/share/xsessions/stumpwm.desktop.

[Desktop Entry]
Encoding=UTF-8
Name=StumpWM
Comment=This session logs you into StumpWM
Exec=stumpwm
TryExec=stumpwm
Icon=
Type=Application

I hope this brief installation guide can be of use to one of you out
there in Internet land. Perhaps in the future I will write an article
about customizing StumpWM with Common Lisp.

From the blog dthompson by David Thompson and used with permission of the author. All other rights reserved by the author.