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

Manipulating Object Behavior at Runtime

Manipulating Object Behavior at Runtime

I had the idea of a component based system with dynamic behavior for a long time. In this talk I show one approach in solving this problem, with a focus on ECMAScript 6 new features.

Andrei Ursan

June 20, 2013
Tweet

More Decks by Andrei Ursan

Other Decks in Programming

Transcript

  1. Motivation • Wanting to write DRY code ◦ Very DRY

    Code Source code metrics RR#041, James’ example from Code Climate
  2. Motivation • Wanting to write DRY code ◦ Very DRY

    Code Source code metrics RR#041, James’ example from Code Climate
  3. Don't Repeat Yourself Principle "DRY says that every piece of

    system knowledge should have one authoritative, unambiguous representation. Every piece of knowledge in the development of something should have a single representation. A system's knowledge is far broader than just its code. It refers to database schemas, test plans, the build system, even documentation." DRY => SOLID => Design Patterns Source Orthogonality and the DRY Principle, Don't repeat yourself
  4. Don't Repeat Yourself Principle "DRY says that every piece of

    system knowledge should have one authoritative, unambiguous representation. Every piece of knowledge in the development of something should have a single representation. A system's knowledge is far broader than just its code. It refers to database schemas, test plans, the build system, even documentation." DRY => SOLID => Design Patterns Source Orthogonality and the DRY Principle, Don't repeat yourself
  5. Problem Domain Game Engines, Game Editors, Widget Systems, CMSs, Interactive

    Systems. (order does not imply anything) Problem As a content creator, I want to be able to create Custom Entities in order to satisfy new use cases. Desired Features Ability to add/remove behavior of an component/entity without changing the implementation.
  6. Component Carcass CC + View View + Movement View +

    Movement + Player var asteroid = new ComponentCarcass(); Component Carcass addComponent removeComponent handleMessage Message TRAP
  7. Component Carcass CC + View View + Movement View +

    Movement + Player var asteroid = new ComponentCarcass(); asteroid.addComponent(new View(x=50, y=60)); asteroid.x // 50 Component Carcass addComponent removeComponent handleMessage Message TRAP
  8. Component Carcass CC + View View + Movement View +

    Movement + Player var asteroid = new ComponentCarcass(); asteroid.addComponent(new View(x, y)); asteroid.addComponent(new Movement()); Component Carcass addComponent removeComponent handleMessage Message TRAP
  9. Handling Dependencies Component Carcass addComponent removeComponent handleMessage Message TRAP when

    you add a component to the Carcass. You set the component delegate property to self (the carcass self)
  10. Handling Dependencies Component Carcass addComponent removeComponent handleMessage Message TRAP messages

    from the component to the delegate are going to be Trapped by the component carcass and handle like any other message.
  11. Handling Messages Component Carcass addComponent removeComponent handleMessage Message TRAP handleMessage

    will check which component from the "array of components" knows how to respond to the trapped message. It will forward the message to the correct component and return the response
  12. Component Carcass CC + View View + Movement View +

    Movement + Player var asteroid = new ComponentCarcass(); asteroid.addComponent(new View(x, y)); asteroid.addComponent(new Movement()); asteroid.addComponent(new Player()); Component Carcass addComponent removeComponent handleMessage Message TRAP
  13. Who Does This? Unity3D Crafty.js many others //Paddles Crafty.e("Paddle, 2D,

    DOM, Color, Multiway") .color('rgb(255,0,0)') .attr({ x: 20, y: 100, w: 10, h: 100 }) .multiway(4, { W: -90, S: 90 }); Crafty has a "Component Builders" community. Source Crafty Github, Crafty Components
  14. How to do it in JavaScript Traits.js Define Prototype Proxy

    function makeColorTrait(col) { return Trait({ color: function() { return col; } });} function makePoint(x, y) { return Trait.create(Object.prototype, Trait.compose( makeColorTrait('red'), Trait({ getX: function() { return x; }, getY: function() { return y; }, toString: function() { return ''+x+'@'+y; } }))); } var p = makePoint(0,2); p.color() // 'red' Source Traits.js
  15. How to do it in JavaScript Traits.js Define Prototype Proxy

    A new feature in ECMAScript 6. Flexible and expressive metaprogramming system which is also securable.
  16. Proxy var proxyObj = Proxy.create({ get: function(obj, name) { return

    'Hello, '+ name; }, set: function(obj, name, value) { var log = "Property " + name + " doesn't like value " + value; console.log(log); return true; } }); proxyObj > "TypeError" proxyObj.baz > Hello, baz proxyObj.foo = -3 > Property foo doesn't like value -3
  17. Proxy var Stack = (function(){ var stack = [], allowed

    = [ "push", "pop", "length" ]; return Proxy.create({ get: function(receiver, name){ if (allowed.indexOf(name) > -1){ if(typeof stack[name] == "function"){ return stack[name].bind(stack); } else { return stack[name]; } } else { return undefined; } } }); }); var mystack = new Stack(); mystack.push("hi"); mystack.push("goodbye"); console.log(mystack.length); // 2 console.log(mystack[0]); // undefined console.log(mystack.pop()); // "goodbye" Source nczonline.net
  18. Resources 1. [API] The new Proxy API (draft) 2. [MDN]

    Old Proxy API 3. Traits: Composable Units of Behavior 4. Delegation - The White Paper[Google Tech Talk] 5. Changes to ECMAScript - Proxies and Traits 6. Brendan Eich - Proxies are Awesome!