Advertisement
lignite0

ROBO24 - typeRegistry

Nov 15th, 2019
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const createConstructor = function () {
  2.     return function (options) {
  3.         Object.assign(this, options);
  4.     };
  5. };
  6.  
  7. const typedArrays = {
  8.     "Int8Array": Int8Array,
  9.     "Uint8Array": Uint8Array,
  10.     "Uint8ClampedArray": Uint8ClampedArray,
  11.     "Int16Array": Int16Array,
  12.     "Uint16Array": Uint16Array,
  13.     "Int32Array": Int32Array,
  14.     "Uint32Array": Uint32Array,
  15.     "Float32Array": Float32Array,
  16.     "Float64Array": Float64Array,
  17. };
  18.  
  19. const encodeGeneric = function (dataView, instance) {
  20.     const value = instance[this.propertyName];
  21.     if (!value instanceof this.arrayType) {
  22.         throw new Error(
  23.             `Cannot encode property named (${this.propertyName}) is not (${this.arrayType.name}) type`
  24.         );
  25.     }
  26.  
  27.     const typedArrayLength = value.length;
  28.     for (let i = 0; i < typedArrayLength; i++) {
  29.         this.dataViewSetter.call(dataView, this.byteOffset + (this.axisByteLength * i), value[i], true);
  30.     }
  31. };
  32.  
  33. const decodeGeneric = function (dataView, instance) {
  34.     const start = dataView.byteOffset + this.byteOffset;
  35.     const end = start + this.byteLength;
  36.     const arrayBufferFragment = dataView.buffer.slice(start, end);
  37.     const arrayTypeConstructor = this.arrayType;
  38.     const arrayType = new arrayTypeConstructor(arrayBufferFragment);
  39.     instance[this.propertyName] = arrayType;
  40. };
  41.  
  42. const decodeStatic = function (dataView, instance) {
  43.     const value = this.dataViewGetter.call(dataView, this.byteOffset, true);
  44.     instance[this.propertyName] = value;
  45. };
  46.  
  47. const encodeStatic = function (dataView, instance) {
  48.     const value = instance[this.propertyName];
  49.     return this.dataViewSetter.call(dataView, this.byteOffset, value, true);
  50. };
  51.  
  52. const getByteLength = function () {
  53.     return this.byteLength;
  54. };
  55.  
  56. const binaryTypeRegistry = new class TypeRegistry {
  57.  
  58.     constructor() {
  59.         this.types = {};
  60.         this.staticTypes = {};
  61.         this.createStaticTypes();
  62.         this.createVectorTypes();
  63.         this.createMatrixTypes();
  64.     }
  65.  
  66.     createStaticTypes() {
  67.         for (let power of [0, 1, 2, 3]) {
  68.             this.createStaticType("s", power, "Int");
  69.             this.createStaticType("u", power, "Uint");
  70.         }
  71.         for (let power of [2, 3]) {
  72.             this.createStaticType("f", power, "Float");
  73.         }
  74.     }
  75.  
  76.     createStaticType(char, power, mapped) {
  77.         const byteLength = 2 ** power;
  78.         const bitSize = byteLength * 8;
  79.         const typeName = `${char}${bitSize}`;
  80.         const dataViewType = `${mapped}${bitSize}`;
  81.  
  82.         const constructor = createConstructor();
  83.         const {prototype} = constructor;
  84.  
  85.         Object.defineProperty(prototype, 'typeName', {value: typeName});
  86.         Object.defineProperty(prototype, 'byteLength', {value: byteLength});
  87.  
  88.         Object.defineProperty(prototype, 'arrayType', {value: typedArrays[`${mapped}${bitSize}Array`]});
  89.         Object.defineProperty(prototype, 'dataViewGetter', {value: DataView.prototype[`get${dataViewType}`]});
  90.         Object.defineProperty(prototype, 'dataViewSetter', {value: DataView.prototype[`set${dataViewType}`]});
  91.  
  92.         prototype.encode = encodeStatic;
  93.         prototype.decode = decodeStatic;
  94.         prototype.getByteLength = getByteLength;
  95.  
  96.         this.staticTypes[typeName] = constructor;
  97.         this.types[typeName] = constructor;
  98.     }
  99.  
  100.     createVectorTypes() {
  101.         for (let vectorWidth = 2; vectorWidth <= 4; vectorWidth++) {
  102.             for (let staticType of Object.values(this.staticTypes)) {
  103.                 this.createGenericType('vec', vectorWidth, vectorWidth, staticType)
  104.             }
  105.         }
  106.     }
  107.  
  108.     createMatrixTypes() {
  109.         for (let matrixWidth = 2; matrixWidth <= 4; matrixWidth++) {
  110.             for (let staticType of Object.values(this.staticTypes)) {
  111.                 this.createGenericType("mat", matrixWidth, matrixWidth ** 2, staticType)
  112.             }
  113.         }
  114.     }
  115.  
  116.     createGenericType(prefix, width, axisLength, staticType) {
  117.         const {typeName: staticTypeName, byteLength: staticByteLength} = staticType.prototype;
  118.         const genericTypeName = `${prefix}${width}<${staticTypeName}>`;
  119.         const genericByteLength = axisLength * staticByteLength;
  120.  
  121.         const constructor = createConstructor();
  122.         const {prototype} = constructor;
  123.  
  124.         Object.defineProperty(prototype, 'typeName', {value: genericTypeName});
  125.         Object.defineProperty(prototype, 'byteLength', {value: genericByteLength});
  126.  
  127.         Object.defineProperty(prototype, 'axisType', {value: staticType});
  128.         Object.defineProperty(prototype, 'axisLength', {value: axisLength});
  129.         Object.defineProperty(prototype, 'axisByteLength', {value: staticByteLength});
  130.  
  131.         Object.defineProperty(prototype, 'arrayType', {value: staticType.prototype['arrayType']});
  132.         Object.defineProperty(prototype, 'dataViewGetter', {value: staticType.prototype[`dataViewGetter`]});
  133.         Object.defineProperty(prototype, 'dataViewSetter', {value: staticType.prototype[`dataViewSetter`]});
  134.  
  135.         prototype.decode = decodeGeneric;
  136.         prototype.encode = encodeGeneric;
  137.         prototype.getByteLength = getByteLength;
  138.  
  139.         this.types[genericTypeName] = constructor;
  140.     }
  141.  
  142.     getTypeByName(typeName) {
  143.         const type = this.types[typeName];
  144.         if (type === undefined) {
  145.             throw new Error(`Not found type named (${typeName})`);
  146.         }
  147.         return this.types[typeName];
  148.     }
  149. };
  150.  
  151. export default binaryTypeRegistry;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement