Monday, March 26, 2012

pushing boundaries in ui, and why

A friend, Jeremy Penner of Glorious Trainwrecks semi-fame, pointed me to this video:



Bret Victor - Inventing on Principle from CUSEC on Vimeo.

That's some amazing UI thought right there. I love how laying out animations can me more like puppeteering if you do it right... and the rest is completely inspiring as well.

Random plug: to get the embeded code the size I wanted it I used my old Youtube Resizer -- it needs a better name, since A. it works on things other than youtube (like Vimeo here) and B. Youtube has put the same functionality into their basic "embed this" webpage, but still, the thing works pretty well.

Thursday, March 22, 2012

wmode and putting flash in its place

Just a note for my future self: that whole "flash appearing in front of other content on the page thing" fix (otherwise flash weirdly, stupidly, appears in front of other content on the page, z-index wise) is setting wmode to opaque:
 <param name="wmode" value="opaque"/>
One reference for that at stackoverflow. I've dealt with this before, right now I'm most annoyed at how Confluence's pdf viewer app doesn't do that and it would be some jar-ish hacking to get it to work so that the PDF viewer didn't block the zoomed in images. Bleh!

Monday, March 19, 2012

a more interesting news ticker

So it's been a little while since I've done a live demo here.

The other week on some website or other -- it might have a Sky-affiliated site? -- I saw a little news ticker that caught my attention. I created a simple mockup of its main action here-- go ahead and hit "ticker it"...

Now I've seen plenty of newstickers, even scrolling ones, but this was a little different: rather than being a simple thing that always scrolls, it starts at the left and builds to the right, only scrolling enough to keep the right edge visible, and the stopping the scroll. It ain't rocket science, but I find it a more natural way of reading than a traditional ticker... the user gets less impatient as the text builds in a more "normal" fashion, but still the animation makes it more engaging than a simple static headline (even one in those garish colors-- I believe yellow and black combo is thought to be the highest and most attention grabbing possible.) The construction invites the user to just keep looking, and builds a bit of suspense with what word comes next.

 You can see my rendition of this on a standalone page, and view the source thereof, but there isn't that much to it, just some simple nested divs with hidden overflow and then some setTimeout javascript to adjust the relative positioning when jQuery's "width()" function indicates things are too long.

Thursday, March 15, 2012

many endpoints, one function: it all depends on what this meaning of "this" is

So as a follow up to today's post, I made a new feature for our site: the MultiDataGrabber.

There are two ugly Patterns I've seen when you need to build a page but there's an ordering dependency that requires information from 2 or more endpoints to be acted on: personally I'm guilty of making long, ugly function chains, storing data as we go, and then the final link in the chain does all the work. The other anti-pattern is to have a single function with 2 synchronous function, so the data can be returned. That's easy to read but causes the site to stall as the synchronous call completes.

I suggested a third ugly pattern: call the 2 endpoints asynchronously, and have each callback store its data in the parent object and check if the other callback has done likewise; if not, return, if so, call the function that uses the data. But at work Ben suggested this could be generalized: it would be nice if we could specify multiple AJAX URLs and then have a function that is called when they have all completed.

Thus, the MultiDataGrabber was born. It's called like this:

var mdg = new MultiDataGrabber(["/rest/user/location",
"/rest/ecommerce/account",
"/rest/user/style"], allDone);



function allDone(ress){
ccdebug("res 0:"+inspect(ress[0]));
ccdebug("res 1:"+inspect(ress[1]));
ccdebug("res 2:"+inspect(ress[2]));
}


Pretty easy, huh? Ben also mentioned if you were having to do too much of this (rather than, say, be able to build a page in parallel) it might mean you had a mismatch between what the endpoints were returning and the function of the page, so you might ask for a refactoring of the former.

The implementation is short, and has a point I want to discuss, so here it is:
function MultiDataGrabber(urls,callback) {
this._countNeeded = urls.length;
this._countHave = 0;
this._finalCallback = callback;
this.ress = [];
//go through each url, make a helper object to store the context
for(var i = 0; i < this._countNeeded; i++){
var url = urls[i];
var helper = new MultiDataGrabber_helper(i,url,this);
global_databroker.getJson(url,CreateDelegate(helper,function(res){ 
this.funk(res);
/*weird(this)*/
}));
helper = undefined;
}
this._myCallback = function(spot, res){
this.ress[spot] = res;
this._countHave++;
if(this._countHave >= this._countNeeded){
this._finalCallback(this.ress);
}
}
}

function MultiDataGrabber_helper(pid,purl,pmdg){
this.id = pid;
this.url = purl;
this.mdg = pmdg;
this.funk = function(res){
this.mdg._myCallback(this.id,res);
}
}

/*

function weird(what){

ccdebug(what);

ccdebug(this);
}
*/
So this code looks pretty obvious... as I read through it I think "aha, OF COURSE I have to make a helper object to store the state during the callback, and OF COURSE it needs a CreateDelegate so the scope doesn't get stomped" but when I was writing it I ran into enough dead ends that (as I've admitted before) I had to acknowledge I am not 100% fluent in Javascript Scoping rules. And I left a fossil of that with the commented-out "weird" function. The function is passed a variable "what", and prints out that, and then it prints out "this".  When the code is run, it first prints the MultiDataGrabber_helper (since it has the CreateDelegate saying that that is the scope), and then prints the window object. But that seems odd to my Java-addled brain, because at invocation the weird() function was passed "this"... but it was a different "this" then you get when you're in the function itself.

Sometimes it alarms me that you can do so much in JavaScript without having this stuff down cold. If I had the same klutziness with Java classes, I'd never get anything done! (On the other hand, I had a cold bath awakening to Java's anonymous function callbacks when I had to use the "Wicket" framework. Apparently they are very familiar to people who used AWT and Swing and what not back in the day, and now I'm very comfortable with them, but then they seemed really ugly and strange.)


UPDATE: I made a Google Docs Presentation for a Boston jQuery meetup's 5 minute talk on this.


UPDATE TO THE UPDATE: At the meetup, Ben "Cowboy" Alman pointed out that functionality along these same lines was added to jQuery 1.5: they're called "deferreds", and defer (ha) to Eric Hynds' explanation of them. To be fair, I'm not sure if it would be easy to utilize them with the plumbing my company uses for AJAX (i.e. the databroker caching and the way we listen in to the traffic to know if we should stop polling for notifications) so I don't feel too too bad, but still it's nice to add this knowledge to my repertoire. 

break the data: pump_databroker

Today I'm going to show a simple model for caching endpoint data (with an optional pubsub system for later in-page updates), a "databroker", so that a single page doesn't have to make multiple calls to the same endpoint.

This is one of those ideas where I think: maybe someone coded a better implementation of this idea, and I should embrace it and renounce my "NIH: Not Invented Here" ways. (Like the way I was using a basterdized version of cgi-lite.pl for CGI parsing in my Perl script long after better alternatives like CGI-lite.pm were around) On the other hand, this implementation has pretty good visibility, a minimum number of "moving parts", and is nicely scoped down to the problems at hand.

At work, we were already doing a good job of using wrapper functions for jQuery's ajax calls, jsonGet and jsonGetSynch (for that nasty synchronous stuff). The main thing these functions did, besides simplifying the syntax, was enable a "keep alive" function, so that we could keep polling for notifications, but then stop polling after a given interval (so that the user's session wouldn't live forever as long as they had the page open). So one design criteria was that the databroker 

So what does our databroker do? It stores the responses from ajax calls in an hashmap, keyed by the endpoint URL. (Furthermore, it automatically adds a timestamp to the requests to avoid caching issues) If a request for a URL comes in and the databroker has a cached response, the response is returned immediately, rather than making another call. Furthermore, if a pile of requests to a (possibly slow/long-running) URL come in at once, only one actual call is made, and then all the callbacks get called, passed the same cached data.

Furthermore, there's an optional "pubsub" publish/subscribe model. A request can specify a channel/tag it wants to "subscribe" to, and then when other operations update related data they can call "refresh" on that tag, and the subscribed callbacks are called with fresh data from the server

The implementation is here. It creates a global variable global_databroker. The syntax for the call is global_databroker.getJson(url, callback, errcallback ,tag].  Errcallback and tag are optional. There's also a getJsonSynch for synchronous calls, and that refresh() call. (I think the behavior might be a bit off for the errcallback relative to the pubsub system)

Because I am a bad person I did not write unit tests. I did write a test script, but since I haven't yet instrumented the calls, it relies on using firebug or the like to see when calls are made, and "ccdebug" in it prints to the console.

<script>
$(document).ready(
function(){
 global_databroker.getJson("/rest/user/profile",function(res){
ccdebug("call profile 0 sub");
 },ccdebug(),"sub");
 global_databroker.getJson("/rest/ecommerce/account",function(res){
ccdebug("call ecommerce 1 sub");
 },undefined,"sub");
global_databroker.getJson("/rest/ecommerce/account",function(res){
ccdebug("call ecommerce 2 nosub");
 });
}
);
function FORE(){
global_databroker.getJson("/rest/ecommerce/account",function(res){ ccdebug("call ecommerce 3 sub");},undefined,"sub");
}
</script>
<input type="button" value="refresh sub" onClick="global_databroker.refresh('sub')">
<input type="button" value="do ecommerce 3 with sub" onClick='FORE();'>
In the page I embedded these comments:
<pre>
So in firebug, you should see:
in "ready" 3 requests, with 2 to ecommerce account queued as one

0 and 1 subscribe w/ keyword "sub", so clicking "refresh sub" 
calls the calls to be repeated, and 0 and 1 get called back

click "do ecommerce 3 with sub" -- you see it immediately gets the info 
without another call to the server

then if you hit refresh sub, 0 1 and 3 all get called back
</pre>
That's that! I think it works pretty well, and the implementation is reasonably compact. 


(In the scheme I cribbed this from, the developer thought it would be good to automagically use the rest URL as the tag. (i.e. maybe just have a simple getJsonSubscribe() call). This would be especially cool if there was a 1:1 mapping between GET and POST URLs-- then anything you saw POST information could call any subscriber! In practice, though there isn't that 1:1 map. Not only that, there's often a disconnect where a  POST Url ends up changing data retrieved by a totally different GET. That's why I like a generic tag system to decouple the input and the output to the server.)


Comments welcome. 

Wednesday, March 7, 2012

the pirate kart

I do have a real post pending (need to figure something out with jsfiddle) but meanwhile I'd like to talk about the 2012-in-one Glorious Developers Konference Kollection Pirate Kart. It has its ultimate origin on a place called Glorious Trainwrecks, a site launched to praise terrible 90s homebrew shareware but now dedicated to the proposition that every can make games, and should.

The Pirate Kart of course shares that sensibility. The most recent Kart had been assembled for the Indie Games Festival Main Competition. Then there was a bit of a... political? motivation? It was meant as a playful argument against the "scenesterism" that sometimes haunts "Indie Games" as a movement.

The Glorious Trainwrecks has always had a spirit of openness, though originally there was an emphasis on use of a particularly peculiar no-programming game construction kit called "Klik and Play" (which is why Ks show up a lot on the site and its offshoots, a trend that as a guy named Kirk I kan only applaud) which let people whip together a game in the 2-hour Klik of the Month Klub events.

Personally, I tend to program in Processing (sometimes making Processing.js variants) which has the added benefit of keeping my Java skills from completely rusting. But more than that, making silly, 2-hour-game prototypes has given me a deeper sense of easy-to-code-but-juicy physics that really helps me make more intriguing and attractive UIs.

Anyway, here are my 5 games! Click to play them online and get some more details about the background story.

shave face race

robotish

dinobeeboxer


hit or missile

action figure fighter

Of all of these, "action figure fighter" is probably my favorite, "robotish" is the best from a game-playing standpoint, and "dinobeeboxer" is just weird and cool.