Showing posts with label Javascript. Show all posts
Showing posts with label Javascript. Show all posts

Tuesday, 5 March 2013

PostToTumblr v3.18 - Fixed Tumblr oauth change

head

 

Just a quick update to say I have now fixed the authentication issue my PostToTumblr that quite a few people contacted me about.

What was going on was that Tumblr appear to have changed the format of the data they return from a token request which was causing a library that PostToTumblr relies on to fail.

Before PostToTumblr can post content on a users behalf it first must get an "access token". This token is given to PostToTumblr as part of the authentication flow.

When PostToTumblr first starts up it checks to see if it still has a valid token (they can expire over time and other various reasons). If it doesnt it must go through the authentication flow. Firstly it redirects the user to the grant permission dialog:

screenshot_02

When the user clicks allow Tumblr then returns an "oauth token" and an "oauth verifier" to PostToTumblr, which it can then use to get an "access token" which is used to do the posting.

The problem that this update fixed was that the "oauth verifier" that was returned from Tumblr changed:

screenshot_03

You see at the end of the query string there is now a "#_=_" well this was causing havoc with the URL parameter parsing code in the Google oauth library I was using.

My solution is quick and dirty, just strip out the "#_=_" from the url while parsing:
// MIKE HACK!!	  
if(param.indexOf('oauth_verifier=')!=-1)
{
param = param.replace('oauth_verifier=','');
param = param.replace('#_=_','');
decoded['oauth_verifier'] = ChromeExOAuth.fromRfc3986(param);
}
else
{
var keyval = param.split("=");
if (keyval.length == 2) {
var key = ChromeExOAuth.fromRfc3986(keyval[0]);
var val = ChromeExOAuth.fromRfc3986(keyval[1]);
decoded[key] = val;
}
}


Well I hope this helps anyone else that may encounter this issue too!

Sunday, 20 January 2013

Post To Tumblr v3.13

head

Just a quick update to my Chrome Extension PostToTumblr this morning to fix a few things and add a couple of features after the large update in v3.12.

The change log:
- v3.13 -- 20/01/13 
+ More one-click options for post state, tags and caption
+ New button in the options for resetting Tumblr auth
+ New button for formatted posts for posting to draft
+ Fixed it so you no longer have a menu on one-click if you only have one blog
+ Correct verbs are now displayed in the desktop notifications when posting
+ Fixed an issue with white pages if you rename your blog

Saturday, 29 December 2012

Recursive, Nuts & Bolts Part 3 - Rendering the Results (3 of 3)

screenshot_01

This is part two of my three part series on the internals of Recursive, an extension for Chrome. In the first post I talked about the general structure of Recursive and some of the lessons I learnt from dealing with Typescript. In the second post I discussed how Recursive goes about crawling and parsing the web. In this, the final post, i'm going to talk about how Recursive represents, lays out and renders that crawled data on the screen.

Code Structure


As mentioned in the first post in the series I have tried to keep the rendering logic as separate as possible from the actual crawling logic. This separation between the renderer and the crawler makes things simpler to understand in the code. The crawler is a model and the renderer is the view. The renderer simply displays whatever state the model contains.

Representation


The question how to represent all the masses of data that the crawling process generates was tricky to decide upon and took quite a bit of tinkering before it ended up in its current form. I first toyed with the idea of displaying the data as a simple list of links where each list represents the next depth in the recurse, I demonstrated this concept in an early video:



The problem, as can be seen in the above, is that there is still far too much data to display in that manner. I also wanted something that was more immediately visual, something that lets you see relative importance of nodes in the graph at a glance, simple lists of links couldn't provide this.

I remembered when I first launched Chrome Crawler a while back someone sent a video in which they had cleverly used Chrome Crawler and the open-source graphing program Gephi to great effect:



When thinking about the problem of how to represent the data I was aware that a key difficulty was representing the relative importance of nodes and edges in the crawl graph but not to swamp the user with too much information. I eventually decided that grouping pages and files together under the domains that the crawler found them would be a good way of giving a sense of the relative size of each domain and the number and type of files found there.

screenshot_02

Nodes, I decided, would be joined by a single line from the parent domain that crawled it. This way there wouldn't be too many confusing lines on the render yet you could still see how various domains were connected.

Layout


Once I had the idea how I was going to represent the data from the crawler it was then a matter of working out how to lay out the nodes. I knew that the nodes were going to be circles and I knew that I didn't want them to overlap, I also wanted a dynamic looking graph (like the one in Gephi video above).

To achieve this I decided to use Box2D the popular physics engine to take some of the difficulties with positioning away for me. Using Box2D each edge between the nodes is a distance joint and the nodes themselves are simple circle shapes. Then I just let the simulation run and the nodes move and naturally try to separate from each other.

screenshot_03

This solution worked in some situation however it was sub-optimal in others. The problem is that because each crawl is different you can end up in situations where there are many small nodes grouped about a parent or a few very large nodes:

ScreenHunter_01 Dec. 27 12.49

I spent a good long while trying to ‘frig’ it so that the length of the distance joints between the nodes were right in most instances so that the nodes didn't overlap. The code was starting to look really messy and complex incorporating rules that depended on the number of children / siblings, the relative size of the nodes, the total length of the sibling nodes, the area values with proportion to the total area and so on.

No matter how many times I multiplied here, divided here I couldn't hack it into a form that worked for every crawl. So I decided to go back to the drawing board and rethink the layout problem.

ScreenHunter_02 Dec. 27 12.54

After some scribbling I decided that what I needed to calculate was the total amount of space required for a node and the amount of space its parent had to allocate to fit it. Once I could correctly calculate those two it should be a relatively simple matter of spacing child nodes correctly about their parent.

I also noted that each node’s required area is simply the recursive sum of the space required by its children:

ScreenHunter_03 Dec. 27 12.59

At the smallest scale the total space required by a single node is just its radius. If you add a child to that node then total space required is the nodes radius plus a constant distance plus the diameter of the child.

ScreenHunter_04 Dec. 27 13.00

As you add more children however you run into the problem that there won't be enough space about the parent:

ScreenHunter_05 Dec. 27 13.02

So now you must layer those children into concentric rings so that there is definitely enough space for each child. So how to do that. Well that was the tricky part and required some trigonometry (just about the only thing I remembered from high school maths).

ScreenHunter_06 Dec. 27 13.13

Because we know the distance between the centre of the child and its parent and we know the radius of the child we can calculate the angle between two lines that extend from the parent and lie on points on the outside of the child’s radius and are perpendicular to the child's centre.

When we have this angle its a simple matter of looping through all of the (sorted smallest to largest) children adding up the angle required until you reach the maximum 360 degrees. Then you increase the distance between the parent by the diameter of the last node and start again on the second layer of children. This way you can guarantee that every child will have sufficient space about the parent.

ScreenHunter_01 Dec. 29 12.31

Rendering


I knew that the graph would get very large and would be complex to render so performance was critical. I didn't want to spend ages messing around with WebGL, having done some before I knew that potentially it could take a lot longer than the relatively simple canvas2d. Because Chrome has a hardware accelerated canvas2d I reasoned that the performance should be okay.

Unfortunately even on a decent machine, the rendering is still rather slow, so that you usually cant crawl beyond about a depth of 3. I tried all the common tips and tricks that can be found on the internet such as minimizing context switches when drawing lines and circles and caching commonly drawn things together in an image so that there are fewer draw calls. I even tried to assist chrome by putting the icons on one large image sheet, thinking it would be represented by a single texture behind the scenes thus minimise context switches when rendering to the GPU.

It seems however, that if you want performance in the browser you are going to have to go with WebGL.

Improvements


Given more time it would be nice to explore swapping out the 2d rendering pipeline with a purely 3d one using WebGL, that should increase the speed of things a great deal. One idea is I could use point-sprite particles to render each icon within a 3d graph with wireframe lines to represent the edges between the nodes.

I did some work on point sprite particles in WebGL a little while ago so I know it should be possible to render millions (literally) of nodes and edges that way.

Finally


Well thats the end of my series on the internals of Recursive, I hope you have enjoyed it. I haven't decided whether I want to release the source code just yet, I may return to the project in the future, but if you are interested in looking over the code send me an email: mike.cann@gmail.com

Thursday, 27 December 2012

Recursive, Nuts & Bolts Part 2 - Crawling the World Wide Web (2 of 3)

screenshot_05

This is part two of my three part series on the internals of Recursive, an extension for Google Chrome. In the first post I laid the groundwork for the contents of this and the next post. In this post i'm going to talk a little about what Recursive does internally once given  a URL.

Chrome Crawler


Recursive is actually based on an extension called Chrome Crawler I wrote about a year ago, but I had to change the name of due to Google's branding policy for Chrome Extensions. So although Recursive was rewritten from the ground up, a lot of the ideas discussed below stem from that project.

Cross-Origin XMLHttpRequest


Much in the same way that search engine crawlers work, Recursive, downloads a url, scans it for links then recursively follows them.

Normally this sort of behaviour isn’t permitted to Javascript (or Flash for that matter) when running within a web page due to the Same Origin Policy without specific permission from the server you are calling. Chrome extensions however don't have this restriction and thus (with permission given in the extension manifest) the extension is able to download content from any server.

This special behaviour is called the Cross-Origin XMLHttpRequest and is what allows Recursive to work its magic.

Code Structure


As briefly mentioned in the previous post the Crawling logic is separated from the Rendering logic. This differs from how Chrome Crawler was implemented where he rendering and crawling logic were mushed together. This separation took a little more thought and planning the result however is that the crawling logic makes much more sense and doesn't contain anything that doesn't purely pertain to the logic and data involved with crawling.

The crawling code is split up into three main files the Graph, the Crawler and the Parser.

screenshot_06

The Graph is the central class that drives the crawling process. Only one of these exists for the application. It provides a number of functions for starting, stopping and pausing the crawling process. It also has a number of events (exposed through signals) that it uses to let listeners (the renderer) know when a particular event occurs.

The Crawler represents a single crawl instance. Its responsibility is to follow a single URL then report when it progresses, returns or errors. The Parser takes the returned HTML from the Crawler and scans it looking for links and files. It then returns the results which are then stored in the Crawler instance.

Parsing Problems


One issue I encountered while developing Recursive (and Chrome Crawler) was the performance and security issues involved with parsing the HTML returned from the crawl. The way I originally handled this was to pass the entire HTML to JQuery then ask it for all ‘src’ and ‘href’ attributes:

[codesyntax lang="javascript" lines="normal"]
function getAllLinksOnPage(page)
{
var links = new Array();
$(page).find('[src]').each(function(){ links.push($(this).attr('src')); });
$(page).find('[href]').each(function(){ links.push($(this).attr('href')) });
return links;
}

[/codesyntax]

The problem with this is that behind the scenes jQuery is constructing a DOM which it uses for querying. Normally this is what you want, but in this instance its a problem because its rather slow process, also the browser executes the script tags and other elements when it generates the DOM. The result of which is the crawling is really slow and there were many security errors generated while crawling.

The solution was to use regex to parse the HTML and look for the attributes manually like so:

[codesyntax lang="javascript" lines="normal"]
var links = new string[];

// Grab all HREF links
var results = c.pageHTML.match(/href\s*=\s*"([^"]*)/g);
if (results) results.forEach(s=>links.push(s.split("\"")[1]));

// And all SRC links
results = c.pageHTML.match(/src\s*=\s*"([^"]*)/g);
if (results) results.forEach(s=>links.push(s.split("\"")[1]));

[/codesyntax]

I was worried that the sheer amount of html text that must be parsed by the regex would result in things being really slow however it seems to hold up quite well, and is definitely not the bottle neck in the app.

Custom File Filter


One addition to the result parsing that was added in v.1.1 was the ability to define a custom file filter:

Screenshot_002

Enabling this adds a third regex call into the results parser. Any matches are added to the Crawler’s files as a special kind of file. When the user opens the files dialog all the matches are shown under a special category:

Screenshot_003

Improvements


Although the regex doesn't take very long to execute when parsing the HTML I had the thought that Javascript workers could be used to take advantage of the multiple cores that are present in most CPUs these days. Perhaps if I decide to perform some more complex sort of parsing i'll revisit this idea.

Finally


Thats about it for part two of my three part discussion on some of the internals of Recursive. Head over to the third part to find out more about the layout and rendering of the returned data.

Sunday, 16 December 2012

Recursive v.1.1

Screenshot_001

I have found a little more time this evening to fix some bugs and make some improvements to my Chrome extension Recursive. The changes are as follows:

----- v.1.1 ------
- Now only displays recursive icon on tabs with http:// and https://
- Full screen now works (uncommented that line of code, doh!)
- Pause and reseting a recurse now works correctly
- Renamed the title page of the app
- Some Performance improvments
- There is now an option in the settings to define a custom file filter
- There is now a setting to disable removing duplicate files


One of the main new additions is the ability to add a custom filter in the settings which recursive uses when parsing a file:

Screenshot_002

If any are found they are then displayed in the files dialog:

Screenshot_003

As I say, just a quick update this evening. I plan on writing some more in-depth blog posts this week explaining some of the nuts and bolts of Recursive.

Tuesday, 4 December 2012

Recursive - Explore the endless web



Wow, well that took longer than expected! 44 days ago I blogged that I had started work on a second version of my Chrome Crawler extension and have only just managed to get it to a state I was happy with enough to release it. To be fair I had been on a trip to New York during that period so perhaps I can be excused. Having said that however I think the time has been well spent and am fairly proud of the result.

TL;DR


Recursive is an experimental tool for visualising the world wide web. Given a URL it downloads the page search for links and then recursively downloads those. The information is then displayed in a node-based graph.

The Name


So what's this all about? Why is it called 'Recursive', why not 'Chrome Crawler 2'?

Although I would like to have called the spiritual successor to 'Chrome Crawler', 'Chrome Crawler 2' Chrome's branding guidelines forbid using the Chrome name or logo (they brought this in since the launch of Chrome Crawler 1).

With that in mind I decided that rather bend Chrome Crawler's name and logo to fit the guidelines I would create a whole new logo, name and app. The app is a total rewrite from the previous iteration anyway so I thought it justified.

According to dictionary.com there is no definition for "Recursive" or "Recurse" but there is one for "Recursion":
2. the application of a function to its own values to generate an infinite sequence of values.

So a tool that downloads pages, follows the links on that page to download other pages seemed like a rather apt description of something that is "Recursive".

Video


Before I go much further, I put together this little video demonstrating some of the extensions core functionality:


Installing


Installing and upgrading is dead simple thanks to how Google Chrome's extension system works. Just head over to this link and hit install:

https://chrome.google.com/webstore/detail/recursive/hbgbcmcmpiiciafmolmoapfgegbhbmcc

Then to launch it visit any website and hit the little icon in the Omnibox:


How it works


Recursive works by taking in a starting URL which it uses to download the page it points to:



Once that page is downloaded Recursive parses it looking for links and files. If it finds things it thinks are files then it records them against that URL. It then proceeds to visit all the links in turn, downloading the page then parsing the for yet more files and links.

This cycle continues until a certain "depth" is reached which is the maximum number of links away from the starting URL. You can set the maximum depth allowed in the settings:



One of the key improvements of Recursive over Chrome Crawler is the way it visualises the data as it is returned:



Every page is grouped by its domain and is represented by a circular "node".



So for example "http://mikecann.co.uk/personal-project/tinkering-with-typescript/" would be grouped under the "mikecann.co.uk" domain. Any other pages found while running that match this domain are added as little page icons inside the host node.



Any files that are found on a given page are given an appropriate icon and added to that page's domain node.



As Recursive downloads pages and follows links it records the path it takes. It then draws lines between the nodes that are linked:


Interacting


Using the mouse wheel you can zoom in and out to get a better perspective. Click and drag to move about the recursive space. You can also run the app in fullscreen if you so desire.



If you click on a node it tells Recursive to explore that node for one extra level depth.

Right clicking a node opens a menu that lets you either open all the pages contained in that node or view the files for that node.


Files


By using the context menu for a node you can checkout all the files that Recursive found for that node. The files are separated into various categories which you can toggle on or off:



Then if you wish you can download all the files as a zip.

The tech


I think i'll leave this section for the next blog post as this one is long enough already.

If you would like specific info on the tech in the meantime however or have some suggestions for features then don't hesitate to contact me: mike.cann@gmail.com

Well that's about it hope you like it. I had a blast making it even if it did take alot longer than I was expecting. It doesn't have much purpose really but there is a lot of cool new tech in there, which is reason enough to make it surely?

Friday, 19 October 2012

Tinkering With TypeScript



In the spirit of David Wagner's try { harder } talk on 'the value of tinkering' I decided to do a little tinkering with a new language from Microsoft called TypeScript.

TypeScript attracted me for three reasons. Its the new project from Anders Hejlsberg the creator of C#, it brings type safety to JavaScript and im a sucker for new technology.

TypeScript is basically a superset of Javascript much in the same way C++ is to C. So every single JS project is a valid TS project. This is good if you are familiar with JS already, you should be able to pick up TS fast and then get to grips with the other cool bits it bring.

TS compiles down to JS much in the same way that that JS target of Haxe compiles down to JS. Unlike Haxe however the generated code is much more readable and so although there is no integrated debugger (yet) you can just use Chrome's developer console to debug with without too much pain.

Before I get too much more into the specifics of the language I want to mention the project I am tinkering with TS for. A while back I wrote an extension for Chrome called Chrome Crawler. It is a rather simplistic web crawler written in JS and released as a Chrome extension (because of the cross-domain scripting limitations with normal JS).

Over the intervening couple of years I have returned to the project on occasion with an idea to do a second version, however I never actually completed one. So I thought it may be nice if I gave it a go again but this time using TypeScript and at the same time see how it compares to the Haxe JS target.

Chrome Crawler v2 isnt ready for release but checkout the quick video I put together below to see how its coming along:



The original idea was to lay out the crawling in a left to right fashion. So each crawl depth is put in its own column, but as you can probably tell from the video above, things start getting a little unmanageable when you get to just level 3 of crawler depth. So I think im going to have to rethink how I display the nodes in the crawl graph. I have some ideas, but that's going to have to wait until I return from my trip to NY next week.

More on that in later posts, lets take a look at a few key TypeScript features:

Typing



One of the key features of TypeScript is that it allows you to structure your code in a type-safe way. You can declare Classes, interfaces (inequivalent to typedef in Haxe) and modules as types then use them later.

TS also has structural typing so you can define a structure as part of a function or variable definition without first declaring a Class or Interface for it. For example:



This is great for many reasons but the big one for me is the way it assists tooling particularly when coupled with the excellent VisualStudio 2012 you get all the things you would expect such as intellisense, go to definition, find references and refactoring. For me it takes much of the pain out of the dynamic nature of JS.

As with AS3 and Haxe typing is optional. You can if you wish declare everything as "any" (dynamic in Haxe or * in AS3). Doing so however would forfeit many of the strengths of TS.

Like Haxe you can 'define' things as being available at runtime, this means you can reuse existing JS libraries without having to totally rewrite them in TS. By declaring an "interface" you can just tell the compiler that this type will exist at runtime (we did this with extern's in Haxe) and thus you can use the existing library in a type-safe way. For example here is a definition for the Facebook SDK:

https://github.com/mientjan/typescript-facebook-definition/blob/master/facebook.d.ts

Alot of the type-safe TS stuff is familiar to me because of Haxe. I think some things in TS are nicer fit because its only designed to compile to JS unlike Haxe which can compile to many different languages. For example TS has function overriding baked into the language also strongly typed functions in my option are a little nicer:

[codesyntax lang="text" lines="normal"]

(index: any, domElement: Element) => any

[/codesyntax]

is a function type that takes in two params and returns anything (including void), its Haxe inequivalent:

[codesyntax lang="text" lines="normal"]

Dynamic -> Element -> Dynamic

[/codesyntax]

These things however are just my opinion, but it does tie nicely into one of my favourite features of TypeScript...

Lambda Functions



Lambda functions are basically syntactical sugar to anonymous function definitions so instead of:

[codesyntax lang="javascript" lines="normal"]

var fn = function(a, b) { return a+b; }

[/codesyntax]

You could write this as:

[codesyntax lang="javascript" lines="normal"]

var fn = (a, b) => a+b;

[/codesyntax]

Which is really nice when looping over arrays:

[codesyntax lang="javascript" lines="normal"]

var a = [4,2,1,6,5];
a.sort((a,b)=>a-b).forEach(i=>console.log(i));

[/codesyntax]

Because TS uses type-inference all the variables in the above are type safe. I really love how terse this syntax is and have had quite a few discussions about introducing it into Haxe.

There is one big difference between function() and lambda definitions however and that is the way they handle scoping of "this".

For example take this example from the javascriptplayground.com blog post:

[codesyntax lang="javascript" lines="normal"]

$("myLink").on("click", function() {
console.log(this); //points to myLink (as expected)
$.ajax({
//ajax set up
success: function() {
console.log(this); //points to the global object. Huh?
}
});
});

[/codesyntax]

This is a common gotcha in JS coding and the usual solution is to do something like the following:

[codesyntax lang="javascript" lines="normal"]

$("myLink").on("click", function() {
console.log(this); //points to myLink (as expected)
var _this = this; //store reference
$.ajax({
//ajax set up
success: function() {
console.log(this); //points to the global object. Huh?
console.log(_this); //better!
}
});
});

[/codesyntax]

In TypeScript lambda functions "this" is scoped to the block in which the lambda was defined so the above can be written more simply as:

[codesyntax lang="javascript" lines="normal"]

$("myLink").on("click", function() {
console.log(this); // points to myLink (as expected)
$.ajax({
success: () => console.log(this); // points to myLink
});
});

[/codesyntax]

this.



One minor thing that does annoy be about TS is the necessity to put "this." in front of every single member variable access. For example:

[codesyntax lang="javascript" lines="normal"]

class Crawler {
constructor(private url:string){}

crawl(){
console.log(url); // error
console.log(this.url) // okay
}
}

[/codesyntax]

Some may consider it rather minor but I find it annoying coming from a Haxe / AS3 / C# perspective where member variable access is implied. I guess the reasoning is because in JS if you dont supply a var before a variable declaration / usage you are referring to global scope, thus in that above example "console.log(url);" would be trying to log global.url which is undefined.

Tooling



The tooling support for TS is pretty good so far. Visual Studio has a plugin for the language and has reasonably good support. There is still quite a bit of room for improvement here however. Things such as integrated debugging, code generation for functions event handlers etc and source formatting would be nice.

Because the TS compiler is written in TS they are able to create really cool things such as the TypeScript Playground:



With it you can mess around with TS and see its generated JS as you type. It even includes a version of intellisese for that type-hinting goodness.

Conclusion



I must admit I really like TypeScript. It provides a light-weight layer over the top of Javascript giving just enough of the type-safe goodness and language enhancements without making it totally alien to a JS coder.

The generated JS looks very similar to the source TS (and will look even more so once ES6 is mainstream) which is important when you are trying to debug a problem. I discovered this to be an important point when developing the Haxe version of my Post To Tumblr chrome extension. Haxe although awesome tends to generate alot of alien looking JS making it tricky to work out where to put a breakpoint.

More important than any particular nuance of the language however is who is backing it. Microsoft is a huge company with a massive following of developers. It pays many people to work on the language and evangelise it. What this results in is a much bigger community. A bigger community means you have more questions asked on Stack Overflow, more API definitions written and more job positions specialising in the language. Also having Anders Hejlsberg, the father of C#, behind it you can be confident that the language will continue to develop in a manner that (if you are a C# fan) makes sense.

I have been having a whole lot of fun in TypeScript, and have high hopes for its future.

Tuesday, 11 September 2012

All New Post To Tumblr Chrome Extension created with Haxe & Robotlegs



I have been working off and on for a while on an update to my popular Chrome Extension 'Post To Tumblr' and seeing as Tumblr have just changed thier API I thought it was time to accelerate its development and release it, finally.

First some screenshots to give you an idea of what it does:



You can right-click any thing on a page and "Post To Tumblr".



A new tab opens where you can format it how you like.



You can change the post type very easily.



When done you just "Create Post"

This version is written totally from scratch using Haxe's Javascript target. Although not strictly necessary for something as simple as this I thought it was a good opportunity to experiment around with Haxe's JS capabilities. I must admit I was pleasantly surprised at how well it worked.

Most stuff just worked. There are also plenty of externs out there for the popular Javascript libraries on lib.haxe.org such as the "chrome-extension" library.

Having type-safe Javacript is great for for so many reasons that im not going to get into here. I must admit however there were times when I was lazy and didn't want fancy creating a type-safe extern class for a library. Fortunately however Haxe has a mechanism for the lazy coder in the form of "untyped".

An example of this is the way in which you access the "localStorage" object in chrome extensions. localStorage is basically a global object that you can set keys and values in and will persist for the life of your extension. To access it you use: "localStorage[myKey]" to return a value. If you tried to do that in Haxe it would throw an error because Haxe has no concept of global variables (quite rightly).

So to access the localStorage you can use untyped to quickly get access to a global variable, I then decided to wrap this little hack in a Model class to make it a little neater:

[codesyntax lang="actionscript3" lines="normal"]
package models;
import js.Lib;

/**
* ...
* @author MikeC
*/

class ChromeLocalStorageModel extends BaseModel
{

public function get(key:String) : Dynamic
{
var val = untyped localStorage[key];
trace('Getting from localStorage: '+key+" :: "+val);
return val;
}

public function set(key:String, val:Dynamic) : Void
{
trace('Saving in localStorage: '+key+" :: "+val);
untyped localStorage[key] = val;
}

}

[/codesyntax]

This lets you just just mix and match the type-safe stuff when you need to and just do a little "hack" when you need to ;)

The above example also shows off another cool feature im using in Post To Tumblr, which is RobotLegs. Thanks to the fact that the RobotHaxe library is written in pure Haxe (has no platform specific bits) that means I am able to use it on a Javascript project.

The only problem is the issue with Views and Mediation. Because unlike Flash events don't bubble up to a central source there is no way to do automatic mediation in the JS target. Instead what you do is implement "IViewContainer" on your context view, then whenever a child is added or removed you call viewAdded() or viewRemoved() that way the MediatorMap can try to make a mediator for that view.

Im not sure if the way I have used RobotLegs is the correct or best way, it was more of an experiment as I went along. The way I have done it is to wrap many of the main HTML elements in my own view classes. So for example I have a "DivView" that represents a "div" and extends BaseView:

[codesyntax lang="actionscript3" lines="normal"]
class DivView extends BaseView
{

public function new(elementId:String=null)
{
super(Lib.document.createElement('div'));
if (elementId != null) element.id = elementId;
}

}

[/codesyntax]

BaseView implements the IViewContainer interface:

[codesyntax lang="actionscript3" lines="normal"]
class BaseView implements IViewContainer
{
public var viewAdded:Dynamic -> Void;
public var viewRemoved:Dynamic -> Void;

public var element : HtmlDom;
public var parent : BaseView;
public var children : Array;

....

public function new(element:HtmlDom)
{
this.element = element;
this.children = [];
isLayoutInvalid = true;
}

...

public function add(child:BaseView) : BaseView
{
children.push(child);
child.parent = this;
child.viewAdded = viewAdded;
child.viewRemoved = viewRemoved;
if(viewAdded!=null) child.addChildren();
element.appendChild(child.element);
if (viewAdded != null) viewAdded(child);
return child;
}

public function remove(child:BaseView) : Void
{
if (viewRemoved != null) child.removeChildren();
children.remove(child);
child.parent = null;
child.viewAdded = null;
child.viewRemoved = null;
element.removeChild(child.element);
if (viewRemoved != null) viewRemoved(child);
}

...

}

[/codesyntax]

Then say I want to construct the following html:

[codesyntax lang="html4strict"]
<div id="container">
<div id="inner">Hello World!</div>
</div>

[/codesyntax]

I would do something like this:

[codesyntax lang="actionscript3" lines="normal"]
class MainPopupContainer extends DivView
{
private var inner : DivView;

public function new()
{
super("container");

inner = new DivView("inner");
inner.element.innerHTML = "Hello World!";
add(inner);
}
}

