Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Livecoding in Javascript

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

Livecoding in Javascript

Avatar for Jason Frame

Jason Frame

May 09, 2013
Tweet

More Decks by Jason Frame

Other Decks in Programming

Transcript

  1. Microworlds Paper - “Twenty Reasons Why You Should Use Boxer

    (Instead of Logo)” Andrea A. diSessa Friday, 31 May 13
  2. Why Javascript? • Flexible language • Ecosystem - browser +

    node.js = node- webkit • Single threaded • Event loop Friday, 31 May 13
  3. Why Javascript? Describing Live programming using program transformations and a

    callstack explicit interpreter Olov Johansson Friday, 31 May 13
  4. Domain-Specific Livecoding • Generalised tools can be complex • May

    also make unacceptable performance/ timing trade-offs • Evolve tools with your application Friday, 31 May 13
  5. Implementation Strategies • Private State • Variable Injection • “Globals”

    Preservation • Internal eval() • Blueprints • Snapshot • Clocksources Friday, 31 May 13
  6. Private State function setup() { position = {x: 10, y:

    20}; velocity = {x: 1, y: 1}; } function loop() { position.x += velocity.x; position.y += velocity.y; } Friday, 31 May 13
  7. Private State (function() { “use strict”; var position; var velocity;

    function setup() { position = {x: 10, y: 20}; velocity = {x: 1, y: 1}; } function loop() { position.x += velocity.x; position.y += velocity.y; } })(); Friday, 31 May 13
  8. Private State (function() { “use strict”; var position; var velocity;

    function setup() { position = {x: 10, y: 20}; velocity = {x: 1, y: 1}; } function loop() { position.x += velocity.x; position.y += velocity.y; } return { setup: setup, loop: loop }; })(); Friday, 31 May 13
  9. Variable Injection // Generate method signature from defined // objects

    (function(car, trafficLights, background) { // Paste user code here function loop() { car.drawAt(0,0,50,50) } // ... // ... // ... }).apply(null, exposedObjects); Friday, 31 May 13
  10. “Globals” Preservation var carX = 0; var carY = 0;

    var speed = 5; function loop() { carY += speed; draw(); } Friday, 31 May 13
  11. “Globals” Preservation var carX = 0; var carY = 0;

    var speed = 5; function loop() { carY += speed; draw(); } Friday, 31 May 13
  12. “Globals” Preservation (function() { "use strict"; var carX = 0;

    var carY = 0; var speed = 5; function loop() { carY += speed; draw(); } return { loop: loop, getVars: function() { return {carX: carX, carY: carY, speed: speed}; }, setVars: function(vars) { carX = vars.carX; carY = vars.carY; speed = vars.speed; } }; })(); Friday, 31 May 13
  13. Internal eval() var car = {x: 20, y: 20} var

    lightState = “red-amber” function setup() { // ... } function loop() { // ... } Friday, 31 May 13
  14. Internal eval() (function() { "use strict"; var car = {x:

    20, y: 20} var lightState = “red-amber” function setup() { // ... } function loop() { // ... } })(); Friday, 31 May 13
  15. Internal eval() (function() { "use strict"; var car = {x:

    20, y: 20} var lightState = “red-amber” function setup() { // ... } function loop() { // ... } function evaluate(code) { return eval(code); } return { __eval__: evaluate } })(); Friday, 31 May 13
  16. Blueprints // Inside engine var blueprint = new SystemBlueprint(); blueprint.id

    = oldSystem.id; blueprint.enabled = oldSystem.enabled; blueprint.update = function() { /* default impl */ } USERCODE = ‘(function(system) { // augment blueprint system.title = “foo”; system.update = function() { ... } })’; // Compile code systemBuilder = eval(USERCODE); systemBuilder(blueprint); // inspect user’s refinements to blueprint and // setup accordingly Friday, 31 May 13
  17. Snapshots system.snapshot = function() { return { entities: Object.keys(this.entities), lastShotTime:

    this.lastShotTime } } system.restore = function(snapshot) { var self = this; this.entities = {}; snapshot.entities.forEach(function(eid) { self.entities[eid] = self.world.getEntityById(eid); } this.lastShotTime = snapshot.lastShotTime; } Friday, 31 May 13
  18. Snapshots function updateSystem(registry, systemId, newSystem) { var existingSystem = registry.getSystemById(systemId);

    var snapshot = existingSystem.snapshot(); try { newSystem.restore(snapshot); registry.setSystem(systemId, newSystem); } catch (e) { // Incompatible snapshot - restart app? } } Friday, 31 May 13
  19. Clocksources Date.now() function Clock() { this.time = 0; this.lastDelta =

    null; } Clock.prototype.tick = function(delta) { this.time += delta; this.lastDelta = delta; } function tick() { var wallclockDelta = Date.now() - lastTick; clock.tick(wallclockDelta); } Friday, 31 May 13