Saturday, November 3, 2012

Is dependency injection needed in Node.js?

Recently I felt the need to write a DI manager.

As I completed my implementation I started to wonder the simple nature of it. If you adhere to the one module per file mindset, I’d wager you don’t need it. Take the following for example.

var Pen = require('Pen');
var Notepad = require('Notepad');

function Reporter() {
    this.pen = new Pen();
    this.notepad = new Notepad();
}

Reporter.prototype.pen = null;
Reporter.prototype.notepad = null;

Reporter.prototype.write = function (note) {
    this.pen.write(note, this.notepad);
}

var reporter = new Reporter();

A reporter needs a pen and notepad to write, here we manually setup the dependencies.

We could do this with dependency injection:

var di = new DependencyManager();
di.register(Pen);
di.register(Notepad);
di.register(Reporter, {
    pen: 'Pen',
    notepad: 'Notepad'
});

var reporter = di.create('Reporter');

My question is, is there a need for DI in Node?

The benefit I can see is that with DI we can override the instances of pen and notepad at run time more easily.

Tuesday, October 9, 2012

Benchmarking jpeg resizing tools

Update2

I ran the following commands utilising -size 8.333% and -scale 1/12:

time ( while ((n++ < 100)); do convert 6977576953_8e36188141_o.jpg -size "8.333%" -resize 886 -quality 90 dest_im.jpg; done );
real	10m27.572s
user	12m11.340s
sys	0m56.694s

time ( while ((n++ < 100)); do gm convert 6977576953_8e36188141_o.jpg -size "8.333%" -resize 886 -quality 90 dest_gm.jpg; done );
real	10m28.351s
user	13m21.717s
sys	0m33.366s

time ( while ((n++ < 100)); do djpeg < 6977576953_8e36188141_o.jpg -dct int -scale 1/12 | pnmscalefixed -width 886 | cjpeg -quality 90 -sample 1x1 > dest.jpg; done );
real	0m31.784s
user	0m38.853s
sys	0m1.650s

As you can see the djpeg method is blindingly fast, in comparison to the IM and GM versions, being 95% faster. I feel like I’m being somewhat unfair to IM and GM by asking them to potentially resizing to a floating point number. So I re ran them again, this time with -size 886×865, the exact final output size:

time ( while ((n++ < 100)); do convert 6977576953_8e36188141_o.jpg -size 886x865 -resize 886 -quality 90 dest_im.jpg; done );
real	9m35.862s
user	12m10.302s
sys	0m56.124s

time ( while ((n++ < 100)); do gm convert 6977576953_8e36188141_o.jpg -size 886x865 -resize 886 -quality 90 dest_gm.jpg; done );
real	9m22.672s
user	13m28.120s
sys	0m33.702s

So, the effect of resizing to a floating point value, costs in the region of 1s for this test, but it’s still not as quick as my djpeg + cjpeg method.

Update 1

It’s been pointed out to me that GraphicsMagick and ImageMagick both have the -size option that can be used to pre-scale images before any further manipulation is performed. In that vein, djpeg also has -scale which will pre-scale an image to a N{1…16}/M fraction, ie 1/8 = 12.5%. I believe this are equal so wil re-perform the test with these options and record the results here

The experiment

In the quest to find the best command line image resizing tool I ran an original image @ 7668 × 7488, 100 times through each command line tool using the following method:

time ( while ((n++ < 100)); do [/* insert command here */] ; done );

I appreciate this isn’t exactly scientific, but as a first round it will help me identify the fastest of the competitors.

The original License Some rights reserved by Bobby McCruffimage du -h original.jpg 5.9M original.jpg ImageMagick

time ( while ((n++ < 100)); do 
    convert original.jpg -resize 886 -quality 90 dest_im.jpg; 
done );

real	9m25.119s
user	12m14.881s
sys	1m3.075s

du -h dest_im.jpg
136K	dest_im.jpg
Resultant image:
image

GraphicsMagick

time ( while ((n++ < 100)); do 
    gm convert original.jpg -resize 886 -quality 90 dest_gm.jpg; 
done );

real	9m42.185s
user	13m24.283s
sys	0m42.524s

du -h dest_gm.jpg
140K	dest_gm.jpg
Resultant image:
image

djpeg + cjepg & pnmscale

time ( while ((n++ < 100)); do 
    djpeg < original.jpg -dct int | pnmscalefixed -width 886 | cjpeg -quality 90 -sample 1x1 > dest.jpg; 
done );