[/codesyntax]

Then perhaps I want to turn the "Hello World!" red when clicked I would do something like this:

[codesyntax lang="actionscript3" lines="normal"]
class MainPopupContainer extends DivView
{
private var inner : DivView;

public function new()
{
super("container");

inner = new DivView("inner");
inner.element.innerHTML = "Hello World!";
add(inner);

new JQuery(inner.element).click(onInnerClicked);
}

private function onInnerClicked()
{
inner.element.style.color = "#FF0000";
}
}

[/codesyntax]

What this means is you have a RobotLegs-familiar looking View with a Mediator behind it (thanks to the mediation happening when you call add()) which is nice. What it does mean however is I have quite abit of boiler plate wrapping the HTML nodes, which definitely slowed down my development.

Another thing im not sure about is my mixing of in-line styles and stylesheets. Sometimes I would use the styles in my css and other times I would just set them on the element directly. To be honest, because I was using classes and inheritance and all that good stuff I usually found it easier and more expedient to set the styles inline in my View class rather than go digging through several hundred lines of css to find the selector I was looking for

For example I may have a "HeaderOptionButton" that defines some inline styles then whenever I wanted a button that looked and acted like a header button I would just make and add a HeaderOptionButton. I know im probably going to get flamed to hell and back for that!

As I said, im not sure if im doing it the "right" or "best" way, its just the way that seemed to work at the time ;)

Well that's a quick overview of where im at. Once I have cleaned the project up a little and added some missing features ill be sticking the source up on GitHub for anyone interested.

Saturday, 26 November 2011

Hxaria, Infinite Terrain [HaXe, WebGL,dat.GUI]



So I have been working on my "Terraria like Terrain" project "Hxaria" again.

Following on from the last post, I have now made it so that each particle can have its texture changed. This completes the functionality required to render each tile as a point sprite, as talked about in my previous post.

The way it works is that the entire world is recorded in a 2x2 array Tilemap. This 2x2 array holds a single Tile object for every single tile in the world:

[codesyntax lang="actionscript3" lines="normal"]
class Tile
{
public var x : Int;
public var y : Int;
public var type : Int;

public function new(x:Int, y:Int, type:Int) { this.x = x; this.y = y; this.type = type; }
}

[/codesyntax]

 

When the TileRenderer needs to render it asks this Tilemap for a Tile that represents that screen coordinate, the Tilemap then offsets the position due to the camera movement and returns a tile. So it looks something like:



The tile type is then passed to the shader in attribute buffers per point sprite / tile along with all the tiles which are stored on a single texture:



The shader then performs the neccessary calculations to work out what the UV coordinate in the texture. The Vertex Shader:

[codesyntax lang="glsl" lines="normal"]
uniform float amplitude;
uniform float tileSize;
uniform float texTilesWide;
uniform float texTilesHigh;
uniform float invTexTilesWide;
uniform float invTexTilesHigh;

attribute float size;
attribute vec3 customColor;
attribute float tileType;

varying vec3 vColor;
varying vec2 vTilePos;

void main()
{
vColor = customColor;

float t = floor(tileType/texTilesWide);
vTilePos = vec2(tileType-(t*texTilesWide), t); // +(.5/tileSize)

gl_PointSize = size;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}

[/codesyntax]

 

And the Fragment Shader:

[codesyntax lang="glsl" lines="normal"]
uniform vec3 color;
uniform sampler2D texture;
uniform float invTexTilesWide;
uniform float invTexTilesHigh;

varying vec3 vColor;
varying vec2 vTilePos;

void main()
{
vec2 uv = vec2( gl_PointCoord.x*invTexTilesWide + invTexTilesWide*vTilePos.x, gl_PointCoord.y*invTexTilesHigh + invTexTilesHigh*vTilePos.y);

gl_FragColor = texture2D( texture, uv );
}

[/codesyntax]

So it works in a way very much like a raster engine. You only have to render as many particles as the screen can contain.

If the screen area moves beyond the extent of the Tilemap then more tiles are randomly generated:



The new tiles are randomly selected from 4 different types, Dirt, Gold, Diamonds and Rock. I have added some controls to the demo that allow you to tweak these values to demonstrate the random tile generation:



The UI may look familiar to people that have seen any experiments anyone who has worked with Three.js before, its the very popular dat.GUI. Its a really simple library written in javascript for creating controls that can be used to tweak experiments, perfect for me!

To get dat.GUI to work with haxe, I used the awesome Extern feature of HaXe. This means that all I have to do is provide a stub interface to dat.GUI rather than a full implementation in haXe. This is great as it allows me to rapidly begin to use the library but also have the type safety of HaXe. It didnt take long to stub out the bits of the library I needed in an extern:

[codesyntax lang="actionscript3" lines="normal"]
package dat;

/**
* ...
* @author Mike Cann
*/

extern class GUI
{

public function new(options:Dynamic) : Void;
public function add(options:Dynamic, name:String) : GUI;
public function name(value:String) : GUI;
public function min(value:Float) : GUI;
public function max(value:Float) : GUI;
public function step(value:Float) : GUI;
public function onFinishChange(f:Void -> Void) : GUI;
public function listen() : GUI;
}

[/codesyntax]

Then I used it like:

[codesyntax lang="actionscript3"]
package ;
import dat.GUI;

/**
* ...
* @author
*/

