World of Warcraft HTML Tooltip Diff

MMO-Champion is a World of Warcraft news website. When a new patch is released, we want to show what has changed in the game (Post Example). An english summary of each spell change is hand written, but we want to show the exact tooltip changes.

.sigrie-tooltip {
max-width: 325px !important;
float: none;
display: inline-block;
}
.inline ins { background-color: #afa; }
.inline del { background-color: #faa; }
ins, del {
text-decoration: none;
}
.new ins {
background-color: #afa;
}
.old ins {
background-color: #faa;
}
.sigrie-tooltip ins {
color: black;
background-color: #80FF80;
font-weight: bold;
}

Generate Tooltips

First, we use the database application to generate the tooltips in HTML form.

Epic
Binds when equipped
Chest
1669 Armor
+341 Intellect
+512 Stamina
Requires Level 85
Item Level 359
Equip: Improves critical strike rating by 205.
Equip: Increases your mastery rating by 241.
Epic
Binds when equipped
Chest
1669 Armor
+321 Intellect
+512 Stamina
Requires Level 85
Item Level 359
Equip: Improves critical strike rating by 205.
Equip: Increases your mastery rating by 221.

Tokenize

We are not going to do a full HTML diff which is really difficult. Instead, the trick is to parse the HTML and extract only text nodes. We split them by space to generate a token stream.

.html-diff-bulle span { display: inline-block; border: 1px solid #333; border-radius: 3px; margin: 3px; padding: 2px; }
.html-diff-bulle .old { background-color: #faa; }
.html-diff-bulle .new { background-color: #afa; }

ChestguardofNature’sFuryBindswhenequippedChest1669Armor+341Intellect+512StaminaRequiresLevel85Equip:Improvescriticalstrikeratingby205.Equip:Increasesyourmasteryratingby241. ChestguardofNature’sFuryBindswhenequippedChest1669Armor+321Intellect+512StaminaRedSocketSocketBonus:+10HasteRatingRequiresLevel85Equip:Improvescriticalstrikeratingby205.Equip:Increasesyourmasteryratingby221.

Diff

Paul Butler SimpleDiff algorithm is used on the two token streams to label each token with old, new or both.

ChestguardofNature’sFuryBindswhenequippedChest1669Armor+341Intellect+512StaminaRequiresLevel85Equip:Improvescriticalstrikeratingby205.Equip:Increasesyourmasteryratingby241. ChestguardofNature’sFuryBindswhenequippedChest1669Armor+321Intellect+512StaminaRedSocketSocketBonus:+10HasteRatingRequiresLevel85Equip:Improvescriticalstrikeratingby205.Equip:Increasesyourmasteryratingby221.

Combine

We parse the HTML again. This time we pretty-print the HTML while traversing it. As we parse text nodes, we add <ins> tags where we need to. We just make sure to group contiguous insertions.

Epic
Binds when equipped
Chest
1669 Armor
+341 Intellect
+512 Stamina
Requires Level 85
Item Level 359
Equip: Improves critical strike rating by 205.
Equip: Increases your mastery rating by 241.
Epic
Binds when equipped
Chest
1669 Armor
+321 Intellect
+512 Stamina
Requires Level 85
Item Level 359
Equip: Improves critical strike rating by 205.
Equip: Increases your mastery rating by 221.

Text Diff

We would also like to get a text-based diff we can insert in a Patch Note. We combine both token streams into one.

Chestguard of Nature’s Fury
Binds when equipped
Chest
1669 Armor
+341+321 Intellect
+512 Stamina
Red Socket
Socket Bonus: +10 Haste Rating
Requires Level 85
Equip: Improves critical strike rating by 205.
Equip: Increases your mastery rating by 241.221.

Chestguard of Nature’s Fury Binds when equipped Chest 1669 Armor +341+321 Intellect +512 Stamina Red Socket Socket Bonus: +10 Haste Rating Requires Level 85 Equip: Improves critical strike rating by 205. Equip: Increases your mastery rating by 241.221.

However, the result isn’t that readable. There is too much noise. We want to show only the information that has changed! In order to do that, we are going to keep only the lines that contain changes.

+341+321 Intellect
Red Socket
Socket Bonus: +10 Haste Rating
Equip: Increases your mastery rating by 241.221.

+341+321 Intellect Red Socket Socket Bonus: +10 Haste Rating Equip: Increases your mastery rating by 241.221.

And it works a lot better πŸ™‚

Conclusion

This approach is working really well with the World of Warcraft tooltips. After many patches and hundreds of changes, I haven’t seen any weird behavior. They were common before using this technique. The only downside: non textual changes such as icons or colors will be completly ignored.

In my Binary Decision Diagram Library, the performance bottleneck was the uniqueness cache. By reducing the number of cache lookup, it is possible to greatly improve the performances.

Common pattern

In order to test if the key is already in the cache, the usual pattern is to use key in cache. This leads to the following code:

function cachedValue(key) {
  if (key in cache) {
    return cache[key];
  } else {
    var result;
    /* generate result */
    return cache[key] = result;
  }
}

Ideal cache lookup

The expensive operation with a cache is to traverse the data structure in order to find the position where the element should be. In the previous code, there are three independent lookups: key in cache and 2x cache[key].

In order to improve performance, the ideal would be to make that expensive lookup once, and do the test/get/set directly at that position.

function cachedValue(key) {
  var position = cache.lookup(key);
  if (cache.has(position)) {
    return cache.get(position);
  } else {
    var result;
    /* generate result */
    cache.set(position, result);
  }
}

Javascript Workaround

However, there is no API to directly manipulate the lookup and position. We have to find workarounds.

We remark that cache[key] will either return the value or undefined if not present in the cache. The belonging test no longer requires a full lookup, you only have to compare the value with undefined.

function cachedValue(key) {
  var result = cache[key];
  if (result === undefined) {
    /* generate result */
    cache[key] = result;
  }
  return result;
}

There is only one drawback: it is no longer possible to use undefined as a value in your cache.

Without temporary

If the result can be generated inline and your cache will never contains falsy values, you can use a shorter version. It should not impact performance however.

function cachedValue(key) {
  return cache[key] || (cache[key] = /* generate result */);
}

Conclusion

There are still two lookups done in case of a cache miss. If you find a way to factor the code in a way that removes it, I’m really interested in knowing πŸ™‚

At the time of writing, the described technique is faster on all the tested browsers. As performance in browser rapidly evolve, check out the jsPerf entry before you decide to use it in your application.

Lately, I’ve been advocating to all my student friends to start a blog. Here’s an article with the most common questions answered πŸ™‚

What are the benefits?

Being known as an expert. The majority of my blog posts are about advanced Javascript topics. As a result, I’m being tagged as the “Javascript” guy by people that know (broad sense) me. Every time they have a question about Javascript or Web Development they go to me.

Expanding your relations. Through my activities with this blog, I had conversations with celebs such as Bjarne Stroustrup (C++), Brendan Eich (Javascript), Jeremy Ashkenas (CoffeeScript) and many other people that I didn’t know before. No one in my close relations is deeply interested in what I am writing. But thanks to the internet, I can meet other people that shares the same interests.

Getting Recruited. As you become an expert in a field, people start to notice and will want you. My blog is barely known and still, I have received several job offers. However this happens at random, take it like a gift but don’t expect it to happen, or it won’t πŸ™‚

Being better. I’ve been so much better at Javascript since I started writing about it. But maintaining this blog also helped me improve my writing skills as well as my English.

Benefits are long term. You should not start a blog and expect it to be rewarding the next week. A blog is a presence on the internet. During the first 6 months, I barely had more than 5 visitors per day, but this number slowly started growing as I wrote more articles and time passed. Now, I’m at 100 visitors a day. I’m still amazed to see that so many people come!

Who cares about my blog?

Your friends. The first thing I do when I am done writing an article is to paste the link to some of my MSN contacts that will be vaguely interested in. It is a powerful way to start a conversation with people you did not talk with for a long time. I often re-write parts of the article given the feedback I receive and it leads to great conversations.

People on the Internet. My girlfriend always says “If you thought about it, someone did it”. On the same idea, I believe that the following statement is correct: “If you find something interesting, someone else does too”. Here is a fact, there are over 100 visitors on my blog everyday. Google connects people with the same interests!

People that want to know about you. The extreme example is your recruiter, but it could be a co-worker or even just a friend. Your blog is the place where you can show who you are and what you are worth. It is much better than a resume as it isn’t constrained by a strong standardization and a ridiculous 1-page constraint.

I don’t know what to write

Projects you’ve done. The easiest way to start a blog is to write one article per school/personal projects you have done. Put a screenshot, a description of what it does and you are set. This way, if I want to know about you, I will quickly scroll over your blog and will see what you have done. If something interests me, I’m going to read the article more closely.

Techniques you have used. It is interesting to go over your projects and allocate one blog article for each technical problem you solved. For example, the project Guild Recruitment leaded me to write several articles such as Dynamic Query Throttling, Mysqli Wrapper, Search Optimizations. The latest eventually made me look deeper to write Sorting Table.

Follow-up a conversation. I am often debating with my friends on topics related to computer science. Those discussions are potential targets for a blog post! It is really interesting to go deeper and start writing about it. You’ll get more arguments to crush your friends theories πŸ™‚

Start writing and ideas will flow. Once you have an article written, it often generates new ideas. Now, every time I write some code, I ask myself if that would be worth blogging. If yes, I create a draft on WordPress for later. This way when I’m in the mood of writing, I have many things to write.

There are already many article on the subject, why should I write mine?

Influence people around you. I always love reading my friends blog because they are talking about subjects that I’m interested in but that I would not have willingly researched for. It helps expanding my Javascript-centric horizon.

If you write about it, it means you know it. For example I wrote an article about how to use makedepend in makefiles. It tells recruiter multiple things. I have experienced the problem of dependency management. I am confortable with Makefiles as I used them in a fancy way. This is invaluable compared to a Makefile entry in a resume.

Go deeper in the subject. I often find myself writing code pretty easily without too much thinking. Writing about this particular sexy technique in my blog more challenging. It requires me to state the exact problem I try to solve, think about alternatives, seek for already existing solutions …

After the post has been written, I receive a lot of feedback. My friends almost always talk about how it would have been solved in their own language of predilection. They also provide more use-cases where the technique would and wouldn’t work, leads to improve it …

How long does it take?

Count one evening per post. I usually spend one full evening writing down an involved article like this one. However I think a lot about the subject in a passive way by reading related articles, thinking about it in my bed … Articles that show off a project are much quicker to write, I’d say about 30 minutes.

Post as often as you want. When I have something I deeply want to share I write an article about it. Once I’ve written once, I often see myself writing some more about drafts I had. Then there is a period of silence. Overall, I’d say I write every two months, often during holidays.

How many articles. Each new article you write is not going to shadow the other but adds up. When I check my analytics, each article written slightly increases my daily viewer count. But even with one article a blog is worth it.

How do I start?

Install a WordPress. Even if you are a geek, I strongly recommend against you coding your own blog or using some nerdy blog software. I went over that myself and I found myself coding stuff every time I wanted to write an article. WordPress gives you all the tools you need to blog, and if you want to do something a bit special, chances are there’s already an extension that does it.

Quickly write your first article. Don’t spend so much time finding the perfect theme or installing many extensions you don’t even need yet. The first article is the hardest! Write it down and send it to your friends. Listen to their feedback and instead of editing the article, write another article trying to fix those issues. Writing is hard so it’ll take more than one shot to feel comfortable with it. The more you practice, the easier it will be.

Conclusion

If I managed to convince your starting a blog, please give me the link! I’d love to read about your stuff and may help you get started if you want.

Javascript – Hook Technique

Let’s go back 5 years ago during the World of Warcraft beta. I was working on Cosmos UI, a projects that aimed to improve the World of Warcraft interface.

As interface modification was not officially supported by Blizzard, we went ahead and directly modify the game files written in Lua and XML. We provided the new edited files for the thousands of people using Cosmos.

Previous Method

Let’s take a concrete example. We need to analyze the combat log in order to display a damage chart. The game calls the function ProcessChatMessage with all the required information.

function ProcessChatMessage(message, source, channel) {
  // ... Default Code ...
}

Note: World of Warcraft uses Lua as its programming language but I will use Javascript for this blog post as you, my readers, are most familiar with it. The technique remains exactly the same.

In order to process the combat log, we simply add some code at the beginning of the function in order to execute some action if the channel is COMBAT_LOG_CHANNEL. Nothing really extraordinary.

function ProcessChatMessage(message, source, channel) {
  if (channel == COMBAT_LOG_CHANNEL) {
    // ... Addon Code ...
  }
 
  // ... Default Code ...
}

// … Default Code …
}

However this solution is extremely intrusive as you have to change alter the code. Every time Blizzard releases a new version, we had to make a diff of all the files that changed and manually update all our code base. While we were doing this process, all the user of our interface could no longer play as they depended on us. This was an extremely stressful process on both parts.

This issue along with Blizzard servers being unstable helped start the meme Patch Day, No Play.

Hook Solution

I found out a non-intrusive way to alter the behavior of the game. With that technology unlocked, we started to modularize our codebase. Blizzard noticed and when our migration was nearly over, they added the ability to officially use modules (called Addons).

The technique is extremely simple. It only requires the language to have first class function. You store the function you want to alter in a variable (1). Then you override that function with yours (2), that will call the stored one to keep the default behavior (3).

// (1) Backup the function
var defaultProcessChatMessage = ProcessChatMessage;
 
// (2) Override the function
ProcessChatMessage = function(message, source, channel) {
  if (channel == COMBAT_LOG_CHANNEL) {
    // ... Addon Code ...
  }
 
  // (3) Call Default Code
  defaultProcessChatMessage(message, source, channel);
}

// (2) Override the function
ProcessChatMessage = function(message, source, channel) {
if (channel == COMBAT_LOG_CHANNEL) {
// … Addon Code …
}

// (3) Call Default Code
defaultProcessChatMessage(message, source, channel);
}

This solution gives you a great control as you can add pre and post processing and even skip the old code if you need to. It works for most use-cases unless you have to modify what is inside of the function.

The technique has several important features:

  • The target function does not need to be written in a special form. It does not require to support hooking and does not need to be registered as being hookable somewhere.
  • Multiple hooks can be added independently. For example if another addon called VjeuxAddon wants to manage all the messages that start with VjeuxAddon:, you can just write the following code somewhere in the addon:
    var defaultProcessChatMessage = ProcessChatMessage;
    ProcessChatMessage = ProcessChatMessage(message, source, channel) {
      if (message.match(/^VjeuxAddon:/) {
        VjeuxAddon.processChatMessage(message, source, channel);
      } else {
        defaultProcessChatMessage(message, source, channel);
      }
    }
  • The technique is decentralized. You don’t have to have a system that coordinates all the hooks. Each addon sees only his own hooks.
  • No library is required to use this technique.

Bonus Links

See these links for non-intrusive hooking techniques in other languages:

There is an open problem in porting real game into the web browser related to cursor handling. But before we jump into that, you might actually find these selection of casino bonuses fascinating. You can get free spins and credits by registering an account as a welcome bonus for new players like you.

Problem

Many games such as First-Person Shooters require the mouse to freely move, without the constraints of screen edges. However there is no such API in the browser to make this work.

If you don’t know what I mean, you can experience it yourself on the CopperLicht Quake 3 Map Demo. You will find it really hard to move because there is no way to reproduce the standard FPS cursor behavior.

This important issue does not occur only on First-Person Shooter games. For example in World of Warcraft, you can Left/Right-click and drag in order to move the camera. During the dragging operation the cursor is hidden. When the operation is over, the cursor re-appears at the position it was when the dragging started.

Proposal

The behavior is usually implemented moving back the cursor to the center of the screen at every moment. Therefore, a way to solve the problem would be to implement an API that lets us set the cursor position.

However, in most games, we don’t need to actually control the mouse. Instead, we want to hide the cursor and make the mouse freely move around, without being limited by the size of the screen.

This is why I suggest the addition of a mouseFreeze function. The mouse will be anchored to that position and the mousemove events are going to set a virtual position.

window.mouseFreeze()
// The cursor is hidden
 
addEventListener(window, 'mousemove', function (event) {
  // Everytime the user moves the mouse
  //   The delta is added to "virtual[X/Y]"
  //   The cursor is moved to the center of the screen
 
  event.pageX, event.pageY // Cursor Real Position
  event.virtualX, event.virtualY // Cursor Virtual Position
});
 
window.mouseUnfreeze()
// The cursor is shown
// The cursor is moved to the position it was frozen

addEventListener(window, ‘mousemove’, function (event) {
// Everytime the user moves the mouse
// The delta is added to "virtual[X/Y]"
// The cursor is moved to the center of the screen

event.pageX, event.pageY // Cursor Real Position
event.virtualX, event.virtualY // Cursor Virtual Position
});

window.mouseUnfreeze()
// The cursor is shown
// The cursor is moved to the position it was frozen

Open Questions

I believe that mouseFreeze API is a solution that enables a wide range of games to be ported into the browser while being an order of magnitude less dangerous than giving total mouse control.

The mouseFreeze is currently only an idea and it raises many questions such as

  • How to make sure you can’t get stuck in frozen state?
  • Can it be exploited?
  • What if the user scrolls?
  • What if the user alt-tabs?
  • Add events onmousefreeze, onmouseunfreeze?
  • Allow it only on fullscreen applications?

I am welcoming any feedback on this idea. If you believe it is a good one and are interested in writing a patch for Chrome/Firefox/Opera, I would love to help you out.

References

mashu on Hacker News mentioned that this issue is being worked on in a Chrome Bug. This is an interesting read that proposes alternative solutions and gives more use cases.

JSLint imposes us to do manual hoisting of variables. What if we did it but at the end of the function? πŸ˜›

How you write

function print_array (array) {
  var length = array.length;
  for (var i = 0; i < length; ++i) {
    var elem = array[i];
    console.log(elem);
  }
}

How Javascript “rewrites” it

function print_array (array) {
  var length, elem, i;
 
  length = array.length;
  for (i = 0; i < length; ++i) {
    elem = array[i];
    console.log(elem);
  }
}

length = array.length;
for (i = 0; i < length; ++i) {
elem = array[i];
console.log(elem);
}
}

How we could write it!

function print_array (array) {
  length = array.length;
  for (i = 0; i < length; ++i) {
    elem = array[i];
    console.log(elem);
  }
 
  var length, elem, i;
}

var length, elem, i;
}

$(‘.highlightvar span:contains(var)’).css(‘background-color’, ‘yellow’).css(‘color’, ‘red’)

I have no idea if that could be of any use but it amused me πŸ™‚

Writing a parser for a structured binary format such as a 3D model is extremely annoying. You have first to declare your file structure, and then go over every structure again and make a proper code to parse it. This is mainly caused because the lack of introspection of C/C++ and for performance reasons.

jParser is available on Github. It works on both NodeJS and Browser.

In Javascript, it does not have to be that way! jParser is a class that only asks you to write a JSON version of the structure. It will parse the file automatically for you.

Here is an example of what you could write with jParser:

var description = {
  header: {
    magic: ['string', 4],
    version: 'uint32'
  },
  model: {
    header: 'header'
  }
};
 
var model = new jParser(file, description).parse('model');
console.log(model);
// {
//   header: {
//     magic: 'MD20',
//     version: 272
//   }
// }

var model = new jParser(file, description).parse(‘model’);
console.log(model);
// {
// header: {
// magic: ‘MD20’,
// version: 272
// }
// }

Description

Standard Structure

The description object defines blocks that needs to be parsed. In the previous example, we define two blocks header and model where each block is a list of labelled sub-blocks.

Default blocks such as int32, char, double are provided by jDataView.

This organization makes it easy to reproduce C structures. Let’s see the description of the BMP format.

// Javascript Description
header: {
  header_sz: 	'uint32',
  width: 	'int32',
  height: 	'int32',
  nplanes: 	'uint16',
  bitspp: 	'uint16',
  compress_type:'uint32',
  bmp_bytesz: 	'uint32',
  hres: 	'int32',
  vres: 	'int32',
  ncolors: 	'uint32',
  nimpcolors: 	'uint32'
}
// C Structure
typedef struct {
  uint32_t header_sz;
  int32_t  width;
  int32_t  height;
  uint16_t nplanes;
  uint16_t bitspp;
  uint32_t compress_type;
  uint32_t bmp_bytesz;
  int32_t  hres;
  int32_t  vres;
  uint32_t ncolors;
  uint32_t nimpcolors;
} BITMAPINFOHEADER;

Reference Structures

As you already noticed, instead of using basic blocks, we can use our own blocks. In the following example, uvAnimation uses animationBlock that uses nofs:

nofs: {
  count: 'uint32',
  offset: 'uint32'
},
 
animationBlock: {
  interpolationType: 'uint16',
  globalSequenceID: 'int16',
  timestamps: 'nofs',
  keyFrame: 'nofs'
},
 
uvAnimation: {
  translation: 'animationBlock',
  rotation: 'animationBlock',
  scaling: 'animationBlock'
}

animationBlock: {
interpolationType: ‘uint16’,
globalSequenceID: ‘int16’,
timestamps: ‘nofs’,
keyFrame: ‘nofs’
},

uvAnimation: {
translation: ‘animationBlock’,
rotation: ‘animationBlock’,
scaling: ‘animationBlock’
}

Functions

At this point, it is possible to express any C structure and parse files that could be loaded using a simple read. We now need to integrate a logic within our parser using anonymous functions.

Recursive Parsing

It is a common operation to read consecutive blocks. It is possible to make an array block that takes a block name and a count. It parses all theses blocks and aggregates them into a Javascript array.

array: function (type, length) {
  var array = [];
  for (var i = 0; i < length; ++i) {
    array.push(this.parse(type));
  }
  return array;
},

In order to call a function, we use an array literal where the first element is the block name and the rest are the arguments. We can easily define float[234].

float2: ['array', 'float', 2],
float3: ['array', 'float', 3],
float4: ['array', 'float', 4]

We can use the array block to build a string block. We parse an array of char and join it.

string: function (length) {
  return this.parse(['array', 'char', length]).join('');
},
 
filename: ['string', 32]

filename: [‘string’, 32]

Seek & Tell

In the World of Warcraft models, there is a small structure called nofs that tells us “There are [count] consecutive [type] at [offset]”. We build a struct block in order to parse this pattern. It will use seek and tell to navigate through the file.

nofs: {
  count: 'uint32',
  offset: 'uint32'
},
 
struct: function (type) {
  // Read the count & offset
  var nofs = this.parse('nofs');
 
  // Save the current offset & Seek to the new one
  var pos = this.tell();
  this.seek(nofs.offset);
 
  // Read the array
  var result = this.parse(['array', type, nofs.count]);
 
  // Seek back & Return the result
  this.seek(pos);
  return result;
},
 
triangles: ['struct', 'uint16'],
properties: ['struct', 'boneIndices']

struct: function (type) {
// Read the count & offset
var nofs = this.parse(‘nofs’);

// Save the current offset & Seek to the new one
var pos = this.tell();
this.seek(nofs.offset);

// Read the array
var result = this.parse([‘array’, type, nofs.count]);

// Seek back & Return the result
this.seek(pos);
return result;
},

triangles: [‘struct’, ‘uint16’],
properties: [‘struct’, ‘boneIndices’]

Code

The code that powers this is only 30 lines long (70 including the standard integral types). It just handles each possible data type.

parse: function (description, param) {
  var type = typeof description;
 
  // Function
  if (type === 'function') {
    return description.apply(this, [this.param].concat(param));
  }
 
  // Shortcut: 'string' == ['string']
  if (type === 'string') {
    description = [description];
  }
 
  // Array: Function Call
  if (description instanceof Array) {
    return this.parse(this.description[description[0]], description.slice(1));
  }
 
  // Object: Structure
  if (type === 'object') {
    var output = {};
    for (var key in description) {
      if (description.hasOwnProperty(key)) {
        output[key] = this.parse(description[key]);
      }
    }
    return output;
  }
 
  throw new Error('Unknown description type ' + description);
}

// Function
if (type === ‘function’) {
return description.apply(this, [this.param].concat(param));
}

// Shortcut: ‘string’ == [‘string’]
if (type === ‘string’) {
description = [description];
}

// Array: Function Call
if (description instanceof Array) {
return this.parse(this.description[description[0]], description.slice(1));
}

// Object: Structure
if (type === ‘object’) {
var output = {};
for (var key in description) {
if (description.hasOwnProperty(key)) {
output[key] = this.parse(description[key]);
}
}
return output;
}

throw new Error(‘Unknown description type ‘ + description);
}

Conclusion

This little parser is an example of how to extensively use all the dynamic characteristics of Javascript such as Object Literals, Anonymous Functions and Dynamic Typing in order to build a powerful and easy to use tool.

I don’t want to release the library just yet as I need to explore more use cases and find elegant solution for them too. But I hope it will give you inspiration to use full Javascript power.

Demo

You can see it in action in my 0.1% completed Javascript WoW Model Viewer demo. The two following files are important:

During the course “Introduction to Model Checking” by Alexandre Duret-Lutz we’ve been assigned to create a Binary Decision Diagram library. Contrary to most people, I’ve been writing mine in Javascript instead of C++. Overall it is running slower but by an acceptable factor (around x5).

Display

iframe { border: 1px solid #ccc; }

I’ve written a BDD display using the graph library called Dracula which is built on-top of RaphaΓ«lJS. The API of the lib is really neat but there are only 2 available node layout algorithms and none of them really fit my needs. I’d love to have the ones available in GraphViz.

In order to enter a formula, I’ve written a small parser that accepts most common binary operations. The little dice gives you some random formula. Also, on the left, you have all the evaluations that satisfy your formula.

Use Case

Binary Decision Diagram are used in Boolean Satisfiability Problem and Model Checking. As a benchmark example, we use the BDD to solve the 8-Queens problem.

A version using web-workers is available. However, using more than one worker will be slower as the cost of communication (through JSON serialization) is really high (hundreds of thousands nodes). You can also try to use a random ordering for the variables, but beware, the execution time varies a lot (up to x100 for the fastest/slowest)!

Conclusion

It was a really fun project to do. You can view the sources and probably use them as a base if you ever need to use a BDD in your life πŸ˜›

During the last 6 months as part of the LRDE (EPITA Research & Development Lab), I’ve been working on Climb, a Common Lisp image processing library. I’ve written a report and presented it. You can download the slides and report.

Climb – Chaining Operators & Component Trees

Abstract: Climb is a generic image processing library designed to be used for rapid prototyping. The implementation of two component trees algorithms impacts Climb in several ways: the definition of values is extended, new site sets are added and debugging utilities are improved.

A detour is taken to understand the Method Chaining design pattern popularized by the Javascript jQuery library. The pattern is adapted to both the image processing domain and Common Lisp and is extended to introduce a parallel notation as well as better control flows.

Everywhere on the web we read that Javascript has prototypal inheritance. However Javascript only provides by default a specific case of prototypal inheritance with the new operator. Therefore, most of the explanations are really confusing to read. This article aims to clarify what is prototypal inheritance and how to really use it on Javascript.

Prototypal Inheritance Definition

When you read about Javascript prototypal inheritance, you often see a definition like this:

When accessing the properties of an object, JavaScript will traverse the prototype chain upwards until it finds a property with the requested name. Javascript Garden

Most Javascript implementations use __proto__ property to represent the next object in the prototype chain. We will see along this article what is the difference between __proto__ and prototype.

Note: __proto__ is non-standard and should not be used in your code. It is used in the article to explain how Javascript inheritance works.

The following code shows how the Javascript engine retrieves a property (for reading).

function getProperty(obj, prop) {
  if (obj.hasOwnProperty(prop))
    return obj[prop]
 
  else if (obj.__proto__ !== null)
    return getProperty(obj.__proto__, prop)
 
  else
    return undefined
}

else if (obj.__proto__ !== null)
return getProperty(obj.__proto__, prop)

else
return undefined
}

Let’s take the usual class example: a 2D Point. A Point has two coordinates x, y and a method print.

Using the definition of the prototypal inheritance written before, we will make an object Point with three properties: x, y and print. In order to create a new point, we just make a new object with __proto__ set to Point.

var Point = {
  x: 0,
  y: 0,
  print: function () { console.log(this.x, this.y); }
};
 
var p = {x: 10, y: 20, __proto__: Point};
p.print(); // 10 20

var p = {x: 10, y: 20, __proto__: Point};
p.print(); // 10 20

Javascript Weird Prototypal Inheritance

What is confusing is that everyone teaches Javascript prototypal inheritance with this definition but does not give this code. Instead they give something like this:

function Point(x, y) {
  this.x = x;
  this.y = y;
}
Point.prototype = {
  print: function () { console.log(this.x, this.y); }
};
 
var p = new Point(10, 20);
p.print(); // 10 20

var p = new Point(10, 20);
p.print(); // 10 20

This is completely different from the code given above. Point is now a function, we use a prototype property, the new operator. What the hell!?

How new works

Brendan Eich wanted Javascript to look like traditional Object Oriented programming languages such as Java and C++. In those, we use the new operator to make a new instance of a class. So he wrote a new operator for Javascript.

  • C++ has the notion of constructor, that initializes the instance attributes. Therefore, the new operator must target a function.
  • We need to put the methods of the object somewhere. Since we are working on a prototypal language, let’s put it in the prototype property of the function.

The new operator takes a function F and arguments: new F(arguments...). It does three easy steps:

  1. Create the instance of the class. It is an empty object with its __proto__ property set to F.prototype.
  2. Initialize the instance. The function F is called with the arguments passed and this set to be the instance.
  3. Return the instance

Now that we understand what the new operator does, we can implement it in Javascript.

     function New (f) {
/*1*/  var n = { '__proto__': f.prototype };
       return function () {
/*2*/    f.apply(n, arguments);
/*3*/    return n;
       };
     }

And just a small test to see that it works.

function Point(x, y) {
  this.x = x;
  this.y = y;
}
Point.prototype = {
  print: function () { console.log(this.x, this.y); }
};
 
var p1 = new Point(10, 20);
p1.print(); // 10 20
console.log(p1 instanceof Point); // true
 
var p2 = New (Point)(10, 20);
p2.print(); // 10 20
console.log(p2 instanceof Point); // true

var p1 = new Point(10, 20);
p1.print(); // 10 20
console.log(p1 instanceof Point); // true

var p2 = New (Point)(10, 20);
p2.print(); // 10 20
console.log(p2 instanceof Point); // true

Real Prototypal Inheritance in Javascript

The Javascript specifications only gives us the new operator to work with. However, Douglas Crockford found a way to exploit the new operator to do real Prototypal Inheritance! He wrote the Object.create function.

Object.create = function (parent) {
  function F() {}
  F.prototype = parent;
  return new F();
};

This looks really strange but what it does is really simple. It just creates a new object with its prototype set to whatever you want. It could be written as this if we allow the use of __proto__:

Object.create = function (parent) {
  return { '__proto__': parent };
};

The following code is our Point example with the use of real prototypal inheritance.

var Point = {
  x: 0,
  y: 0,
  print: function () { console.log(this.x, this.y); }
};
 
var p = Object.create(Point);
p.x = 10;
p.y = 20;
p.print(); // 10 20

var p = Object.create(Point);
p.x = 10;
p.y = 20;
p.print(); // 10 20

Conclusion

We have seen what prototypal inheritance is and how Javascript implements only a specific way to do it.

However, the use of real prototypal inheritance (Object.create and __proto__) has some downsides:

  • Not standard: __proto__ is non-standard and even deprecated. Also native Object.create and Douglas Crockford implementation are not exactly equivalent.
  • Not optimized: Object.create (native or custom) has not yet been as heavily optimized as the new construction. It can be up to 10 times slower.

Some further reading:

Bonus

If you can understand with this picture (from the ECMAScript standard) how Prototypal Inheritance works, you get a free cookie!