Sunday, November 29, 2009

Processing.js – strokeCap()

strokeCap()
Another week or two, and a bit of work toward the 0.3 release of my DPS909 project. This time it was strokeCap()'s turn to be ported to Processing.js (Pjs).
So here is the basic Processing example working in Pjs:


And here is the example running in the Processing Development Environment (PDE):

Squishy Innards
This is all done by setting canvas' lineCap attribute. lineCap has three possible values which correspond directly to those used by Processing so strokeCap()'s code looks just like this:
p.strokeCap = function strokeCap( set ){
if ( set == p.ROUND ) {
curContext.lineCap = 'round';
} else if ( set == p.SQUARE ) {
curContext.lineCap = 'butt';
} else if ( set == p.PROJECT ) {
curContext.lineCap = 'square';
}
};

lineCap is also handled by canvas' state saving functions, which means Pjs' pushStyle() and popStyle() can already handle saving and restoring the setting as well.

A Different Starting Point
The main difference between canvas and Processing/Pjs is the default setting for lineCap. Canvas' default is “butt", which is “SQUARE" in Processing. Processing needs to default to “ROUND", which is “round" in canvas.

There was a bit of trouble getting the default working in Pjs. At first adding curContext.lineCap = 'round'; to function init didn't work. Al MacDonald (F1LT3R) was very quickly able to find where the problem was and fix it: it turns out function size recreated the canvas context every time it was called, which in turn reset all the attributes. Thanks, Al!

So now the default setting works very nicely in Pjs:


Compare to the same thing in PDE:

Useful Links

Thursday, November 26, 2009

Firefox Addon and XPCOM

So last week in DPS909 we were supposed to feel our way through a lab giving some idea how Mozilla's XPCOM works. XPCOM is used to ensure code portability. I do not pretend to understand how it all works, it's rather complicated and terrifying for a newbie, but at the very least I can follow instructions.

The big first step is to create an XPCOM interface using a XPIDL file, which includes function prototypes using familiar C/C++ data types (at least in the walkthrough, XPCOM may be used with other languages to). A header file is automatically generated which, amongst other things, transforms the data types into Mozilla's data types and creates a stub class using the header. In other words, a lot of the basic set up work is done for the code cruncher (winner!)

Most of the walkthrough was pretty straight forward. There were a few minor things that needed to be changed or were different. In install.rdf, I changed em:minVersion and em:maxVersion to 3.5.5 and 3.7a1pre respectively (that allowed the extension to work in the trunk build.) Also, IFirstXpcom,h was created in $(objdir)/dist/include/ rather than $(objdir)/dist/include/firstxpcom/.

But everything worked out and so I can now claim to have created (after near slavishly following somebody else's instructions) an add-on for Firefox.


Friday, November 20, 2009

Processing.js – Something Lost/Gained in the Translation

The nice thing about porting is the end result is already known. Comparing the effects of the original with the effects of the transcription is a good indicator of how close you are and whether or not you're on the right track.

Simple, yes?

Sure, at least in a perfect world where I could have my kitchen faucet yield hot chocolate and have my computer magically upgrade itself to the latest hardware and software. Alas, a perfect, honest-to-the-source, zero deviation transcription may not always be possible; such is what I have discovered while tinkering with pushStyle() popStyle() and boolean().

Below you will find I have not embedded the Pjs examples, instead I shall provide a link to another web page with the example on it. This is because embedding requires minification, and I'd rather not go through the frustration of minifying some of the larger examples. I'll provide screenshots of how the examples look using the Processing Development Environment (PDE) for comparison.

Differences in pushStyle() and popStyle()
The basic Processing reference example looks like this

and can now be reproduced in Pjs (Pjs demo here.)

But take a Pjs demo like this one. See the extra pops at the bottom? You can't do that in Processing. The PDE won't allow the Pjs example code to run; it'll see the extra pops, throw an exception, and refuse to run properly until the extra pops are removed. The closest approximation to the Pjs example Processing will allow looks something like this:

Pjs doesn't really concern itself with catching logical errors in the code. At best it just concerns itself with syntactic errors, and if there are any it simply doesn't paint anything onto the canvas. Saying that, the Pjs version of popStyle() has to be a bit more lax than its Processing counterpart and work with, rather than crash on, extra pop calls.

In this matter the solution is simple. Upon figuring out the pop call is extraneous, Pjs effectively ignores it and carries on. It must be one of the few times burying one's head in the sand actually makes the problem go away!
Differences in boolean()
Moving onto boolean(). Let's start out with showing a basic example based on the one found on the Processing website. It looks like this:


and it too may be reproduced in Pjs (Pjs demo here.) However, boolean() is afar more complicated beast than the basic example would imply. In this case it's a matter of how Java/Processing is very strict on the number and nature of arguments passed to a method, while JavaScript/Pjs is not.

Take for example the following this Pjs demo. Note how we're passing in doubles, booleans, ints, nulls, undefines, etc., and arrays with mysteriously empty elements. If you were to try the code in Processing it wouldn't work. For one, Processing's boolean() refuses to handle boolean variables, or double variables, or nulls, and other fancy things like that. In fact, the closest Processing example to the Pjs demo is rather more sparse and looks like this:


(Un)fortunately, Pjs' boolean() can't take the easy way out and throw away arguments it doesn't like, coughing up an exception, and making the whole show grind to a halt. Being JavaScript it's syntactically correct to pass a cornucopia of dynamically typed arguments into a function. Pjs' boolean() has to handle whatever comes its way gracefully.

As you can tell from the Pjs boolean() demo, I thought this was best done by having the function return "meaningful" results from arguments not normally handled by Processing's boolean(). Numeric arguments are handled like integers: zero values return false, non-zero values return true. Boolean arguments are just returned as themselves. Nulls and undefines return false.

Heresy!
I like to think I've cobbled together an acceptable compromise between how Pjs and Processing behave. I guess I'll find out soon whether this is acceptable or not when I try to push the code into the library.

Thursday, November 19, 2009

DPS909 Project – Processing.js – v0.2

Returning to Ground Zero
First, a self-plagiarized recap. This semester at Seneca College I am taking a course revolving around open source development. As part of the course the students (yours truly being no exception) were nudged into getting involved in some Mozilla related projects, produce code for the real world, and see fist hand how the whole open source thing works.

I chose to work on Processing.js (Pjs), a JavaScript port of the Java-based Processing. More specifically, I volunteered to work on porting over the functions pushStyle(), popStyle(), and boolean().

On 19 October 2009, I threw release 0.1 out into the cruel world to fend for itself. Today I present release 0.2 to the world. Applause!

Not new, but shinier!
The watchwords for release 0.2 were: fix it. Release 0.1 included reasonably functional code for pushStyle() and popStyle(), and totally untested and untried code for boolean().

Bringing boolean() up-to-spec was the goal of this release and this was done by throwing together some test cases for boolean(). Bugs were indeed caught, squashed, and flushed down the toilet.

Although boolean() got most of the attention, the elder siblings did not totally escape notice. pushStyle() and popStyle() received their own test cases too. One issue was whether the pop should spit out alert popups if there were not enough pushes. I decided not to use any popups and just have a warning be sent to the console, where most users probably won't notice. pushStyle() and popStyle() were further improved to better handle the library's own variables; before they only managed canvas' variables with any proficiency.

Better to get it when it's pleasantly warm rather than skin-charring hot

What now?
Pursuant to getting my code merged into the Pjs library there are a few instructions I have to follow. So I'll make another post comparing the results of my Pjs code with those of the Java-based Processing code. As I have discovered it is not totally possible to faithfully port Processing to JavaScript. For example, Processing will throw exceptions and refuse to do anything if you try to pass an argument to a function and the function is not designed to accept, say, the variable type of the argument. But in Pjs you have to handle these weird arguments and preferably return some meaningful result. This comes up a few times in boolean(). But more on that soon.

For release 0.3, it looks like I'll have to choose another function to port over, or at least get started on even if I don't finish by the end of the semester. strokeCap() looks appropriately involving.

Saturday, November 7, 2009

Learning a Bit of JavaScript

This week in DPS909 we talked a bit about JavaScript. This was particularly relevant to my project this semester, implementing a few functions in the Processing.js JavaScript library. As part of this week's journey of the mind, we were directed to watch a lecture by Douglas Crockford called "JavaScript: The Good Parts". Leaping over to Wikipedia for some familiarization, Crockford is the senior JavaScript Architect at Yahoo!, and wrote the specification for JavaScript Object Notation. The lecture in the video is based off his book of the same name.

Right off the bat, I'm one of those people who, as Crockford' puts it, started tinkering with JavaScript without learning it. So given my novice credentials coupled with a pressing need to "learn more" I'm pleased that the lecture had a few "do and don't" pointers that someone like me could take away.

The first big thing I learned was use ===, avoid ==. I was first exposed to === by David Humphrey, who gave me a code snippet demonstrating how to detect if a JavaScript variable was an array. A bit of research revealed === compares not only the value of two variables but their types as well, a very useful feature in a language with dynamic typing. I was, not, however, inclined to use === near exclusively.

After watching Crockford's lecture made me realize using mainly == would eventually cause grief.. Sooner or later I would make compare two values, forget the variable types, or forget the distinction between null and undefined, and end up with an annoying, very small, difficult to track down, bug. Using === would be an easy way to save a bit of heartache in the future, which is always a good thing.

Learning the distinction between null and undefined was an ancillary to the first major thing I picked up. The former is a value for an object variable, the latter can be had if trying to retrieve a variable an object doesn't have. Note to self: further research required.

The second, and most surprising, thing I learned was coding style matters. It's easy to mistake JavaScript for a free-wheeling language: dynamic typing, you don't have to use semi-colons half the time! But apparently something as "simple" as bracket placement when defining blocks can really mess things up. Crockford gave the following example:

return
{
ok: false
};

This seems innocent enough, but apparently behind-the-scenes shenanigans means it actually is interpreted like so:

return;
{
ok: false;
}

In other words, everything after return goes nowhere and does nothing. For this to work as intended the opening bracket must be placed to the right of return like so:

return {
ok: false
};

While my coding style generally resembles the "correct" example, this will be a useful tidbit when deciphering the code of other programmers.

Fortunately, it seems Crockford has developed JavaScript code quality checker called JSLint to help developers catch some of their more egregious code. Methinks I shall be availing myself of it in the near future.