Advertisement
lignite0

ROBO24 - Descriptor

Oct 22nd, 2019
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const regex = new RegExp(`(?<mainType>\\w+)(?:<(?<subType>\\w+)>)?(?:\\[(?<count>\\w*)\\])?`);
  2.  
  3. const dataViewMapperBase = {
  4.     "s": "Int",
  5.     "u": "Uint"
  6. };
  7.  
  8. const vectorAxes = [
  9.     ["x", "y"],
  10.     ["x", "y", "z"],
  11.     ["x", "y", "z", "w"],
  12. ];
  13.  
  14. const Descriptor = new class Descriptor {
  15.  
  16.     constructor() {
  17.         this.types = {};
  18.         this.staticTypes = {};
  19.         this.vectorClasses = {};
  20.         this.matrixClasses = {};
  21.         this.dataViewMap = {};
  22.         this.createDataViewMap();
  23.         this.createStaticTypes();
  24.         this.createVectorTypes();
  25.         this.createMatrixTypes();
  26.         this.createBlobTypes();
  27.     }
  28.  
  29.     createDataViewMap() {
  30.         for (let [signed, dataViewSigned] of Object.entries(dataViewMapperBase)) {
  31.             for (let i = 0; i < 4; i++) {
  32.                 const bitSize = (2 ** i) * 8;
  33.                 this.dataViewMap[`${signed}${bitSize}`] = `${dataViewSigned}${bitSize}`;
  34.             }
  35.         }
  36.  
  37.         for (let i = 1; i <= 2; i++) {
  38.             const bitSize = i * 32;
  39.             this.dataViewMap[`f${bitSize}`] = `Float${bitSize}`;
  40.         }
  41.     }
  42.  
  43.     createStaticTypes() {
  44.         for (let signed of ["s", "u"]) {
  45.             for (let i = 0; i < 4; i++) {
  46.                 const byteSize = 2 ** i;
  47.                 const typeName = `${signed}${byteSize * 8}`;
  48.                 const staticType = {
  49.                     name: typeName,
  50.                     size: byteSize,
  51.                     define: this.createStaticDescriptorCreator(typeName),
  52.                 };
  53.                 this.staticTypes[typeName] = staticType;
  54.                 this.types[typeName] = staticType;
  55.             }
  56.         }
  57.  
  58.         for (let i = 1; i <= 2; i++) {
  59.             const byteSize = i * 4;
  60.             const bitSize = i * 32;
  61.             const typeName = `f${bitSize}`;
  62.             const staticType = {
  63.                 name: typeName,
  64.                 size: byteSize,
  65.                 define: this.createStaticDescriptorCreator(typeName),
  66.             };
  67.             this.staticTypes[typeName] = staticType;
  68.             this.types[typeName] = staticType;
  69.         }
  70.     }
  71.  
  72.     createVectorTypes() {
  73.         for (let axis of vectorAxes) {
  74.             for (let {name: staticTypeName, size: staticTypeSize} of Object.values(this.staticTypes)) {
  75.                 const vectorTypeName = `vec${axis.length}<${staticTypeName}>`;
  76.                 const vectorTypeSize = axis.length * staticTypeSize;
  77.                 const vectorClassName = `Vector${axis.length}<${staticTypeName}>`;
  78.                 const vectorClass = (function (length) {
  79.                     return function (dataView) {
  80.                         this.length = length;
  81.                         this.dataView = dataView;
  82.                     };
  83.                 })(axis.length);
  84.                 vectorClass.prototype = Object.create(Array.prototype);
  85.                 vectorClass.prototype.constructor = vectorClass;
  86.                 vectorClass.size = vectorTypeSize;
  87.                 vectorClass.axisSize = staticTypeSize;
  88.                 vectorClass.axisType = staticTypeName;
  89.  
  90.                 this.vectorClasses[vectorClassName] = vectorClass;
  91.  
  92.                 for (let [axisOffset, field] of axis.entries()) {
  93.                     let subOffset = staticTypeSize * axisOffset;
  94.                     const staticDescriptorCreator = this.createStaticDescriptorCreator(staticTypeName);
  95.                     const descriptor = staticDescriptorCreator(null, subOffset);
  96.                     Object.defineProperty(vectorClass.prototype, axisOffset, descriptor);
  97.                     Object.defineProperty(vectorClass.prototype, field, descriptor);
  98.                 }
  99.  
  100.                 const vectorDescriptorCreator = this.createSubObjectDescriptorCreator(vectorClass);
  101.  
  102.                 this.types[vectorTypeName] = {
  103.                     name: vectorTypeName,
  104.                     size: vectorTypeSize,
  105.                     define: vectorDescriptorCreator
  106.                 }
  107.             }
  108.         }
  109.     }
  110.  
  111.     createMatrixTypes() {
  112.         for (let matrixWidth = 2; matrixWidth <= 4; matrixWidth++) {
  113.             for (let {name: staticTypeName, size: staticTypeSize} of Object.values(this.staticTypes)) {
  114.                 const matrixTypeName = `mat${matrixWidth}<${staticTypeName}>`;
  115.                 const matrixElements = (matrixWidth ** 2);
  116.                 const matrixTypeSize = matrixElements * staticTypeSize;
  117.                 const matrixClassName = `Matrix${matrixWidth}<${staticTypeName}>`;
  118.                 const matrixClass = (function (length) {
  119.                     return function (dataView) {
  120.                         this.length = length;
  121.                         this.dataView = dataView;
  122.                     };
  123.                 })(matrixElements);
  124.                 matrixClass.prototype = Object.create(Array.prototype);
  125.                 matrixClass.prototype.constructor = matrixClass;
  126.                 matrixClass.size = matrixTypeSize;
  127.                 matrixClass.axisSize = staticTypeSize;
  128.                 matrixClass.axisType = staticTypeName;
  129.  
  130.                 this.matrixClasses[matrixClassName] = matrixClass;
  131.  
  132.                 for (let i = 0; i < matrixElements; i++) {
  133.                     let subOffset = staticTypeSize * i;
  134.                     const staticDescriptorCreator = this.createStaticDescriptorCreator(staticTypeName);
  135.                     const descriptor = staticDescriptorCreator(null, subOffset);
  136.                     Object.defineProperty(matrixClass.prototype, i, descriptor);
  137.                 }
  138.  
  139.                 const matrixDescriptorCreator = this.createSubObjectDescriptorCreator(matrixClass);
  140.  
  141.                 this.types[matrixTypeName] = {
  142.                     name: matrixTypeName,
  143.                     size: matrixTypeSize,
  144.                     define: matrixDescriptorCreator
  145.                 }
  146.             }
  147.         }
  148.     }
  149.  
  150.     createBlobTypes() {
  151.         this.types["blob"] = {
  152.             name: "blob",
  153.             size: undefined,
  154.             define: this.createBlobDescriptorCreator(),
  155.         };
  156.     }
  157.  
  158.     createStaticDescriptorCreator(typeName) {
  159.         const getterName = `get${this.dataViewMap[typeName]}`;
  160.         const setterName = `set${this.dataViewMap[typeName]}`;
  161.         return function createStaticDescriptor(property, offset) {
  162.  
  163.             offset = parseInt(offset);
  164.             if (isNaN(offset)) {
  165.                 throw new Error("Static descriptor must have valid offset");
  166.             }
  167.  
  168.             return {
  169.                 get: function () {
  170.                     return this['dataView'][getterName](offset);
  171.                 },
  172.                 set: function (value) {
  173.                     this['dataView'][setterName](offset, value);
  174.                 }
  175.             }
  176.         }
  177.     }
  178.  
  179.     createSubObjectDescriptorCreator(constructor) {
  180.         return function createSubObjectDescriptor(property, offset) {
  181.  
  182.             offset = parseInt(offset);
  183.             if (isNaN(offset)) {
  184.                 throw new Error("Object descriptor must have valid offset");
  185.             }
  186.  
  187.             return {
  188.                 get: function () {
  189.                     const {buffer, byteOffset} = this['dataView'];
  190.                     const dataView = new DataView(buffer, byteOffset + offset, constructor.size);
  191.                     const object = new constructor(dataView);
  192.                     Object.defineProperty(this, property.name, {value: object});
  193.                     return object;
  194.                 },
  195.                 set: function (value) {
  196.                 }
  197.             };
  198.         }
  199.     }
  200.  
  201.     createBlobDescriptorCreator() {
  202.         return function createBlobDescriptor(property) {
  203.             return {
  204.                 get: function () {
  205.                     const size = this[`${property.name}Size`];
  206.                     const offset = this[`${property.name}Offset`];
  207.                     const {buffer, byteOffset} = this['dataView'];
  208.                     return new DataView(buffer, byteOffset + offset, size);
  209.                 },
  210.                 set: function (value) {
  211.                 }
  212.             }
  213.         }
  214.     };
  215.  
  216.     extends(constructor, config) {
  217.         const {prototype} = constructor;
  218.         prototype.getDataView = function () {
  219.             return this['dataView'];
  220.         };
  221.  
  222.         let offset = 0;
  223.         for (let propertyDeclaration of config.properties) {
  224.             const property = this.parseProperty(propertyDeclaration);
  225.             const {define, size} = property.type;
  226.             const descriptor = define(property, offset);
  227.  
  228.             if (size !== undefined && offset !== undefined) {
  229.                 offset += size;
  230.             } else {
  231.                 offset = undefined;
  232.             }
  233.  
  234.             Object.defineProperty(prototype, property.name, descriptor);
  235.         }
  236.     }
  237.  
  238.     parseProperty(propertyDeclaration) {
  239.         const {type} = propertyDeclaration;
  240.         const match = regex.exec(type);
  241.         const {mainType, subType, count} = match.groups;
  242.         const typeKey = `${mainType}` + (subType ? `<${subType}>` : '');
  243.         const typeDefinition = this.types[typeKey];
  244.  
  245.         if (typeDefinition === undefined) {
  246.             throw new Error(`Type (${type}) not exists`);
  247.         }
  248.  
  249.         const {property: propertyName, ...others} = propertyDeclaration;
  250.  
  251.         return {
  252.             name: propertyName,
  253.             ...others,
  254.             type: {
  255.                 ...typeDefinition
  256.             },
  257.         };
  258.     }
  259. };
  260.  
  261. /**
  262.  * @property tragedia
  263.  */
  264. class Chunk {
  265.     constructor(options) {
  266.         this.dataView = options['dataView'];
  267.     }
  268. }
  269.  
  270. Descriptor.extends(Chunk, {
  271.     properties: [
  272.         {type: "u8", property: "type"},
  273.         {type: "u8", property: "blockBitWidth"},
  274.         {type: "vec3<u16>", property: "position"},
  275.         {type: "mat4<f32>", property: "modelViewMatrix"},
  276.         {type: "u16", property: "blockDataOffset"},
  277.         {type: "u16", property: "blockIndexDataOffset"},
  278.         {type: "u16", property: "terrainDataOffset"},
  279.         {type: "u16", property: "additionalDataOffset"},
  280.         {type: "u16", property: "overrideDataOffset"},
  281.         {type: "u16", property: "blockDataSize"},
  282.         {type: "u16", property: "blockIndexDataSize"},
  283.         {type: "u16", property: "terrainDataSize"},
  284.         {type: "u16", property: "additionalDataSize"},
  285.         {type: "u16", property: "overrideDataSize"},
  286.         {type: "blob"},
  287.         {type: "blob", property: "blockData"},
  288.         {type: "blob", property: "blockIndexData"},
  289.         {type: "blob", property: "terrainData"},
  290.         {type: "blob", property: "additionalData"},
  291.         {type: "blob", property: "overrideData"},
  292.     ],
  293. });
  294.  
  295. const buffer = new ArrayBuffer(1000);
  296. const dataView = new DataView(buffer, 0);
  297. dataView.setInt8(0, 0xff);
  298.  
  299. const chunk = new Chunk({dataView});
  300.  
  301. chunk.blockBitWidth = 0x01;
  302. chunk.position.x = 5;
  303. chunk.position.y = 6;
  304. chunk.position.z = 0x4444;
  305. chunk.blockDataOffset = 0x04;
  306. chunk.blockDataSize = 0x08;
  307.  
  308. chunk.modelViewMatrix[0] = 0.2;
  309. chunk.modelViewMatrix[4] = 0.10;
  310. const matrix = Array.from(chunk.modelViewMatrix);
  311. console.log(Descriptor);
  312.  
  313. chunk.blockData.setInt8(0, 0xee);
  314. console.log(buffer);
  315. console.log(matrix);
  316. console.log([...chunk.modelViewMatrix]);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement