/js/controller/traits/BaseTrait.js

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