class GUIManager
{
public var goldChance : Float;
public var rockChance : Float;
public var diamondsChance : Float;
public var mapWidth : Int;
public var mapHeight : Int;

private var gui : GUI;
private var game : Game;

public function new(game:Game)
{
this.game = game;

gui = new GUI( { height : 5 * 32 - 1 } );

goldChance = game.tilemap.goldSpawnChance;
rockChance = game.tilemap.rockSpawnChance;
diamondsChance = game.tilemap.diamondsSpawnChance;
game.tilemap.mapResized = onTilemapResized;
mapWidth = 0;
mapHeight = 0;

gui.add(this, 'goldChance').name("Gold").min(0).max(1).step(0.001).onFinishChange(function() { game.tilemap.goldSpawnChance = goldChance; } );
gui.add(this, 'rockChance').name("Rock").min(0).max(1).step(0.001).onFinishChange(function() { game.tilemap.rockSpawnChance = rockChance; } );
gui.add(this, 'diamondsChance').name("Diamond").min(0).max(1).step(0.001).onFinishChange(function() { game.tilemap.diamondsSpawnChance = diamondsChance; } );
gui.add(this, 'mapWidth').listen();
gui.add(this, 'mapHeight').listen();
}

private function onTilemapResized(mapW:Int, mapH:Int):Void
{
mapWidth = mapW;
mapHeight = mapH;
}
}

[/codesyntax]

Simples!

Anyways you can check the final result out on this page: http://mikecann.co.uk/projects/hxaria/02/
(Click and drag to move the camera about)

I have also uploaded a quick video too:



I have also uploaded the source again to my github page: https://github.com/mikecann/Hxaria
(I have also created a tag, incase the source changes in the future)

Next up, lighting!

Friday, 21 October 2011

Why Developing for WebGL Sucks!



For some time now I have been working with WebGL and have developed a sort of love/hate relationship with it. I love the ability to instantly target millions of people with GPU accelerated code without any plugins or barriers (excluding the targets that dont support it). However as a developer, writing code that takes advantage of WebGL kinda sucks.

Procedural Based


First off is the way you have to structure your GL calls. For example take a look at the following generic bit of webGL harvested from the net:

[codesyntax lang="javascript" lines="normal"]
texture = gl.createTexture();
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 64, 64, 0,
gl.RGB, gl.FLOAT, new Float32Array(pix));
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);

texture1 = gl.createTexture();
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 64, 64, 0,
gl.RGB, gl.FLOAT, new Float32Array(pix1));
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);

FBO = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, FBO);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D, texture, 0);
FBO1 = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, FBO1);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D, texture1, 0);
if( gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE)
alert(err + "FLOAT as the color attachment to an FBO");

[/codesyntax]

All it does is create a couple of textures, setting their starting values and creates two frame buffers for rendering to. Its just it looks complicated and difficult to understand.

GL works on a procedural basis, so you tell GL that you are about to work on something by calling a function like "bindTexture()" then on the next line you perform an operation on it such as "pixelStorei()". Now this may have made perfect sense back when we were writing everything in C which is procedural anyway however this is Javascript (or haXe in my case) which is an Object based language, code like this is difficult to understand and follow.

The procedural nature of WebGL means you have to be much more careful about unsetting things you have previously set. For example if you bind a texture to perform some operation, you must then remember to unbind it else you could inadvertently cause operations to be applied to it on subsequent calls elsewhere in your codebase. It this 'hidden state' that has caused me alot of headaches when developing my samples.

The principal behind WebGL was to provide a very low-level library which other developers can build upon to build more complex and abstracted libraries. And there are numerous libraries out there. I personally have tried several of them including the very popular three.js. Three.js is great for doing common things like loading models and putting quads on the screen. I however encountered a problem with render targets which I struggled with for days before I discovered that you had to set "needsUpdate" to true on your texture before using it. In the end I decided to drop three.js beacuse of another issue I encountered and instead attempt to reduce my complications by working with webGL directly.

Flash11's Stage3D has the same philosophy as webGL, to provide a low level API for other developers to build libraries upon. The thing is Flash11's low-level API makes more sense and is more readable. For example the following to me is much more readable than its webGL equivalent:

[codesyntax lang="actionscript3" lines="normal"]
texture = c.createTexture(logo.width, logo.height, Context3DTextureFormat.BGRA, false);
texture.uploadFromBitmapData(logo);

[/codesyntax]

The Stage3D API also uses language like "upload" to let you know when you are transferring data to the GPU, for a new comer to GL you have no clue when things are going to the GPU. Its small things like this that reduce the "WTF?" factor when tackling the tricky world of hardware-accelerated 3D programming.

Cross-domain textures


This one cropped up around July time this year and took me ages to work out what was going on. For some inexplicable reason (or so it seemed) my code one day stopped working. When I looked for demo code online it all worked fine, however when I downloaded it and run it locally it also didnt work. I was getting errors like the following:

Uncaught Error: SECURITY_ERR: DOM Exception 18
Uncaught Error: SECURITY_ERR: DOM Exception 18
Uncaught Error: SECURITY_ERR: DOM Exception 18
Uncaught Error: SECURITY_ERR: DOM Exception 18
Uncaught Error: SECURITY_ERR: DOM Exception 18 

I was so baffled that I posted about it on the HaXe mailing list asking for help, thinking it was something I was doing wrong with HaXe. It turns out (after much wall-head-butting) this was a change that they brought into Chrome 13 and Firefox 5 to combat a security problem when using shaders that use textures from a different domain to the one running the code:

http://blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html

Now I have no problem with cross-domain issues, im used to this from Flash where we have the same sort of setPixel() restrictions on cross-domain BitmapData's. The thing is, it appears that this restriction applies when running code locally too. So If you are developing something on your local machine and trying to access a texture from disk it throws the same security errors because the browser thinks you are reaching across domains to access the image.

At the time the only way to get around this was to create your own webserver that you run on localhost to server up the files. So to do that I had to download python so I could run a simple localhost commandline webserver from my bin directory. What an effort! There may be easier ways these days to solve it but at the time it really frustrated me and formed yet another barrier to developing webGL.

No Error Messages


