|
1 | 1 | const { utils } = require('../../utils'); |
2 | | -const { kernelRunShortcut } = require('../../kernel-run-shortcut'); |
| 2 | +const { Input } = require('../../input'); |
3 | 3 |
|
4 | | -function removeFnNoise(fn) { |
5 | | - if (/^function /.test(fn)) { |
6 | | - fn = fn.substring(9); |
| 4 | +function constantsToString(constants) { |
| 5 | + const results = []; |
| 6 | + for (const p in constants) { |
| 7 | + const constant = constants[p]; |
| 8 | + switch (typeof constant) { |
| 9 | + case 'number': |
| 10 | + case 'boolean': |
| 11 | + results.push(`${p}:${constant}`); |
| 12 | + } |
7 | 13 | } |
8 | | - return fn.replace(/[_]typeof/g, 'typeof'); |
9 | | -} |
10 | | - |
11 | | -function removeNoise(str) { |
12 | | - return str |
13 | | - .replace(/^[A-Za-z]+/, 'function') |
14 | | - .replace(/[_]typeof/g, 'typeof'); |
| 14 | + return `{ ${ results.join() } }`; |
15 | 15 | } |
16 | 16 |
|
17 | 17 | function cpuKernelString(cpuKernel, name) { |
18 | | - return `() => { |
19 | | - ${ kernelRunShortcut.toString() }; |
20 | | - const utils = { |
21 | | - allPropertiesOf: ${ removeNoise(utils.allPropertiesOf.toString()) }, |
22 | | - clone: ${ removeNoise(utils.clone.toString()) }, |
23 | | - isArray: ${ removeNoise(utils.isArray.toString()) }, |
24 | | - }; |
25 | | - let Input = function() {}; |
26 | | - class ${ name || 'Kernel' } { |
27 | | - constructor() { |
28 | | - this.canvas = null; |
29 | | - this.context = null; |
30 | | - this.built = false; |
31 | | - this.program = null; |
32 | | - this.argumentNames = ${ JSON.stringify(cpuKernel.argumentNames) }; |
33 | | - this.argumentTypes = ${ JSON.stringify(cpuKernel.argumentTypes) }; |
34 | | - this.argumentSizes = ${ JSON.stringify(cpuKernel.argumentSizes) }; |
35 | | - this.output = ${ JSON.stringify(cpuKernel.output) }; |
36 | | - this._kernelString = \`${ cpuKernel._kernelString }\`; |
37 | | - this.output = ${ JSON.stringify(cpuKernel.output) }; |
38 | | - this.run = function() { |
39 | | - this.run = null; |
40 | | - this.build(arguments); |
41 | | - return this.run.apply(this, arguments); |
42 | | - }.bind(this); |
43 | | - this.thread = { |
44 | | - x: 0, |
45 | | - y: 0, |
46 | | - z: 0 |
47 | | - }; |
| 18 | + const header = []; |
| 19 | + const thisProperties = []; |
| 20 | + const beforeReturn = []; |
| 21 | + |
| 22 | + const useFunctionKeyword = !/^function/.test(cpuKernel.color.toString()); |
| 23 | + |
| 24 | + header.push( |
| 25 | + ' const { context, canvas, constants } = settings;', |
| 26 | + ` const output = new Int32Array(${JSON.stringify(Array.from(cpuKernel.output))});`, |
| 27 | + ` const _constants = ${constantsToString(cpuKernel.constants)};`, |
| 28 | + ); |
| 29 | + |
| 30 | + thisProperties.push( |
| 31 | + ' constants: _constants,', |
| 32 | + ' context,', |
| 33 | + ' output,', |
| 34 | + ' thread: {x: 0, y: 0, z: 0},', |
| 35 | + ); |
| 36 | + |
| 37 | + if (cpuKernel.graphical) { |
| 38 | + header.push(` const _imageData = context.createImageData(${cpuKernel.output[0]}, ${cpuKernel.output[1]});`); |
| 39 | + header.push(` const _colorData = new Uint8ClampedArray(${cpuKernel.output[0]} * ${cpuKernel.output[1]} * 4);`); |
| 40 | + |
| 41 | + const colorFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.color.toString(), { |
| 42 | + thisLookup: (propertyName) => { |
| 43 | + switch (propertyName) { |
| 44 | + case '_colorData': |
| 45 | + return '_colorData'; |
| 46 | + case '_imageData': |
| 47 | + return '_imageData'; |
| 48 | + case 'output': |
| 49 | + return 'output'; |
| 50 | + case 'thread': |
| 51 | + return 'this.thread'; |
| 52 | + } |
| 53 | + return JSON.stringify(cpuKernel[propertyName]); |
| 54 | + }, |
| 55 | + findDependency: (object, name) => { |
| 56 | + return null; |
48 | 57 | } |
49 | | - setCanvas(canvas) { this.canvas = canvas; return this; } |
50 | | - setContext(context) { this.context = context; return this; } |
51 | | - setInput(Type) { Input = Type; } |
52 | | - ${ removeFnNoise(cpuKernel.build.toString()) } |
53 | | - setupArguments() {} |
54 | | - ${ removeFnNoise(cpuKernel.setupConstants.toString()) } |
55 | | - translateSource() {} |
56 | | - pickRenderStrategy() {} |
57 | | - run () { ${ cpuKernel.kernelString } } |
58 | | - getKernelString() { return this._kernelString; } |
59 | | - ${ removeFnNoise(cpuKernel.validateSettings.toString()) } |
60 | | - ${ removeFnNoise(cpuKernel.checkOutput.toString()) } |
61 | | - }; |
62 | | - return kernelRunShortcut(new Kernel()); |
63 | | - };`; |
| 58 | + }); |
| 59 | + |
| 60 | + const getPixelsFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.getPixels.toString(), { |
| 61 | + thisLookup: (propertyName) => { |
| 62 | + switch (propertyName) { |
| 63 | + case '_colorData': |
| 64 | + return '_colorData'; |
| 65 | + case '_imageData': |
| 66 | + return '_imageData'; |
| 67 | + case 'output': |
| 68 | + return 'output'; |
| 69 | + case 'thread': |
| 70 | + return 'this.thread'; |
| 71 | + } |
| 72 | + return JSON.stringify(cpuKernel[propertyName]); |
| 73 | + }, |
| 74 | + findDependency: () => { |
| 75 | + return null; |
| 76 | + } |
| 77 | + }); |
| 78 | + |
| 79 | + thisProperties.push( |
| 80 | + ' _imageData,', |
| 81 | + ' _colorData,', |
| 82 | + ` color: ${colorFn},`, |
| 83 | + ); |
| 84 | + |
| 85 | + beforeReturn.push( |
| 86 | + ` kernel.getPixels = ${getPixelsFn};` |
| 87 | + ); |
| 88 | + } |
| 89 | + |
| 90 | + const constantTypes = []; |
| 91 | + const constantKeys = Object.keys(cpuKernel.constantTypes); |
| 92 | + for (let i = 0; i < constantKeys.length; i++) { |
| 93 | + constantTypes.push(cpuKernel.constantTypes[constantKeys]); |
| 94 | + } |
| 95 | + if (cpuKernel.argumentTypes.indexOf('HTMLImageArray') !== -1 || constantTypes.indexOf('HTMLImageArray') !== -1) { |
| 96 | + const flattenedImageTo3DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._imageTo3DArray.toString(), { |
| 97 | + doNotDefine: ['canvas'], |
| 98 | + findDependency: (object, name) => { |
| 99 | + if (object === 'this') { |
| 100 | + return (useFunctionKeyword ? 'function ' : '') + cpuKernel[name].toString(); |
| 101 | + } |
| 102 | + return null; |
| 103 | + }, |
| 104 | + thisLookup: (propertyName) => { |
| 105 | + switch (propertyName) { |
| 106 | + case 'canvas': |
| 107 | + return; |
| 108 | + case 'context': |
| 109 | + return 'context'; |
| 110 | + } |
| 111 | + } |
| 112 | + }) |
| 113 | + beforeReturn.push(flattenedImageTo3DArray); |
| 114 | + thisProperties.push(` _imageTo2DArray,`); |
| 115 | + thisProperties.push(` _imageTo3DArray,`); |
| 116 | + } else if (cpuKernel.argumentTypes.indexOf('HTMLImage') !== -1 || constantTypes.indexOf('HTMLImage') !== -1) { |
| 117 | + const flattenedImageTo2DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._imageTo2DArray.toString(), { |
| 118 | + findDependency: () => { |
| 119 | + debugger; |
| 120 | + } |
| 121 | + }); |
| 122 | + beforeReturn.push(flattenedImageTo2DArray); |
| 123 | + thisProperties.push(` _imageTo2DArray,`); |
| 124 | + } |
| 125 | + |
| 126 | + return `function(settings) { |
| 127 | +${ header.join('\n') } |
| 128 | + for (const p in constants) { |
| 129 | + const constant = constants[p]; |
| 130 | + switch (typeof constant) { |
| 131 | + case 'number': |
| 132 | + case 'boolean': |
| 133 | + continue; |
| 134 | + } |
| 135 | + _constants[p] = constant; |
| 136 | + } |
| 137 | + const kernel = (function() { |
| 138 | +${cpuKernel._kernelString} |
| 139 | + }) |
| 140 | + .apply({ ${thisProperties.join('\n')} }); |
| 141 | + ${ beforeReturn.join('\n') } |
| 142 | + return kernel; |
| 143 | +}`; |
64 | 144 | } |
65 | 145 |
|
66 | 146 | module.exports = { |
|
0 commit comments