generateCreateBody.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. const createPatternBuilder = require('./createPatternBuilder');
  2. module.exports = generateCreateBodyFunction;
  3. module.exports.generateCreateBodyFunctionBody = generateCreateBodyFunctionBody;
  4. // InlineTransform: getVectorCode
  5. module.exports.getVectorCode = getVectorCode;
  6. // InlineTransform: getBodyCode
  7. module.exports.getBodyCode = getBodyCode;
  8. // InlineTransformExport: module.exports = function() { return Body; }
  9. function generateCreateBodyFunction(dimension, debugSetters) {
  10. let code = generateCreateBodyFunctionBody(dimension, debugSetters);
  11. let {Body} = (new Function(code))();
  12. return Body;
  13. }
  14. function generateCreateBodyFunctionBody(dimension, debugSetters) {
  15. let code = `
  16. ${getVectorCode(dimension, debugSetters)}
  17. ${getBodyCode(dimension, debugSetters)}
  18. return {Body: Body, Vector: Vector};
  19. `;
  20. return code;
  21. }
  22. function getBodyCode(dimension) {
  23. let pattern = createPatternBuilder(dimension);
  24. let variableList = pattern('{var}', {join: ', '});
  25. return `
  26. function Body(${variableList}) {
  27. this.isPinned = false;
  28. this.pos = new Vector(${variableList});
  29. this.force = new Vector();
  30. this.velocity = new Vector();
  31. this.mass = 1;
  32. this.springCount = 0;
  33. this.springLength = 0;
  34. }
  35. Body.prototype.reset = function() {
  36. this.force.reset();
  37. this.springCount = 0;
  38. this.springLength = 0;
  39. }
  40. Body.prototype.setPosition = function (${variableList}) {
  41. ${pattern('this.pos.{var} = {var} || 0;', {indent: 2})}
  42. };`;
  43. }
  44. function getVectorCode(dimension, debugSetters) {
  45. let pattern = createPatternBuilder(dimension);
  46. let setters = '';
  47. if (debugSetters) {
  48. setters = `${pattern("\n\
  49. var v{var};\n\
  50. Object.defineProperty(this, '{var}', {\n\
  51. set: function(v) { \n\
  52. if (!Number.isFinite(v)) throw new Error('Cannot set non-numbers to {var}');\n\
  53. v{var} = v; \n\
  54. },\n\
  55. get: function() { return v{var}; }\n\
  56. });")}`;
  57. }
  58. let variableList = pattern('{var}', {join: ', '});
  59. return `function Vector(${variableList}) {
  60. ${setters}
  61. if (typeof arguments[0] === 'object') {
  62. // could be another vector
  63. let v = arguments[0];
  64. ${pattern('if (!Number.isFinite(v.{var})) throw new Error("Expected value is not a finite number at Vector constructor ({var})");', {indent: 4})}
  65. ${pattern('this.{var} = v.{var};', {indent: 4})}
  66. } else {
  67. ${pattern('this.{var} = typeof {var} === "number" ? {var} : 0;', {indent: 4})}
  68. }
  69. }
  70. Vector.prototype.reset = function () {
  71. ${pattern('this.{var} = ', {join: ''})}0;
  72. };`;
  73. }