Monday, September 27, 2010

Moving images in JavaScript

So now that I have a drawing program and can save drawings, I am ready for the next step. I want to be able to place an icon on the grid and be able to move it around, treating the lines drawn as walls. This next app is a little simpler though and will just move icons around. I will leave it for a future app to combine the two.

My first step was to get an icon. I have no artistic skill, so I downloaded icons. To make sure I don't step on anyone's licensed toes I grabbed images from commons.wikimedia.org.

Next was to create the HTML. The HTML looks very similar to the drawing program, except that I have an icon layer rather than a drawing layer. Also, I don't need to show any control information, so I am did away with the control layer.
<div id='windowContainer'> 
  <canvas id="gridLayer" class="gridLayer" height="500" width="800"></canvas>
  <canvas id="iconLayer" class="gridLayer" height="500" width="800"></canvas>
</div> 
Next I created some helper classes. I have an Icon class which holds the image, the location of the icon, knows how to move the icon, and how to draw the icon. I have an IconLayer class which keeps track of all of the icons and is responsible for drawing/clearing the icon layer as a whole. I have a IconControl class which is responsible for tracking mouse clicks and calling the move methods on the appropriate icon at the appropriate time. I also reused the Grid class and Geometry classes from before.
function Icon(img, iconLayer, gridPt) { /* code */ }
Icon.prototype.draw = function() { /* code */ }
Icon.prototype.setGridPoint = function(point) { /* code */ }
Icon.prototype.moveTo = function(point) { /* code */ }

function IconLayer(canvas, grid) { /* code */ }
IconLayer.prototype.draw = function() { /* code */ }
IconLayer.prototype.addIcon = function(img, gridPoint) { /* code */ }
IconLayer.prototype.findIcon = function(point){ /* code */ }

function IconControls(iconLayer) { /* code */ }
IconControls.prototype.click = function(x, y) { /* code */ }
I want the movement of the icons to be visible to the user which means that I can't just draw them at their destination. So, to move an icon, I'll erase it, draw it slightly closer to the new locations, and then wait a little bit and repeat the process. However, if I have two icons moving, I don't want to be redrawing twice as often. My solution to this is to have each icon, when it is moving, to just update its own location, but not to redraw. The IconLayer will periodically redraw itself with the icons in their new location. To keep from redrawing repeatedly when no icons are moving, the IconLayer will only redraw as long as at least one Icon is moving.

I was concerned about threading issues, but it appears that while JavaScript is asynchronous, it is actually single threaded. This means I shouldn't have to worry about race conditions. Of course if a function goes into an infinite loop, it does mean nothing else will run. Anyway, here are the methods for moving an icon.
  1 Icon.prototype.movePerUnit = 5; 
  2 Icon.prototype.delayPerMove = 50; 
  3 Icon.prototype.moveTo = function(point){ 
  4   this.moveQueue.push({gridPoint:point, realPoint:this.grid.getReal(point)});
  5   if (!this.moving) {
  6     this.moving = true;
  7     this.iconLayer.incrMovingIcon(); 
  8     this.moveImpl(); 
  9   } 
 10 } 
 11 Icon.prototype.moveImpl = function(){ 
 12   var move = this.nextMove();
 13   if (!move) { 
 14     this.moving = false;
 15     this.iconLayer.decrMovingIcon(); 
 16   } else { 
 17     this.realPoint.x += move.dx; 
 18     this.realPoint.y += move.dy; 
 19     if (--move.steps < 1) { 
 20       this.realPoint = move.realPoint; 
 21       this.gridPoint = move.gridPoint; 
 22     } 
 23     setTimeout(this.moveFunc, this.delayPerMove);
 24   } 
 25 } 
 26 Icon.prototype.nextMove = function(){ 
 27   var move = this.moveQueue.peek();
 28   while (move != null && this.gridPoint.eq(move.gridPoint)) {
 29     this.moveQueue.pop(); 
 30     move = this.moveQueue.peek(); 
 31   } 
 32   if (move && !move.steps) { 
 33     move.steps = move.gridPoint.dis(this.gridPoint) * this.movePerUnit;
 34     move.dx = (move.realPoint.x - this.realPoint.x) / move.steps; 
 35     move.dy = (move.realPoint.y - this.realPoint.y) / move.steps; 
 36   } 
 37   return move; 
 38 }
The moveTo method (lines 3-10) pushes the new move onto the moveQueue and then starts the move, if necessary. moveToImpl method does the real action of making a move. Lines 14-15 handles ending a move. Lines 17-18 actually make the move. Lines 20 and 21 make sure that we end on the right spot and gets rid of rounding errors that might've happend along the way. Lines 23 makes sure that the moveImpl function which will get called repeatedly. nextMove calculates the next move.  The loop on lines 28-31 finds the next move in the queue that isn't the current location. Lines 33-35 calculate how the move will be made, if that hasn't already been done for this move object.

The function this.moveFunc that is referenced on line 23 is defined in the Icon constructor as
var self = this;
this.moveFunc = function() {self.moveImpl();};
This is done so that we will have access to the appropriate this value when moveImpl is called by the setTimeout function. IconLayer's methods incrMovingIcon and decrMovingIcon called on lines 7 and 15 tell the IconLayer to start or stop drawing, if needed. These methods look like:
  1 IconLayer.prototype.refreshTimeout = 25;
  2 IconLayer.prototype.incrMovingIcon = function(){
  3   if (this.movingIconCt == 0) {
  4     this.drawTimer = setInterval(this.drawFunc, this.refreshTimeout);
  5   } 
  6   this.movingIconCt++; 
  7 } 
  8 IconLayer.prototype.decrMovingIcon = function(){
  9   this.movingIconCt--; 
 10   if (this.movingIconCt == 0) {
 11     clearInterval(this.drawTimer); 
 12     this.draw(); 
 13   } 
 14 }
drawFunc (on line 4) is similar to moveFunc up above and is set in the constructor and refers to draw. draw just clears the IconLayer and then draws all of the Icons in their current location.  These methods scream "race-condition" to me, but as I stated above, JavaScript is actually run single-threaded, so this isn't an issue.


Well, that was the meat of the code.  The only other interesting thing was the loading of the images. I originally just added the icons right away in the script, like:
  1 var names = ["smile", "frown", "kiss", "cool"];
  2 for (var i = 0; i < names.length; i++) {
  3   var img = document.getElementById(names[i] + "_icon");
  4   iconLayer.addIcon(img, {x: i*2, y:0});
  5 } 
  6 iconLayer.draw(); // ERROR! - doesn't work.
and this caused errors because JavasScript would try drawing the image to the canvas before the browser had actually downloaded the whole image. Oops. I had to use the image.onload method to add the images after they were loaded. However, I really wanted to run after the last image was loaded. The code to do that is below. I add each icon as they are loaded, and keep a count. I don't call draw until the last one is loaded. Note that I actually add a property to the image object so that I will have access to it inside the onload method. And since onload is a property of the image, these parameters are accessible via the this variable inside the onload function, which is still kind of odd to my C++/Java/C# brain, but I am getting used to it.
  1 var names = ["smile", "frown", "kiss", "cool"];
  2 var loaded = 0;
  3 for (var i = 0; i < names.length; i++) {
  4   var img = document.getElementById(names[i] + "_icon");
  5   img.my_x = 2*i; 
  6   img.onload = function() { 
  7     iconLayer.addIcon(this, {x: this.my_x, y:0});
  8     loaded++; 
  9     if (loaded == names.length) { 
 10       iconLayer.draw(); 
 11     } 
 12   } 
 13 }
Demo

Anyway, here's the demo.  Click on one of the icons.  Click a destination.  Lather, rinse, repeat.

Monday, September 20, 2010

Javascript Prototype Inheritance

A common desire when coding in an OO way is to create a class that inherits from another class. So how do you do this in Javascript? You can find various links on the web about how you can do this. However, just because “you can program FORTRAN in any language," doesn't mean that I want to program Java in Javascript. So, to me, learning Javascript means learning the Javascript way of doing things. It turns out that asking about inheritance in Javascript is the wrong question and you shouldn't want that, at least not exactly.

Prototype
Every object in Javascript has a prototype property. This prototype object is specified at the Function level. Whenever you try to look up a property on an object (and remember, object methods are really just properties), if the object doesn't have the specified property, it will try to look it up on the prototype property. Let's say we have a class defined as such:
function Car() { 
} 
Car.prototype.wheels = 4; 
Car.prototype.drive = function() { /* do something */ }
And code that looks like:
var car = new Car(); 
var wheelCt = car.wheels;
As you would expect, wheelCt = 4. Here's how it got its value:
  1. look at car.wheels - the car object has no property called "wheels"
  2. get the property car.prototype which is the Car.prototype object
  3. look at the wheels property of this object, which is 4.
So now I want to create a Sedan object. I would like it to "inherit" the properties from Car. The way to do that is to instantiate a Car object and use this object as the Sedan prototype.
  1 Sedan.prototype = new Car() 
  2 Sedan.prototype.constructor = Sedan 
  3 function Sedan(color) { 
  4   this.color = color; 
  5 } 
  6 Sedan.prototype.doors = 4; 
  7  
  8 var newCar = new Sedan();
  9 var newWheelCt = newCar.wheels;
As you would expect, newWheelCt = 4.  Here's how it got its value:
  1. look at newCar.wheels - the sedan object has no property called "wheels"
  2. get the property newCar.prototype (call it sedanProto) which is the Car object we created on line 1
  3. look at the wheels property of sedanProto - it has no property called "wheels"
  4. Get the property sedanProto.protototype which is the Car.prototype object
  5. look at the wheels property of this object, which is 4.
We can, of course create further types and assign their prototypes to Sedan to increase this hierarchy as much as we want.

Oh, in case your curious about the line 2 - each prototype object has a constructor property which is the Function that it is associated with.  The can be used to determine what "type" an object is at runtime.  If we don't set it then Sedan's prototype's constructor will still be associated with Car which is not what we want.

Difference From Class Based Inheritance
Behaviorally this is pretty similar to inheritance as we all know it - Sedan gets the properties of Car. So how does it differ? Well, a big difference is that in Class based inheritance there is effectively one Car object for every Sedan object. With the prototype approach there is a single Car object, the one assigned to the prototype, and it is shared by all the Sedans. This means that you can't send parameters from the constructor of Sedan to the constructor of Car (see below for ways around this). You have to know the parameters for the superclass constructor at class declaration time, like below.
  1 function Polygon(sides) { 
  2   this.sides = sides; 
  3 } 
  4  
  5 Square.prototype = new Polygon(4);
  6 Square.prototype.constructor = Square 
  7 function Square(length) { 
  8   this.length = length; 
  9 }
So what if we wanted to add perimeter function to Polygon so all polygons have it. Something like:
Polygon.prototype.perimeter = function() {return this.length * this.sides;}
How does polygon get the length field? Obviously we could make the perimeter method take a length parameter, but that wouldn't make for a very good example. One thing that we could do, which is very disconcerting as a Java programmer, is nothing - it'll actually work as is.
var s1 = new Square(5);
var p1 = s1.perimeter();  // returns 20
Even though Polygon doesn't have a length property, because of JavaScript's dynamicness, at runtime everything is hunky-dory since Square's this does have a length property.

What if we really want Polygon to have a length property and not make every derived class specify this property? Maybe we have a base class with a bunch of instance properties that we want inherited? Well, there are a couple of approaches. One is to create a method that acts like a constructor in the base class and have the derived constructors call it.
Polygon.prototype.init = function(length) { this.length = length; }
function Square(length) { 
  this.init(length); 
} 
Another option is to write the base constructor so that it will handle 0 or all the arguments, and then call the base constructor:
  1 function Polygon(sides, length) { 
  2   this.sides = sides; 
  3   this.length = length; 
  4 } 
  5  
  6 Square.prototype = new Polygon();  // the prototype object has undefined sides and length property
  7 Square.prototype.constructor = Square 
  8 function Square(length) { 
  9   Polygon.call(this, 4, length);  // let Polygon's constructor update our properties
 10 }
Note that a new Polygon is NOT created on line 9.  Polygon's constructor is being executed on Square's this property.  One thing you have to watch out with this approach is that when we instantiate a Polygon to assign it to a Square prototype (line 6), we are not passing any arguments. As long as in the Polygon constructor we are just assigning them to properties, that is fine. However, if we are going to dereference them (e.g. to do more advanced calculations), we must first check that they are defined or else we will get the equivalent of a null pointer exception.

Wrong Approach
One solution that might seem like a good idea is to set the prototype in the constructor, as such:
  1 function Square(length) { 
  2   this.__proto__ = new Polygon(4, length); // bad idea
  3 } 
  4 Square.prototype.area = function() { return this.length * this.length; }
  5  
  6 var square = new Square(10);
  7 var sideCt = square.sides; // returns 4
  8 var area = square.area() // ERROR! no such method
This does give you access to the "superclass" properties, so line 7 will work as you would expect.  However, you are overwriting the default prototype object, so you lose all of its properties.  In the example above this means that the square object doesn't actually have the area method defined on line 4, which will cause an error to happen on line 8.  You'll also notice on line 3 that the actual name of the prototype property is __proto__, which is a good indicator that you shouldn't use it directly.

Summary Is-A vs. Has-A

In Class based inheritance, a derived class has an Is-A relationship with its parent class. An instance of the derived class is an instance of the parent class, just with more properties.  In the JavaScript prototype approach, the "derived" class Has-An instance of the "parent" class.  When property lookups are made on the derived instance, if it doesn't have the property it delegates the call to the parent object.  However, this automatic delegation can make the object behave as if it "is-a" parent object.  Which means I am going to stop writing now before I confuse you (or myself) any more.

Monday, September 13, 2010

Extending the Drawing Program with AJAX

Recently I wrote a simple drawing program.  Now I want to be able to save what I drew and then reload it.  I want the data saved on a server somewhere, and I want the act of saving and loading to be done via AJAX. This is the story of how I accomplished this.

Decisions

Ruby on Rails vs. Google App Engine

My first decision was what to use as my server platform.  I've had some experience with Java Servlets, ASP.NET, PHP, and Ruby on Rails.  Ruby on Rails is definitely the coolest of these.  However, given that I am a Google fan-boy, I at least considered the Google App Engine which also looks pretty cool.  However, laziness won out and I stuck to Rails because I know it and I am already tackling a bunch of new things on this project.  Plus I want to know Rails better.  At some point I'll have to come up with a project to try out with Google, and see if I want to change my mind.

JQuery vs. Prototype

As I said above, I want to accomplish the interaction between the client and the server via AJAX.  Well, actually I want to pass JSON messages, not XML, but I think they still call it AJAX.  Anyway, while I could do this myself, it seems to make sense to take advantage of existing libraries.  While there are a ton of JavaScript libraries, the two that seem to be the most popular are jQuery and Prototype.  Prototype is distributed with Rails and so is the natural choice.  But supposedly jQuery is much more lightweight and efficient, so I am going to go with jQuery.

I realize that neither of the choices above seem to be very well researched.  Well, this is just a toy project - if I spend forever researching all the options then I'll never get anything done.  Just by doing something, hopefully I'll be better informed in the future.

What I Did

First I created a rails project:
rails drawing
and then I imported the HTML and JavaScript that I wrote into the public directory of the project.

Of course I needed a database to store the maps in.  I decided to use SQLite for now because it is so easy to set up.  I'll probably move to mysql or something if/when I deploy it for real.  I then used the rails scaffold command to generate the stub rails code.

ruby script/generate scaffold Map name:string content:text

In theory, I don't really need the generated map controller and views.  However, being able to point a browser at <host>/map/ and see all of the uploaded maps provides a very easy way to test if maps are being saved.  I then created my AJAX controller with a save_map and load_map action.  Since these are intended to be used in an AJAX fashion, I didn't create any views for them.

Ruby

My intent was for the drawing program to pass the map as a JSON object to the AJAX call.  The controller could just save that to the database and read it back for a load.  As far as Ruby is concerned it is just a string.  Here is the ruby code that makes that work.
class MyAjaxController < ApplicationController
  
  def save_map
    name = params[:name]
    mapData = params[:map].to_json
    map = Map.find(:first, :conditions=>{:name=>name})
    map.content = mapData if map
    map = Map.new(:name=>name, :content=>mapData) unless map
    map.save!
    render :text=>"ok"
  end

  def load_map
    name = params[:name]
    map = Map.find(:first, :conditions=>{:name=>name})
    render :text=>map.content
  end
end
As you can see, the save method just reads the name and map value from the posted parameters.  Since ruby tries to parse these as objects, I call to_json to get the map contents back into a string.  Then I just save it to the database (either as a new row, or updating an existing row).  load_map just returns the map content that was saved with the given name.  Neither of these methods have much in the way of error checking, so they are definitely not "production" ready, but they work great as a proof of concept.

HTML

Here are the controls I added to the page to allow saving and loading.
<input type="text" id="name"/>
<input type="submit" id="save" value="Save" />
<input type="submit" id="load" value="Load" />

JavaScript

The JavaScript for making the AJAX call looks like this:
  1 $("#save").click(function() {
  2   var data = draw.save(); 
  3   var name = $("#name").get(0).value;
  4   $.post('/my_ajax/save_map', {name:name, map:data}, function() {
  5       alert("Map saved!"); 
  6   });  
  7 }); 
  8  
  9 $("#load").click(function() {
 10   var name = $("#name").get(0).value;
 11   $.getJSON('/my_ajax/load_map', {name:name}, function(data, textStatus) {
 12     control.reset(); 
 13     draw.load(data); 
 14   });  
 15 });
Everything that starts with a $ is a jQuery function.  #save, #load, and #name refer to the HTML controls I've put on the page. The draw variable is the DrawingRecord instance, and control is a ControlLayer instance from the original drawing program.  I added a save and a load method to the DrawingRecord to save and restore the map.  Both Ajax calls $.post(...);   $.getJSON(...); take a URL, an object to pass to the server, and a function which is called when thecall returns (i.e. the A in AJAX).
As for what the draw.save() method returns, originally I just tried using the DrawingRecord.lines object.  Unfortunately this caused problems - apparently jQuery tried to package up all the methods as well as the fields of the object.  So instead I made the save and load methods in DrawingRecord package up all of the points into a single array which can be easily passed back and forth.
  1 DrawingRecord.prototype.save = function(){
  2   var lines = [] 
  3   for (var i in this.lines) {
  4     var line = this.lines[i];
  5     lines.push(line.p1.x, line.p1.y, line.p2.x, line.p2.y); 
  6   } 
  7   return {lines:lines} 
  8 } 
  9 DrawingRecord.prototype.load = function(data) {
 10   this.reset(); 
 11   this.dontDraw = true;
 12   var temp = []; 
 13   for (var index in data.lines) {
 14     temp.push(parseInt(data.lines[index])); 
 15     if (temp.length == 4) {
 16       this.addLine(new Point(temp[0], temp[1]), new Point(temp[2], temp[3]));
 17       temp = []; 
 18     } 
 19   } 
 20   this.dontDraw = false;
 21   this.draw(); 
 22 }
And with that, it basically all works.  Unfortunately, I can't have a live demo of this to put in this blog as I don't have a live server that I want to have committed to serving this project forever.

Monday, September 6, 2010

Depending on Dependency Management

Back in school most development projects were standalone, depending on nothing more than the standard libraries that ship with the compiler (typically C or Pascal in those days).  And really, how much in the way of libraries do you need to calculate the effects of different collision resolution techniques on hash tables?  However in the "real" world, you are writing something much larger, and you'd be foolish not to take advantage of various libraries out there to help.  Heck, in most groups I've worked in, we've had our own internal libraries to do common tasks in addition to external libraries.

One other important difference between school and the "real" world (at least for purposes of this discussion), is that in school projects are small, both in terms of people and duration.  Which means if you do need some library you just make sure everyone on the team gets it.  You don't typically have the problem of taking a new guy on a team and telling them to go get this project from 3 years ago and get it working on your current hardware/software platform.

So now, 3 paragraphs in, I've gotten to the plight of our mythical developer.  He checks out the code out of CVS (ugh, are they still using CVS?), loads it up in Eclipse, and !?!?!   I (err...I mean he) can't even build it?  What's up with that?  "Oh, you need to go get jar file A and B and C.  They can be found here."  Ok, now it builds, let's deploy it.  "Oh, now you need to install jar file D in your JBoss directory..."  Ok, that wasn't too bad, but how long would it have taken me (I mean him) to figure out all of these dependencies if someone wasn't around who knew what was needed?

And now, only 1 paragraph later, we've gotten to the main topic - Dependency Management.  These days everyone has dependencies (see paragraph 1), and here are some ways that you may handle them in the Java world:

Options
  1. Manage the dependencies in your head - go and get the libraries you need when you need them and put them in their CLASSPATH.  Or the slightly better variants where these dependencies are documented on your team Wiki (you do have a team wiki, right?), or in a script that you run when you do an initial checkout to get your dependencies.
  2. Create a lib directory in the project and check in all of the required dependent libraries in this directory.
  3. Have a common network share that can be mounted by all of your developers and have your project CLASSPATH (as described in ant or a .classpath file or something checked into your version control) refer to these shared jars
  4. Use Ivy - an ant plugin for describing dependencies and let it go grab all the jars that you need when you try to build
  5. Use Maven - a project management tool that will both grab your dependencies and jars.
As you've probably guessed by this point, I am not a fan of the first approach.  It makes it hard for someone to get started on the project.  This startup cost can be the difference between someone helping out or not, if they have just a little bit of time to work on your project.

Option 2, putting all your jars in a lib directory and checking it in, is definitely easy.  There is some concern that this will be too large.  Let's investigate this concern.  Our largest project (in terms of dependencies) seems to have about 80 megs of dependent jars, so I am going to use that number.  Let's say that we upgrade these jar files once a year and that the new jars and that the version control system thinks they are 100% different, so space is duplicated.  So in 5 years, 400MB of your version control system is taken up with these jars.  And if you are using a DVCS like Mercurial this means that each developer will have all of this, and will have to copy it across the network when they do their first checkout.  And, while that wouldn't have fit on the hard drive of my college computer ("Back in my day..."), now-a-days with terabyte drives and gigabit Ethernet that's not really that much, and 5 years from now (which is when it will be that big), its going to be even less.  Of course, your numbers may be different - so it may pay to do this calculation yourself.

Option 3 is about as easy as option 2, but without requiring the "bloating" of your version control system.  However, it kind of feels wrong to me, and here are a couple of reasons.
  • Remote working - hard to work disconnected from home, if you need access to the shared drive just to compile
  • Will your team really be as disciplined with these files as files in version control?  i.e. Are you sure a file won't just get deleted / replace / modified?  Can you revert to an old version if it does?
I am going to talk about Option 4 and 5 together.  I have used Maven in the past and recently looked into Ivy which led to this blog post.  They both seem like cool ideas, and if you are in an environment where you may not be able to include the dependent libraries with your code (e.g. open source projects), it may be a really good idea to use one of them.  However, for in-house development, I am not sure they are worth the effort.  Using either of them means one or more configuration files that have to be associated with each project.  This means yet one more tool to integrate with all your other tools and that everyone on the team has to know and understand.  At least one person has to take the time to understand it well enough to be able to setup/convert your projects to use this tool.  And it adds one more external dependency, which can particularly be a pain going forward - just ask people who had Maven 1 projects and then had to go through work to upgrade them to Maven 2.  It may not seem like a lot of work, but it's more than just a 10 minute download and install and any work is typically too much if it isn't helping you write your software.

Conclusion

There are plenty of options out there, but unless you have a good reason to do something different, just check your libraries into a lib directory and then forget about it and get back to work.

Sunday, August 29, 2010

JavaScript Drawing Program

I have decided to create a simple drawing program in JavaScript.  My goal is to provide a simple <draw straight lines on graph paper> application. I won't support curves, line styles, or colors. I would like to support erase and undo/redo. All points will be automatically snapped to lattice points. My vision is that you'll start with a piece of graph paper (i.e. a light blue grid). You should be able to click on two points to create a line. It would be nice if it showed you what you were about to draw before you draw it. i.e. this should be just like many other drawing program, just with less features.

If you don't want to read any of the details, jump to the bottom and see the end result.

Implementation Highlights

HTML 5 provides this nice tag, <canvas>, which looks very useful for drawing. Every modern browser, except Internet Explorer, seems to support it including the Android and iPhone mobile devices. Since I am writing this for myself, I am ok with IE not being supported.

I see this app as having 3 layers. The bottom layer is the grid. The middle layer is the actual drawing. The top layer is the control layer where it shows you what you are about to draw. It seems logical to me to implement this as 3 canvas instances that are all in the same location. I do this by putting all 3 canvas instance in the same div, and positioning them absolutely to the top left of this div. This seems to do the trick, as when I play with it, all 3 are superimposed and drawing on a higher layer covers the lower layer, and erasing the higher layer reshows the lower layer.
  1 <html> 
  2   <head> 
  3     <style> 
  4 #windowcontainer {position:relative; height:400px;}
  5 .gridLayer {position: absolute; top: 0px; left: 0px;}
  6     </style> 
  7     <script> 
  8 // javascript code goes here 
  9     </script> 
 10   </head> 
 11   <body>  
 12     <div id='windowContainer'>  
 13       <canvas id="gridLayer" class="gridLayer" height="400" width="600"></canvas> 
 14       <canvas id="drawLayer" class="gridLayer" height="400" width="600"></canvas> 
 15       <canvas id="controlLayer" class="gridLayer" height="400" width="600"></canvas> 
 16     </div> 
 17   </body> 
 18 </html>
Now I create 3 classes, one for handling each layer. The Grid knows how to map between browser coordinates and lattice coordinates, as well as how to draw itself. The DrawingRecord knows how to draw lines and keeps track of all of the lines that have been drawn. The ControLayer actually registers the mouse listeners and determines when lines should be drawn, delegating functionality to the other two objects when appropriate.
  1 function Grid(canvas, width, height) { 
  2   this.ctx = canvas.getContext('2d');
  3   this.width = width; 
  4   this.height = height; 
  5 } 
  6 Grid.prototype.color = "#00FFFF"; 
  7 Grid.prototype.size = 25; 
  8 Grid.prototype.offsetX = 10; 
  9 Grid.prototype.offsetY = 10; 
 10 Grid.prototype.draw = function(){ /* implementation */ }
 11 Grid.prototype.getLatticePoint = function(x, y){ /* implementation */ }
 12 Grid.prototype.getReal = function(latticePoint){ /* implementation */ }
 13  
 14 function DrawingRecord(canvas, grid){ 
 15   this.canvas = canvas; 
 16   this.ctx = canvas.getContext('2d');
 17   this.grid = grid; 
 18   this.lines = {}; 
 19   this.nextLine = 0;
 20 } 
 21 DrawingRecord.prototype.addLine = function(p1, p2){ /* implementation */ }
 22 DrawingRecord.prototype.eraseLine = function(p1, p2){ /* implementation */ }
 23 DrawingRecord.prototype.draw = function(){ /* implementation */ }
 24 DrawingRecord.prototype.reset = function() { /* implementation */ }
 25  
 26 function ControlLayer(canvas, grid, drawRecord){
 27   this.ctx = canvas.getContext('2d');
 28   this.canvas = canvas; 
 29   this.grid = grid; 
 30   this.drawRecord = drawRecord; 
 31 } 
 32 ControlLayer.prototype.drawTempLine = function(){ /* implementation */ }
 33 ControlLayer.prototype.click = function(e){ /* implementation */ }
 34 ControlLayer.prototype.onmousemove = function(e){ /* implementation */ }
 35 ControlLayer.prototype.registerMouse = function(){
 36   var self = this;
 37   this.canvas.addEventListener("click", 
 38                    function(e){ self.click(e); }, 
 39                    false); 
 40   this.canvas.onmousemove = function(e){ self.onmousemove(e); }
 41 }
You can see one interesting JavaScript thing that I learned in the registerMouse method in lines 36-40.  I create a self variable which is the same as this.  If I don't do this, when canvas.onmousemove is called, the this object will refer to the canvas not the ControlLayer, since it is canvas's onmousemove that is being called.  Since I don't actually want an infinite loop, I can't do this.  By creating a local 'self' variable I make it a free variable (if I am using the closure terminology correctly) which will refer to this ControlLayer object for all time.

Erasing Lines

Erasing a line segment was more complicated than I had first hoped. It turns out that there doesn't seem to be a "clearLine" method in the canvas context. So, to accomplish an erase I do something like:
  1. Remove the line segment from the list of lines that have been drawn
    1. For each existing line segments
      1. If it doesn't overlap with the erase line segment go to next segment
      2. Remove the existing line segment.
      3. Determine if the overlap if full or partial, and if partial, add the shorter new line segment(s) back to the list.
  2. Clear the drawing layer
  3. Redraw all of the existing line segments
Undo/Redo

An undo feature is always really nice to have, and I once read (I don't remember where) about a project where it was a real pain to retrofit it in after the fact.  So undo/redo is one of the first features I am writing.  Logically, what I have is a stack of actions.  Undo moves us down the stack and redo moves us back up.  Since functions are first class objects, it is easy to store them on the stack.  Redo is easy, as I just run the command again.  But what about undo?  My first thought was to have undo just do the inverse function, so if the action was drawLine, then undo would eraseLine.   Unfortunately eraseLine isn't actually the opposite of drawLine, as I'll show.

Imagine I draw a horizontal line on the x-axis from 1 to 4.  Now I draw a second line from 3 to 6.  When I undo, if I erase from 3 to 6, I'll have erased too much.  I really want to only erase from 4 to 6 so I don't erase any of the first line.

With some work, I could actually determine the real inverse action, and I may still need to do that.  However, a much simpler, though more computationally expensive, idea occurred to me.  If a user has done actions 0 through N, and then does an Undo, rather than try to reverse step N, just clear the state and then replay actions 0 through N-1.  This feels wasteful, but if I turn off drawing while doing this, this is just replaying a bunch of simple calculations which will happen really quick (assuming we aren't talking millions of steps - but if you are doing that much work, this toy drawing program is not for you), and then I can just do a single draw of the final state.  i.e. something like:
  1 function UndoStack(draw){ 
  2   this.stack = []; 
  3   this.maxCmds = 0;
  4   this.curCmd = 0;
  5   this.draw = draw; 
  6 } 
  7 UndoStack.prototype.add = function(cmd) { 
  8   this.stack[this.curCmd++] = cmd;
  9   this.maxCmds = this.curCmd;
 10 } 
 11 UndoStack.prototype.undo = function(){ 
 12   this.draw.reset(); 
 13   this.draw.dontDraw = true;
 14   this.curCmd--; 
 15   for (var i = 0; i < this.curCmd; i++) {
 16     this.stack[i](); 
 17   } 
 18   this.draw.dontDraw = false;
 19   this.draw.draw(); 
 20 } 
 21 UndoStack.prototype.redo = function(){ 
 22   this.stack[this.curCmd++]();
 23 }
And the code in the ControlLayer looks like
  1 var p1 = this.firstPoint;
  2 var p2 = this.currentPoint;
  3 var drawRecord = this.drawRecord;
  4 var drawFunc = this.erase ? drawRecord.eraseLine 
  5                           : drawRecord.addLine; 
  6 var func; 
  7 if (this.rect) { // draw all 4 sides of rectangle as one action
  8   func = function(){ 
  9     drawFunc.call(drawRecord, p1, new Point(p2.x, p1.y));
 10     drawFunc.call(drawRecord, p1, new Point(p1.x, p2.y));
 11     drawFunc.call(drawRecord, p2, new Point(p2.x, p1.y));
 12     drawFunc.call(drawRecord, p2, new Point(p1.x, p2.y));
 13   } 
 14 } else { 
 15   func = function(){drawFunc.call(drawRecord, p1, p2);}
 16 } 
 17 func(); 
 18 this.undoStack.add(func);
Geometry
Computation geometry problems are a set of problems that always seem to bite me in programming contests. So I tried to keep things simple and created a couple of helper classes.

Point
I created a Point class, which just has an x and y coordinate and the ability to compare points with Fortran style methods .lt, .ge, .eq, etc.  My definition of ordering is, Point A is less than Point B iff A.x < B.x OR (A.x == B.x AND A.y < B.y).  This definition provides the expected ordering of points that are collinear which is useful when calculating line overlaps.

Line
My Line class is just two points, p1 and p2.  For simplicity, I ensure that p1 < p2.  I also store a slope object of the line which is just a rise and a run.  The slope is canonicalized so that rise and run are in lowest terms, and that run is nonnegative.
  1 function Slope(p1, p2) { 
  2   var rise = p1.y - p2.y; 
  3   var run = p1.x - p2.x; 
  4   var gcd = Slope.gcd(Math.abs(rise), Math.abs(run));
  5   rise /= gcd; 
  6   run /= gcd; 
  7   if (run < 0) {
  8     rise *= -1; 
  9     run *= -1; 
 10   } else if (run == 0) {
 11     rise = 1; 
 12   } 
 13   this.rise = rise; 
 14   this.run = run; 
 15 }
I can now determine if two lines overlap by seeing if they are collinear
  1 Line.prototype.collinear = function(line) {
  2   if (!this.slope.eq(line.slope)) return false;
  3   if (!this.p1.eq(line.p1) &&
  4       !this.slope.eq(new Line(this.p1, line.p1).slope)) return false;
  5   return true;
  6 }
and if their endpoints overlap.
  1 Line.prototype.overlaps = function(line) {
  2   return this.collinear(line) &&
  3          this.p1.lt(line.p2) && this.p2.gt(line.p1);
  4 }

Demo
And here is what the end product looks like, at least if you are using a compatible browser.  Feel free to view the source and see all the code that I left out of the examples above, if you are at all curious.


   


Saturday, August 21, 2010

Learning JavaScript

So I've decided to learn JavaScript. There are a couple of motivations behind this. The practical one is that I have various ideas that I think would be cool on hand-held devices like my Droid or an iPhone or iPad. The obvious drawback is writing for one platform is not going to be compatible with the other, and it is going to be hard enough to find time to write an app once, much less twice. However, if I write the app in JavaScript and make it available as a webpage, it is suddenly available everywhere.

The second motivation is some reading I've done on the web about how JavaScript is a misunderstood language, and it is more like Lisp than like Java. After reading this I felt I owed it to myself to at least learn something about the language, and stop being one of those people who looks down on it "because nobody wants to be a web developer. No self-respecting, rootin'-tootin', core-dump-debugging programmer wants to be one, anyway."

Oh, and let's not forget all of the amazing things Google has done with JavaScript.

JavaScript for Programmers

So to learn, I am going to be writing some programs and I will lean heavily on examples found on the web. Unfortunately, the majority of what is out there is geared towards non programmers. Meaning there is a lot of, "This is a variable. This is a loop. And, if you are ready for it, here is a function!" Or, as one book I saw in the library said, "JavaScript is a programming language, but don't let that scare you." What I am looking for is something geared towards programmers.

While I can't do it justice (only partially because I don't know anywhere near enough), here are a few things I've learned along the way. (and since some of my sources are old, this may be inaccurate).

What I've Learned So Far

Syntactically it is a C family language. So control structures (if, for, while, curly braces) work the way you'd expect.

JavaScript seems to have five types, though in some sense everything is an object.
  • boolean
  • number
  • string
  • object
  • function
Variables are passed by value to functions but, like Java, object variables are really references to the object, so for most purposes you can treat it as pass by reference. And yes, functions can be stored in variables and passed around. (Boy, I hope Java 7 really is going to include closures).

JavaScript is Object Oriented in the sense that everything is an object, but it doesn't have classes in the sense of Java and C++. However, you can treat it like it does, but I think then you are missing some of the power of JavaScript. It follows more of a property pattern, or what Steve Yegge calls the Universal Design Pattern.

So how do you use your own objects? (I'm going to ignore all the built in objects since you can go search the web for them yourself.)

Choice one - ad hoc
  1 var obj = new Object();
2 obj.name = 'hello world';
3 alert(obj.name);
Yep - you can just create an object and start assigning its properties, without defining them first. You can also treat these properties as if they were values in an associative array.
  4 var name = obj["name"];
Choice two - create a standard definition
  5 function Person(name, age) {
6 this.name = name;
7 this.age = age;
8 this.field = 'some value';
9
10 this.getOlder = function() {this.age++;}
11 this.changeName = personChangeName;
12 }
13 function personChangeName(newName) {
14 this.name = newName;
15 }
Note that inside this Person function (aka a constructor) we have access to a 'this' field which acts like this in Java. There are two methods defined in Person, done two different ways. The method getOlder is defined inline - which actually means that a new function is created every time this constructor gets called. If we refer to an existing method, like personChangeName, the function is only created once, but it still has access to the 'this' variable. Now, as expected, you can create a Person object and call its methods and access its fields.
 16 var bart = new Person("Bart Simpson", 10);
17 var me = new Person("Madking", 17); // I can pretend, right?
18 me.getOlder(); // Now I can vote!
19 alert(me.name + " is " + me.age + " and has field: " + me.field);
However, like the ad-hoc method, we can still attach new properties or methods to a Person object at any time.
 20 me.sayHi = function() { alert("hi: " + this.name); };
21 me.species = "Wannabe Blogger";
We can also assign properties to the function/Class itself. (ala static methods/variables)
 22 Person.staticVar = "not a constant";
23 Person.staticFunction = function() { /* do something */ };
There is a special Class variable called 'prototype'. Every instance automatically gets the fields and functions defined by its prototype.
 24 Person.prototype.sayBye = function() { alert("bye: " + this.name); };
25 Person.prototype.species = "Homo Sapien";
So every Person object (like "me") now has a function called "sayBye", and a field "species". However, individual objects can override these "inherited" properties. So the me object is still of species "Wannabe Blogger". Note that this means that even though it looks like "bart" and "me" are both instances of Person, this isn't true in the Java sense of the world. me has a "sayHi"method which bart doesn't have. Also note that you can add new fields and methods to both the objects and their prototype (thereby affecting all objects of this type that already or will exist) at any time.

Last couple notes

Arrays and Associative Arrays are commonly used data structures. In JavaScript, every object is an Associative Array mapping strings to anything. However you can also use non-negative integers as your key ala an array. And if the object is an Array object, it will have array-like methods and properties (like length). Arrays can be sparse, so you can have an array and assign element 0 and 100 and nothing in between, if you want. In this case, the length will be 101, i.e. the lowest unassigned index. There is also convenient literal syntax for defining arrays and associative arrays (objects) which is fairly self explanatory.
  1 var myArray = [1, 2, "mixed type", new Person("Lisa", 7), 3];
2 var myObject = {
3 name : "Homer",
4 age : 36,
5 wife : new Person("Marge", 34),
6 talk : function() { alert("DOH!"); }
7 };
Oh, and strings can be contained inside of either single or double quotes. Though it is poor style to randomly switch between them as I did in my examples above.

One other cool thing about JavaScript is the low barrier to entry. Open your favorite editor (or least favorite, doesn't matter), and create an html file. Put any/all of the code above inside a script tag. Nope open the file up in your browser of choice. VoilĂ , you have written a JavaScript program.
<script>
alert("java script is working!"); // replace with your own code
</script>
Yes, there is supposed to be an attribute in the script tag, and it should be embedded inside a body element of an html element, but this lazy approach seems to work if you are just playing around.

Monday, August 16, 2010

Don't Reuse. Rewrite!

As Isaac Newton said, "If I have seen further it is only by standing on the shoulders of giants." This is the promise of reuse. By taking advantage of libraries and frameworks we are able to write large complex systems at a fraction of the time and effort that it would be without.

And yet...

Just like anything else in an engineering discipline, it is about tradeoffs. Using an external library causes an external dependency. An external dependency is one more thing that has to be learned to understand a whole system. It may have bugs or just be poorly documented. Two years from now when you are moving to new hardware, it may not support the new hardware. In short using a third party library is far from free even if it is free as in beer or speech.

"If it's a core business function -- do it yourself, no matter what."So when should you use an existing library vs. writing it yourself? Joel Spolsky says, "If it's a core business function -- do it yourself, no matter what." This is is good advice. However, I would also say that if the effort of writing it yourself is not much more than that of integrating the library, then you should write it yourself.

So what brought this up? On my last post about JNDI, SQL, and JUnit, I used a few third party packages. Joseph Graves emailed me and told me how he had solved the SQL problem by writing his own mock JDBC library, and that it looked like it would be simple to do so for JNDI. While I still think using HSQLDB was the right thing for my situation, he had a good point about JNDI. Did I really need to add an external dependency when all I wanted was effectively a global Map? And so I rewrote the JNDI part as follows:
  1 import java.util.HashMap;
2 import java.util.Hashtable;
3 import java.util.Map;
4
5 import javax.naming.Binding;
6 import javax.naming.Context;
7 import javax.naming.Name;
8 import javax.naming.NameClassPair;
9 import javax.naming.NameParser;
10 import javax.naming.NamingEnumeration;
11 import javax.naming.NamingException;
12 import javax.naming.spi.InitialContextFactory;
13
14 public class MockInitialContextFactory implements InitialContextFactory {
15
16 private static Context sInitialContext;
17
18 public synchronized Context getInitialContext(Hashtable<?, ?> environment)
19 throws NamingException {
20 if (sInitialContext == null) {
21 sInitialContext = new MockContext();
22 }
23 return sInitialContext;
24 }
25
26
27 static class MockContext implements Context {
28
29 private Map<String, Object> mMap = new HashMap<String, Object>();
30
31 public Object lookup(String name) throws NamingException {
32 return mMap.get(name);
33 }
34
35 public void bind(String name, Object obj) throws NamingException {
36 mMap.put(name, obj);
37 }
38
39 // remainder of auto-generated stub methods with default implementation
40 }
41 }
As you can see, with just a handful of meaningful lines of code (and Eclipse's stub generation) I was able to remove the dependency on two third party jars, thereby simplifying the whole system.