PageRenderTime 77ms CodeModel.GetById 35ms app.highlight 4ms RepoModel.GetById 36ms app.codeStats 0ms

/js/controller/traits/BaseTrait.js

http://github.com/onedayitwillmake/RealtimeMultiplayerNodeJs
JavaScript | 127 lines | 45 code | 11 blank | 71 comment | 1 complexity | c34d2e880984522bf71a9463e9ddeb23 MD5 | raw file
  1/**
  2 File:
  3 BaseTrait.js
  4 Created By:
  5 Mario Gonzalez
  6 Project    :
  7 RealtimeMultiplayerNodeJS
  8 Abstract:
  9 Traits work by effectively 'hi-jacking' properties of their attachedEntity.
 10 These properties can by functions, or non-primitive data types.
 11
 12 Instead of creating a new trivial subclass, considering creating a trait and attaching it to that object
 13
 14 For example to make an entity invincible for a period of time you might make a trait like this
 15
 16 [PSUEDO CODE START]
 17 // Inside a trait subclass
 18 attach: function(anEntity)
 19 {
 20     this.callSuper();
 21     this.intercept(['onHit', 'getShotPower']);
 22 },
 23
 24 onHit: function() {
 25 		// Do nothing, im invincible!
 26 	},
 27
 28 getShotStrength: function() {
 29 		return 100000000; // OMGBBQ! Thats high!
 30 	}
 31 [PSUEDO CODE END]
 32
 33 Be sure to call restore before detaching the trait!
 34
 35 Basic Usage:
 36
 37 // Let my character be controlled by the KB
 38 if(newEntity.connectionID === this.netChannel.connectionID) {
 39		aCharacter.addTraitAndExecute( new ClientControlledTrait() );
 40		this.clientCharacter = aCharacter;
 41	}
 42 */
 43(function () {
 44    RealtimeMultiplayerGame.namespace("RealtimeMultiplayerGame.controller.traits");
 45
 46    RealtimeMultiplayerGame.controller.traits.BaseTrait = function () {
 47        this.interceptedProperties = new SortedLookupTable();
 48        return this;
 49    };
 50
 51    RealtimeMultiplayerGame.controller.traits.BaseTrait.prototype = {
 52        interceptedProperties: null,  					// SortedLookupTable of traits we've intercepted so they can be applied back
 53        attachedEntity: null,						// Trait host
 54        detachTimeout: 0,						// Store detach setTimeout
 55        displayName: "BaseTrait",				// Unique string name for this Trait
 56
 57        // If a trait can stack, then it doesn't matter if it's already attached.
 58        // If it cannot stack, it is not applied if it's currently active.
 59        // For example, you can not be frozen after being frozen.
 60        // However you can be sped up multiple times
 61        canStack: false,
 62
 63        /**
 64         * Attach the trait to the host object
 65         * @param anEntity
 66         */
 67        attach: function (anEntity) {
 68            this.attachedEntity = anEntity;
 69        },
 70
 71        /**
 72         * Execute the trait
 73         * For example if you needed to cause an animation to start when a character is 'unfrozen', this is when you would do it
 74         */
 75        execute: function () {
 76
 77        },
 78
 79        /**
 80         * Detaches a trait from an 'attachedEntity' and restores the properties
 81         */
 82        detach: function (force) {
 83            clearTimeout(this.detachTimeout);
 84            this.restore();
 85
 86            this.interceptedProperties.dealloc();
 87            this.interceptProperties = null;
 88            this.attachedEntity = null;
 89        },
 90
 91        /**
 92         * Detach after N milliseconds, for example freeze trait might call this to unfreeze
 93         * @param aDelay
 94         */
 95        detachAfterDelay: function (aDelay) {
 96            var that = this;
 97            this.detachTimeout = setTimeout(function () {
 98                that.attachedEntity.removeTraitWithName(that.displayName);
 99            }, aDelay);
100        },
101
102        /**
103         * Intercept properties from the entity we are attached to.
104         * For example, if we intercept handleInput, then our own 'handleInput' function gets called.
105         * We can reset all the properties by calling, this.restore();
106         * @param arrayOfProperties
107         */
108        intercept: function (arrayOfProperties) {
109            var len = arrayOfProperties.length;
110            while (len--) {
111                var aKey = arrayOfProperties[len];
112                this.interceptedProperties.setObjectForKey(this.attachedEntity[aKey], aKey);
113                this.attachedEntity[aKey] = this[aKey];
114            }
115        },
116
117        /**
118         * Restores traits that were intercepted.
119         * Be sure to call this when removing the trait!
120         */
121        restore: function () {
122            this.interceptedProperties.forEach(function (key, aStoredProperty) {
123                this.attachedEntity[key] = aStoredProperty;
124            }, this);
125        }
126    }
127})();