Friday, 22 July 2011

Calling pregenerated jsonp files via javascript with a hardcoded callback function name

Recently I have had to work on a JavaScript heavy project that had a .js file that any third party could include on their website, it had the caveat that it could not use Jquery, and for reasons of performance it had to make ajax calls to pregenerated json files.

So the simple way of invoking a jsonp call is:
window['NAMEOFCBFUNCTION'] = function (o) {
    //Callback logic here
    alert(o.someJsonKey)
   }

   document.getElementsByTagName('body')[0].appendChild((function () {
                var s = document.createElement('script');
                s.type = 'text/javascript';
                s.src = Url;
                return s;
            })());

And the jsonp file would look like
NAMEOFCBFUNCTION({someJsonKey:"someJsonValue"})

However in my case the .js file could theoretically be included on the same page multiple times, and could make multiple jsonp calls as well, but since the callback function name is hardcoded, I couldn't reassign the callback function until the last call was done or start another jsonp call until the previous one was done, so I came up with the following logic that uses a queue to send off the jsonp requests and calling the associated callback functions in the correct order before firing off the next queued jsonp call, whilst also keeping context as well!:

function NameOfMyMainClass () {
// All sort of logic here....
}

 if (!window['NAMEOFCBFUNCTION']) {
        window['NAMEOFCBFUNCTION'] = function (o) {            
            var callbackargs = window.CONTEXTQUEUE.shift();            
            callbackargs.success && callbackargs.success.apply(callbackargs.context, [o]);
            if (window.CALLBACKQUEUE && window.CALLBACKQUEUE.length > 0) {
                var args = window.CALLBACKQUEUE.shift();
                args.context.GetJSON.apply(args.context, [args.url, args.success])
            }
        };   
    }

    NameOfMyMainClass.prototype.GetJSON = function (Url, success) {        
        var cntxt = this;

        if (window.CONTEXTQUEUE && window.CONTEXTQUEUE.length > 0) {
            if (!window.CALLBACKQUEUE) window.CALLBACKQUEUE = new Array();
            window.CALLBACKQUEUE.push({
                url: Url,
                success: success,
                context: cntxt
            });
        }
        else {            
            if (!window.CONTEXTQUEUE) window.CONTEXTQUEUE = new Array();
            window.CONTEXTQUEUE.push({ context: this, success: success });                        
            document.getElementsByTagName('body')[0].appendChild((function () {
                var s = document.createElement('script');
                s.type = 'text/javascript';
                s.src = Url;
                return s;
            })());
        }
    };

Friday, 28 August 2009

.NET is not VB6, so stop setting objects to nothing/null!

A lot of old school VB6/classic ASP developers seem to have a habit of setting objects to nothing/null just before they're about to go out of scope. But it does nothing! I know I should ignore it, but the redundant code drives me mad.

Rant aside, here is some proof!

First, let's create a big object class, in fact each instance of this baby will be 10MB!
class MyBigObject
{
private byte[] lotsOfData = new byte[1024 * 1024 * 10];//'10 MB

public MyBigObject()
{
for (int i = 0; i < lotsOfData.Length; i++)
lotsOfData[i] = 255;
}
}

Now create a function, but let's be brave and trust in the .NET garbage collector, and not set anything to null!
void useData()
{
MyBigObject bigInstance = new MyBigObject();
Console.WriteLine("Big object in use:" + GC.GetTotalMemory(false));
//Potentially use it now.    
}
Okay, now to find out how much memory we are using - use the big object, and again, and again..
(note we are printing out the total memory usage for each step)
Console.WriteLine("Before:" + GC.GetTotalMemory(false));    
useData();
useData();
useData();
useData();
useData();
useData();
Console.WriteLine("After:" + GC.GetTotalMemory(false));
From the output we can see after the first iteration the memory jumps up to about 10MB (fair enough the memory is still allocated after use) but after the following iterations memory use still stays at about 10MB, Proof that the garbage collector does actually work.


I can almost hear the VB6 folk shouting - "But if you set it to nothing the garbage collector will pick it up sooner, and the application will use less memory!". Okay Lets test that, and set the object to nothing/null.
static void useData()
{
MyBigObject bigInstance = new MyBigObject();
Console.WriteLine("Big object in use:" + GC.GetTotalMemory(false));      
//Potentially use it now.                
bigInstance = null;//Freeing memory here, right?
}
Oh the tension
.
.
.
It is the same!


Conclusion:

So do not set your objects to Nothing/null in .NET when they're about to go out of scope, it is redundant.

Wednesday, 12 August 2009

Memorize how to draw Hiragana software - initial release



This program was written by me, for me, to help me memorize Hiragana, soon Katakana and less soon Kanji. The idea is that I expand it as I go through the journey of learning Japanese. The scope could include adding in some exercises... but for now it only contains Hiragana exercises!

I have released it under the GNU GPL v3 licence.
Windows executable: LearnHiraganaV0.1alpha.zip
C# source code: LearnHiraganaV0.1alphaSRC.zip

Requirements are:
It asks you to draw a particular random kana, e.g. ki. Using your mouse you draw it from memory then once you are done you click the done button, it then shows you what it is meant to look like. You then indicate if it is correct or not. If you get it correct enough times it won't ask you for that one again - you can specify how often in a row each kana has to be correct before it removes it from the rotation.

Under options you can limit it to only Gojūon (simple list) or Dakuten/handakuten ('' and ゜accents).

See video sample of it running below:






Sunday, 9 August 2009

How to convert manga for your Sony Ebook reader

There seems to be a few guides out there on how to convert Manga scanlations to a format that is easily readable on an Ebook, and they all seem to point to the same two pieces of software: Manga2Ebook and RasterFarian (please note RasterFarian produces .lrf files) however, both were released before Windows Vista was around and Manga2Ebook will work on Vista but unfortunately RasterFarian won't! However both are essential for a pleasant reading experience, so for a step by step guide:

First

  • Get hold of an XP or Server 2003 OS (I have a vmware image install for this kind of thing)
Then
  • Download Manga2Ebook (the download with imagemagick-DLL included worked well for me) and RasterFarian
  • Extract Manga2Ebook, and install RasterFarian
  • If your images aren't zipped up, you will need to zip it before Manga2Ebook will work
  • Point Manga2Ebook to your zip folder, and under settings ensure that you are resizing the images to the same dimensions as the output PDF otherwise the sides will be chopped off!

  • Once that is done you should have a PDF, but if you put that on your ebook it is hard to read and a massive file too, so now run it through RasterFarian by right clicking on the pdf and choosing RasterFarian.
  • I chose all the defaults, except for the split option instead I chose full page - which works okay, but if you are finding the text a bit too small to read, then you can split it into two or four panels. RasterFarian will show you how far it has progressed in a dos window, see screengrab below

  • Once that is done, you should have an .lrf file ready for your Sony Ebook reader!
Below is a photo that should give you more or less an idea of the quality: