Skip to content

Instantly share code, notes, and snippets.

@egonelbre
Created December 29, 2012 15:23
Show Gist options
  • Save egonelbre/4407520 to your computer and use it in GitHub Desktop.
Save egonelbre/4407520 to your computer and use it in GitHub Desktop.
Battle = Context(function(bearPlayer, lionPlayer){
Bear = bearPlayer;
Lion = lionPlayer;
Bear.fight();
Lion.touch();
Lion.fight();
},{
Lion : {
fight : function(){
console.log(this.name + " : meow");
},
touch : function(){
Lion.fight();
Bear.fight();
}
},
Bear : {
fight : function(){
console.log(this.name + " : grrr");
}
}
});
var player = {name:"player"};
var cpu = {name:"cpu"};
var b = Battle(player, cpu);
function Context(init, roles) {
// closure for scoping things
var sfn = "(function(){\n";
// scoped role players
sfn += " var " + Object.keys(roles).join(",") + ";\n";
// creates the function
var mkName = function(role, fn){ return role + "$" + fn; };
// redirects all role method calls
var fixMethod = function(fn){
fn = fn.toString();
for(var roleName in roles){
var role = roles[roleName];
for(var fnName in role){
// replaces Role.method(arg1,arg2,arg3) with
// with Role$method.call(Role, arg1, arg2, arg3)
var rx = new RegExp( "([^.])" + roleName + "\\." + fnName + "\\(", "g");
fn = fn.replace(rx, "$1" + mkName(roleName, fnName) + ".call(" + roleName + ",");
// hack-fix Role$method.call(Arg,)
fn = fn.replace(",)", ")");
}
}
return fn;
};
// define role methods in to the context
var methods = [];
for(var roleName in roles){
var role = roles[roleName];
for(var fnName in role){
methods.push(mkName(roleName, fnName) + " = " + fixMethod(role[fnName]));
}
}
sfn += "var " + methods.join(",\n") + ";\n";
// return the init
sfn += "return " + fixMethod(init) + ";})()";
return eval(sfn);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment