Sunday 24 April 2011

[Demoscene] Numb Res by Fairlight & CNCD 2011.1

This weekend was The Gathering, a massive gathering of nerds and gamers in Norway. What started out as a humble demoscene party has blossomed into a 5 day gathering of some of the best gamers and scene groups around.

The following is the offering by the ever excellent CNCD & Fairlight. I posted a particle-tastic video by them last year so if you like this sort of thing I strongly recommend that you check that out too.



Edit: Oh if you like the music on this video you should check out the artist album, its bloody fantastic! http://stereowildlife.co.uk/

Monday 11 April 2011

URI Parser For HaXe

Continuing on my theme of the moment haXe, I have another post  regarding the development of my haXe rewrite of  ChromeCrawler.

I was in need of a way to split a URL into its various parts. To do this in previous versions of ChromeCrawler I used a ready built one I found on the web.

I thought it should be a fairly simple matter to port this to haXe, unfortunately however this wasn't the case. The problem was that haXe, unlike JS, doesnt have the exec() method on its regular expression function. What this meant is that the URL couldnt be split in the same way.

Confused I jumped on the haXe IRC, unfortunately the solutions the kind people there provided didnt work. Instead I posted a message on the mailing list and within a few hours I had my answer. The solution was to use EReg.match() then EReg.matched() to get each part.

Anyways, I promised to share the code when I was done so here it is:

[codesyntax lang="javascript"]
package utils;
import haxe.Http;

/**
* ...
* @author mikecann.co.uk
*/

class URLParser
{
// Publics
public var url : String;
public var source : String;
public var protocol : String;
public var authority : String;
public var userInfo : String;
public var user : String;
public var password : String;
public var host : String;
public var port : String;
public var relative : String;
public var path : String;
public var directory : String;
public var file : String;
public var query : String;
public var anchor : String;

// Privates
inline static private var _parts : Array<String> = ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];

public function new(url:String)
{
// Save for 'ron
this.url = url;

// The almighty regexp (courtesy of http://blog.stevenlevithan.com/archives/parseuri)
var r : EReg = ~/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;

// Match the regexp to the url
r.match(url);

// Use reflection to set each part
for (i in 0..._parts.length)
{
Reflect.setField(this, _parts[i], r.matched(i));
}
}

public function toString() : String
{
var s : String = "For Url -> " + url + "\n";
for (i in 0..._parts.length)
{
s += _parts[i] + ": " + Reflect.field(this, _parts[i]) + (i==_parts.length-1?"":"\n");
}
return s;
}

public static function parse(url:String) : URLParser
{
return new URLParser(url);
}
}

[/codesyntax]

So for example the following use:

[codesyntax lang="javascript"]
trace(new URLParser("http://www.mikecann.co.uk/programming/haxe/haxe-jqueryextern-gotcha?somevar=1242#home"));

[/codesyntax]

Will print the following:

[codesyntax lang="text"]
For Url -> http://www.mikecann.co.uk/programming/haxe/haxe-jqueryextern-gotcha?somevar=1242#home
source: http://www.mikecann.co.uk/programming/haxe/haxe-jqueryextern-gotcha?somevar=1242#home
protocol: http
authority: www.mikecann.co.uk
userInfo: undefined
user: undefined
password: undefined
host: www.mikecann.co.uk
port: undefined
relative: /programming/haxe/haxe-jqueryextern-gotcha?somevar=1242#home
path: /programming/haxe/haxe-jqueryextern-gotcha
directory: /programming/haxe/haxe-jqueryextern-gotcha
file:
query: somevar=1242
anchor: home

[/codesyntax]

Simples!

Im not sure how performant the reflection usage would be on the various platforms haXe targets but atleast it would work and its fairly elegant to boot ;)

Edit: Thank you Adrian Cowen for posting this as a haXe snippet: http://haxe.org/doc/snip/uri_parser

Sunday 10 April 2011

HaXe & jQueryExtern Gotcha



As some of you may know, I have been getting into haXe reccently. For those of you dont know what haXe is, this is taken from haxe.org:
haXe (pronounced as hex) is an open source programming language

While most other languages are bound to their own platform (Java to the JVM, C# to .Net, ActionScript to the Flash Player), haXe is a multiplatform language.

I have been aware of haXe for a long time, infact I used to make extensive use of precursor to haXe, MTASC the alternative compiler for AS2. Since the launch of AS3 however, Nicolas Cannasse of Motion-Twin has moved onto HaXe, and the project has flourished.

I have used HaXe in the past for various small projects, usually to take advantage of some of the features that the language offers Flash developers that AS3 cant offer us. Features such as function inlining and the fast memory ops mean that flash developers can really get some great performance out of their libraries while at the same time still able to compile to SWC's.

Recently I have been exploring the various other targets offered by haXe, not just the flash one. Currently haXe supports the following targets:
Javascript : You can compile a haXe program to a single .js file. You can access the typed browser DOM APIs with autocompletion support, and all the dependencies will be resolved at compilation time.

Flash : You can compile a haXe program to a .swf file. haXe is compatible with Flash Players 6 to 10, with either "old" Flash 8 API or newest AS3/Flash9+ API. haXe offers very good performance and language features to develop Flash content.

NekoVM : You can compile a haXe program to NekoVM bytecode. This can be used for server-side programming such as dynamic webpages (using mod_neko for Apache) and also for command-line or desktop applications, since NekoVM can be embedded and extended with some other DLL.

PHP : You can compile a haXe program to .php files. This will enable you to use a high level strictly-typed language such as haXe while keeping full compatibility with your existing server platform and libraries.

C++ : You can now generate C++ code from your haXe source code, with the required Makefiles. This is very useful for creating native applications, for instance in iPhone development.

C# and Java targets are coming soon! (from @cwaneck)

The target that has taken my interest recently has been Javascript.

Having recently worked in Javascript on my Chrome extensions PostToTumblr and ChromeCrawler I have gained a better understanding of how JS works and how to code in it. Despite this however I still cant get over what I consider some "very nasty" things in the language. Lack of type safety, nested anonymous functions and lack of proper classes just have my stomach all in knots thinking about them.

So I was extremely happy to discover that haXe now targets Javascript. It meant I could write the next version of ChromeCrawler in type-safe, class-happy haxe and it would simply hide all the nastyness from me once it compiles. (You can ofcourse modify the JS that is exported if you so wish however)

So now, finally to the point of this post. I sat down to write the core functionality of the crawler. To do the URL crawling so far I had been using jQuery's get() method to load an external page.

How was I to use the jQuery library in haXe I wondered. Well thankfully this has already been thought of with the special "extern" keyword: http://haxe.org/doc/js/extern_libraries

Thankfully Andy Li has also already provided an excellent version of the library for haXe in his jQueryExtern project. Using the haxelib command I downloaded the project and started coding.

It wasnt long however before I ran into a compilation issue when I tried to use the static function get() on the JQueryS class:
characters 2-9 : Unknown identifier : JQueryS

This confused me as no matter what I did, I couldn't get the haXe compiler to recognise the class. Having spent an evening stuck on the problem I decided to email the creator of the project Andy Li.

It turns out that to beable to use the JQueryS class you must first import the JQuery class:
import JQuery;

Low and behold that worked!

As I couldn't find the solution to this problem on a Google search I thought I would write up the solution myself so that others don't stumble on this rather singular gotcha.