real	4m22.249s
user	4m33.203s
sys	0m25.874s

du -h dest.jpg
132K	dest.jpg
Resultant image:
image

The conclusion

Looking carefully at the images I can see that the djpeg+cjpeg one is slightly bluer than the original and the other two competitors, but at almost half the time taken (i casually observed the CPU which was lower as well) this has to be a viable option when resizing many images.
The file size was also smaller, however this could be due too like colour not matching. I’ll keep investigating if I can improve the colour quality in future experiments.

What do you think?

Sunday, October 7, 2012

iOS6 Safari Caching POST Responses

If you’re wondering how to prevent the caching of POST responses in nginx I think the following works.

location / {
    if ( $request_method = POST ) {
        add_header Cache-Control no-cache;
    }
}

Let me know if it works for you too

Wednesday, September 26, 2012
Don’t build an app based on your website. Build the app that acts as if websites never existed in the first place. Build the app for the person who has never used a desktop computer. Because they’re coming. Soon. My Product Feedback | massive greatness by MG Siegler
Friday, April 20, 2012

Dirty rectangles

Recently I’ve been experimenting in HTML5 game development and like my last post, this post is to document my findings.

Dirty Rectangles, what are they?

Imagine canvas animation is similar to cel animation, in that you compose your animation using serveral layers. Cel animators don’t want to have to draw the entire character for each frame if the only thing that is moving is the character’s mouth. (thanks to @speakersfive for this analogy)

With dirty rectangles, we detect which areas of our game have changed and therefore need updating.

How do we detect a dirty rectangle

The simplest way is to keep an array of ractangles, foreach over them on the next draw pass and clear those areas of our canvas.

You might be thinking; “what about my background or HUD?”, remember the cel animation analogy? Well just like cel animation we’d create our game in layers, leaving our background unaffected by our player’s movement.

Whenever we make a change to the player’s position, we’d mark the player sprite as dirty and add its rectangle to the array of dirty rectangles

How do we code this>

Coding this is fairly straight forward, so lets start with our game object.

// Game is our game object and hold all data about our game
// as well as update and draw methods
Game.dirtyRectangles = [];
function Player(x, y, width, height) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
}


/**
 * Move player by x and y increments
 * @param  {Number} x player x increment
 * @param  {[type]} y player y increment
 * @return {void}
 */
Player.prototype.move = function Player_move(x, y) {
    var original_x = this.x;
    var original_y = this.y;

    this.x += x;
    this.y += y;

    // if some change to the position was made
    if (original_x != this.x || original_y != y) {
        this.dirty = true;

        // add this rectangle to the dirty rectangles array
        // note: it's the rectangle before the movement was made
        Game.dirtyRectangles.push({
            x: original_x,
            y: original_y,
            width: this.width,
            height: this.height
        });
    }
};

So let me explain what we are doing here.

This prototype is configured to have an x and y position and a width and height. These properties control the position of the player and dirty rectangle size and position.

When we call move() to move out player we first store the existing position and then update it. Next we check if the position changed since the start of the method, when we stored the position, if it did then we set the dirty property and push an object holding the bounding rectangle of the previous position into the dirty rectangle array.

Next we move on to our game loop’s draw method.

Game.draw = function Game_draw() {
    var ctx = Game.canvasContext;


    var i, dirtyRectangleCount = this.dirtyRectangles.length;
    for (i = 0; i < dirtyRectangleCount; i+= 1) {
        var rect = this.dirtyRectangles[i];

        // clear this rectangle from the canvas
        ctx.clearRect(rect.x, rect.y. rect.width, rect.height);
    }

    // clear the dirty rectangle list
    this.dirtyrectangles = [];

    // then redraw any dirty sprites
    var spritesCount = this.sprites.length;
    for(i = 0; i < spritesCount; i += 1) {
        var sprite = this.sprites[i];

        // is the sprite dirty?
        if (sprite.dirty) {
            sprite.draw(ctx); // pass canvas context to the sprite
        }
    }
};

Okay, here we iterate of the the dirty rectangles array and clear those parts of the canvas. then we iterate over the sprites and redraw any sprites that have been marked as dirty. Simple.

Next we’ll need to mark our sprite as clean again. The best place to do this is probably the sprite’s draw method.

/**
 * Draw the player
 * @param  {CanvasContext} ctx canvas context
 * @return {void}
 */
Player.prototype.draw = function Player_draw(ctx) {
    /*
        ...
        our drawing code
        ...
    */
   
   // set our sprite to clean again
   this.dirty = false;
};

And that’s it. Only the changed parts of our screen will be updated using dirty rectangles.

Feel free to give me feedback on twitter @bytespider

Wednesday, April 4, 2012

requestAnimationFrame and HTML5 game loops

When looking at writing a HTML5 game, I first went down the usual route of using setTimeout(run, 1000/60);. However due to the nature of javascript, this isn’t always optimal. Javascript is single threaded so you can’t always guarantee that your frame will be rendered when you expected it.

In walks requestAnimationFrame

Thankfully there’s a new kid on the block, requestAnimationFrame, and the browser will call your function when it has rendering time free and passing the time.

But how do we update our game loop to use this? In much the same way as setTimeout() thankfully.

function main(time) {
    run();
    window.requestAnimationFrame(main);
}
window.requestAnimationFrame(main);

Gotcha

This one stumped me for a while, but in my simple game the CPU was hitting 100%. So I added code to reduce the frame rate.

var skipTicks = 1000 / 30, nextTick = new Date().getTime();
function run(time) {
    while (time > nextTick) {
        update();
        draw();

        nextTick += skipTicks;
    }
};

However my CPU usage was still 100%. I had a think and it dawned on me, requestAnimationFrame makes a request for rendering time and the browser will give the next available spot. But the browser is so fast, we’re practically requesting a frame every millisecond, no wonder my CPU hits 100%.

So I’ve updated my code, to wait 10ms before requesting the next animation frame.

function main(time) {
    run();
    setTimeout(function () {
        window.requestAnimationFrame(main);
    }, 10);
}
window.requestAnimationFrame(main);

Object cloning using ES5

function clone(object) {
    var cloned = Object.create(object.prototype || null);
    Object.keys(object).map(function (i) {
        cloned[i] = object[i];
    });

    return cloned;
}
Thursday, March 1, 2012 Tuesday, February 28, 2012

Using CommonJS modules for UI View components in Titanium

I’ve been playing with using CommonJS modules in Appcelerator Titanium to create reusable components and prototypes. I start with a basic object structure:

function Car() {
    this.init.apply(this, arguments);
}

Car.prototype.init = function (make, model) {
    this.make = make;
    this.model = model;
};

Car.prototype.make = null;
Car.prototype.model = null;

Car.createWithMakeAndModel = function (make, model) {
    return new Car(make, model);
};

module.exports = Car;

Whilst you may argue there is some redundancy in the pattern I use, I makes sections of code easy to override later on if I decide to use it as a prototype.

You may also frown upon the use of module.exports = Car;. However I find that

var Car = require("Car");

looks and feels better than

var Car = require("Car").Car;

You may argue that you should never have access to the constructor and that you should use factory methods. Whilst your argument is valid, I prefer to be able to make sure that my object X is an instance of Y using the built in instanceof operator.

How this applies to views and windows

For views and windows I add .view and .wnd properties to my object inside my init() method, which is where I call all other parts of my view construction. Take the following example of a list view.

function UIListView()
{
    this.init.apply(this, arguments);
}

UIListView.prototype.init = function () {
    this.view = Ti.UI.createTableView();
};

UIListView.prototype.populate = function (data) {
    var i = 0, len = data.length, row;
    for (; i < len; ++i)
    {   
        row = Ti.UI.createTableViewRow(data[i].asTableViewRow());
        this.view.appendRow(row);
    }
};

module.exports = UIListView;

As you can see I can now call populate() at anytime to update my view with new data.

I’d like to experiment more with patterns like this. I’d love to hear your opinions and suggestions for other patterns or structures, so tweet me or send me an email.

Friday, February 24, 2012

Chosen does allow you to set when the search box should show

I started using chosen in a few projects but it frustrated me that the search box would always show regardless of how many options I had.

I read through the website and discover theres no mention of a setting, so being a good little community developer I decide to implement the functionality.

After getting my head round the coffeescript source, which in my opinion is far worse to read and grok than javascript, I add the code. Then i think I’ll be really good and make it configurable before I submit a pull-request.

Thats when I discover disable_search_threshold, and wondering what it was I try it. Turns out that it’s exactly the functionality I had just written and wasted time on.

So next time you’re using chosen and you need to hide search for the first, lets say, 10 items do this:

$(".chzn-select").chosen({
    disable_search_threshold: 10
});