This is by far the most annoying thing about developing for WebGL. So many times I have been trying to write something that I know SHOULD work but for some reason it doesn't. I dont get any error messages, nothing. It makes writing something from scratch neigh on impossible.

In my last post "GPU State Preserving Particle Systems with WebGL & HaXe" I started with an idea. I attempted to code it 'bottom-up'. That is start with nothing and then add more code until I reached what I wanted. Unfortunately having no error messages in WebGL makes this very difficult indeed. I would spend some time writing something really simple, like trying to get a textured quad to render on the screen only to find I get nothing. I double check my camera matrices my vertex and texture buffers, my shader and still nothing. Eventually I found that I hadn't bound something first before trying to operate on it *sigh*

In the end I found the best way to get anywhere is to go from the other direction, a 'top-down' method. Start with something kind of simmilar to what you want then cut bits out one line at a time until you get what you want. Its extremely time consuming and frustrating, but its less frustrating than going from the other way.



There are tools out there that help with debugging what is going wrong. Namely the WebGL Inspector (see above) is intended to provide gDEBugger / PIX like debugging information about what is going on inside webGL. Its a clever bit of tech, it lets you inspect buffers and traces each gl call, however it suffers from the same underlying problem of having no errors. You setup a buffer incorrectly and what you get is "INVALID_VALUE". No indication as to which of the values is invalid or what part of the call you messed up on :(

Googling Doesn't Help


If you do happen to get an error message (unlikely) or you word your problem in a sufficiently succinct and googaleble way you will then run into the next big problem with WebGL; theres very few people using it. Now I know I am likely to be flamed for that comment, but it just seems that way to me. Whenever I tried to google my problem, or google for what I was trying to achieve (because working bottom-up doesnt work) there would be a very sparse smattering of relevant posts. Usually the results are forum posts and are OpenGL not WebGL related and are from 5-10 years ago.

But..


Now having just ranted on for several hundred words about why it sucks im going to finish it off by saying that im going to continue to develop for WebGL using haXe regardless. Why? Well I just like making pretty things that run fast and GPGPU programming appeals to me for some unknown (likely sadistic) reason.

Thursday, 20 October 2011

GPU State Preserving Particle Systems with WebGL & HaXe



Well this is the post I didnt think was going to happen. I have been struggling for weeks with this little bit of tech, ill explain more about why it has been so difficult in another post. For now however, ill just talk about this sample.

So the idea was to build upon what I had been working with previously with my stateless particles systems with WebGL and HaXe. The intention from the start was to replicate some of my very early work (from 2007) on state preserving particle systems in WebGL.

Before I go any further, you can check it out in action here:
http://mikecann.co.uk/projects/HaxeWebGLParticles/ 

First a quick reminder. The difference between a stateless and state-preserving particle simulation is that in the latter we store and update the positions, velocities and other properties of each particle per frame, allowing us to interact and control the simulation. This differs from the stateless particle simulation (detailed in my previous post), where the position for each particle is calculated each frame based on a fixed algorithm.

A fairly reccent addition to WebGL made this possible, namely texture lookups in the vertex shader (aka Vertex Texture Fetch). I wont go over the exact details how this makes state preserving particle systems possible as I have already documented it in my earlier work. A brief explanation is that it allows you to use the fragment shader to perform the updates on particle state stored in textures then use the vertex shader to map those states to a point-sprite vertex buffer.

Basically what this means is that the entire particle simulation can be contained and updated on the GPU, which means no read-back. This allows us to achieve simulations of millions of particles without too much difficulty (depending on GPU ofcourse).

I have uploaded the source for people to perouse at their leisure:
https://github.com/mikecann/HaxeWebGLParticles

As usual it was written using the JS target of HaXe so it should be fairly easy to understand whats going on if you have written any Ecma-script-like-language. Im going to detail this in my next post, but the code isnt the best I have ever written as its a result of a mish-mash of various samples and examples I have found on the web. If anyone has any comments on things that are wrong or could be done better I would be very happy to hear about them.

Sunday, 10 July 2011

More HTML5 & HaXe Speed Tests



Ive spent a little more time this weekend looking at some more  HTML5 with HaXe. Following on from my previous experiments with WebGL I decided to give HTML5's Canvas a a look as it was supposed to be designed specifically for the purpose of doing 2D.

I had heard from the HaXe mailing list that the Jeash project was a common way of interacting with the canvas in HaXe. Jeash is a remapping of the Flash API into JS so in effect I should beable to take any of my usual flash code, Sprite's,  BitmapData's, etc and it should run on the canvas no problems. Nice!

So I coded up a quick blitting example to see what sort of performance I would get:

http://mikecann.co.uk/projects/HTML5SpeedTests/HaXeJeash/bin/

The results were okay (I get about 11FPS with 5,000 crawlers) however I was interested to know what sort of cost HaXe adds. So I decided to code up a second example, this time using pure JS:

http://mikecann.co.uk/projects/HTML5SpeedTests/JSCanvas/

The results this time were better (14FPS with 5,000 crawlers) so I now wondered what happens if I do without Jeash and just code up the example using pure HaXe. I was expecting to see the same sort of performance hit as Jeash:

http://mikecann.co.uk/projects/HTML5SpeedTests/HaXeCanvas/bin/

Surprisingly it actually runs faster (17FPS with 5,000 crawlers) ! This is quite a surprise and totally contradicts my notion that going from HaXe -> JS would incur a cost. I was expecting some cost, but a performance increase?! I can only speculate that behind the scenes the JS engine in the browser is able to JIT compile the HaXe JS much better than the hand-crafted JS and hence more speed.

If you are interested in the source then I have uploaded it here: http://mikecann.co.uk/projects/HTML5SpeedTests/HTML5SpeedTests_1.zip

P.S. All the test were run on Windows 7 x64 in Chrome 14 (dev)