@shaderfrog/core 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/cjs/package.json +1 -0
  2. package/esm/engine.d.ts +69 -0
  3. package/esm/engine.js +209 -0
  4. package/esm/graph/base-node.d.ts +36 -0
  5. package/esm/graph/base-node.js +9 -0
  6. package/esm/graph/code-nodes.d.ts +44 -0
  7. package/esm/graph/code-nodes.js +18 -0
  8. package/esm/graph/context.d.ts +37 -0
  9. package/esm/graph/context.js +243 -0
  10. package/esm/graph/data-nodes.d.ts +83 -0
  11. package/esm/graph/data-nodes.js +131 -0
  12. package/esm/graph/edge.d.ts +13 -0
  13. package/esm/graph/edge.js +7 -0
  14. package/esm/graph/evaluate.d.ts +9 -0
  15. package/esm/graph/evaluate.js +27 -0
  16. package/esm/graph/graph-node.d.ts +8 -0
  17. package/esm/graph/graph-node.js +135 -0
  18. package/esm/graph/graph-types.d.ts +38 -0
  19. package/esm/graph/graph-types.js +22 -0
  20. package/esm/graph/graph.d.ts +89 -0
  21. package/esm/graph/graph.js +506 -0
  22. package/esm/graph/graph.test.d.ts +1 -0
  23. package/esm/graph/graph.test.js +168 -0
  24. package/esm/graph/index.d.ts +11 -0
  25. package/esm/graph/index.js +11 -0
  26. package/esm/graph/parsers.d.ts +39 -0
  27. package/esm/graph/parsers.js +213 -0
  28. package/esm/graph/shader-sections.d.ts +47 -0
  29. package/esm/graph/shader-sections.js +256 -0
  30. package/esm/index.d.ts +3 -0
  31. package/esm/index.js +3 -0
  32. package/esm/package.json +1 -0
  33. package/esm/plugins/babylon/bablyengine.d.ts +28 -0
  34. package/esm/plugins/babylon/bablyengine.js +589 -0
  35. package/esm/plugins/babylon/importers.d.ts +3 -0
  36. package/esm/plugins/babylon/importers.js +64 -0
  37. package/esm/plugins/babylon/index.d.ts +2 -0
  38. package/esm/plugins/babylon/index.js +2 -0
  39. package/esm/plugins/playcanvas/importers.d.ts +3 -0
  40. package/esm/plugins/playcanvas/importers.js +28 -0
  41. package/esm/plugins/playcanvas/index.d.ts +2 -0
  42. package/esm/plugins/playcanvas/index.js +2 -0
  43. package/esm/plugins/playcanvas/playengine.d.ts +39 -0
  44. package/esm/plugins/playcanvas/playengine.js +517 -0
  45. package/esm/plugins/three/importers.d.ts +3 -0
  46. package/esm/plugins/three/importers.js +15 -0
  47. package/esm/plugins/three/index.d.ts +2 -0
  48. package/esm/plugins/three/index.js +2 -0
  49. package/esm/plugins/three/threngine.d.ts +34 -0
  50. package/esm/plugins/three/threngine.js +608 -0
  51. package/esm/strategy/assignemntTo.d.ts +9 -0
  52. package/esm/strategy/assignemntTo.js +26 -0
  53. package/esm/strategy/declarationOf.d.ts +9 -0
  54. package/esm/strategy/declarationOf.js +23 -0
  55. package/esm/strategy/hardCode.d.ts +15 -0
  56. package/esm/strategy/hardCode.js +23 -0
  57. package/esm/strategy/index.d.ts +9 -0
  58. package/esm/strategy/index.js +9 -0
  59. package/esm/strategy/inject.d.ts +15 -0
  60. package/esm/strategy/inject.js +122 -0
  61. package/esm/strategy/namedAttribute.d.ts +9 -0
  62. package/esm/strategy/namedAttribute.js +48 -0
  63. package/esm/strategy/strategy.d.ts +28 -0
  64. package/esm/strategy/strategy.js +31 -0
  65. package/esm/strategy/stratgies.test.d.ts +1 -0
  66. package/esm/strategy/stratgies.test.js +164 -0
  67. package/esm/strategy/texture2D.d.ts +6 -0
  68. package/esm/strategy/texture2D.js +83 -0
  69. package/esm/strategy/uniform.d.ts +6 -0
  70. package/esm/strategy/uniform.js +190 -0
  71. package/esm/strategy/variable.d.ts +6 -0
  72. package/esm/strategy/variable.js +80 -0
  73. package/esm/util/ast.d.ts +30 -0
  74. package/esm/util/ast.js +332 -0
  75. package/esm/util/ensure.d.ts +1 -0
  76. package/esm/util/ensure.js +7 -0
  77. package/esm/util/id.d.ts +1 -0
  78. package/esm/util/id.js +2 -0
  79. package/package.json +9 -11
  80. /package/{engine.d.ts → cjs/engine.d.ts} +0 -0
  81. /package/{engine.js → cjs/engine.js} +0 -0
  82. /package/{graph → cjs/graph}/base-node.d.ts +0 -0
  83. /package/{graph → cjs/graph}/base-node.js +0 -0
  84. /package/{graph → cjs/graph}/code-nodes.d.ts +0 -0
  85. /package/{graph → cjs/graph}/code-nodes.js +0 -0
  86. /package/{graph → cjs/graph}/context.d.ts +0 -0
  87. /package/{graph → cjs/graph}/context.js +0 -0
  88. /package/{graph → cjs/graph}/data-nodes.d.ts +0 -0
  89. /package/{graph → cjs/graph}/data-nodes.js +0 -0
  90. /package/{graph → cjs/graph}/edge.d.ts +0 -0
  91. /package/{graph → cjs/graph}/edge.js +0 -0
  92. /package/{graph → cjs/graph}/evaluate.d.ts +0 -0
  93. /package/{graph → cjs/graph}/evaluate.js +0 -0
  94. /package/{graph → cjs/graph}/graph-node.d.ts +0 -0
  95. /package/{graph → cjs/graph}/graph-node.js +0 -0
  96. /package/{graph → cjs/graph}/graph-types.d.ts +0 -0
  97. /package/{graph → cjs/graph}/graph-types.js +0 -0
  98. /package/{graph → cjs/graph}/graph.d.ts +0 -0
  99. /package/{graph → cjs/graph}/graph.js +0 -0
  100. /package/{graph → cjs/graph}/graph.test.d.ts +0 -0
  101. /package/{graph → cjs/graph}/graph.test.js +0 -0
  102. /package/{graph → cjs/graph}/index.d.ts +0 -0
  103. /package/{graph → cjs/graph}/index.js +0 -0
  104. /package/{graph → cjs/graph}/parsers.d.ts +0 -0
  105. /package/{graph → cjs/graph}/parsers.js +0 -0
  106. /package/{graph → cjs/graph}/shader-sections.d.ts +0 -0
  107. /package/{graph → cjs/graph}/shader-sections.js +0 -0
  108. /package/{index.d.ts → cjs/index.d.ts} +0 -0
  109. /package/{index.js → cjs/index.js} +0 -0
  110. /package/{plugins → cjs/plugins}/babylon/bablyengine.d.ts +0 -0
  111. /package/{plugins → cjs/plugins}/babylon/bablyengine.js +0 -0
  112. /package/{plugins → cjs/plugins}/babylon/importers.d.ts +0 -0
  113. /package/{plugins → cjs/plugins}/babylon/importers.js +0 -0
  114. /package/{plugins → cjs/plugins}/babylon/index.d.ts +0 -0
  115. /package/{plugins → cjs/plugins}/babylon/index.js +0 -0
  116. /package/{plugins → cjs/plugins}/playcanvas/importers.d.ts +0 -0
  117. /package/{plugins → cjs/plugins}/playcanvas/importers.js +0 -0
  118. /package/{plugins → cjs/plugins}/playcanvas/index.d.ts +0 -0
  119. /package/{plugins → cjs/plugins}/playcanvas/index.js +0 -0
  120. /package/{plugins → cjs/plugins}/playcanvas/playengine.d.ts +0 -0
  121. /package/{plugins → cjs/plugins}/playcanvas/playengine.js +0 -0
  122. /package/{plugins → cjs/plugins}/three/importers.d.ts +0 -0
  123. /package/{plugins → cjs/plugins}/three/importers.js +0 -0
  124. /package/{plugins → cjs/plugins}/three/index.d.ts +0 -0
  125. /package/{plugins → cjs/plugins}/three/index.js +0 -0
  126. /package/{plugins → cjs/plugins}/three/threngine.d.ts +0 -0
  127. /package/{plugins → cjs/plugins}/three/threngine.js +0 -0
  128. /package/{strategy → cjs/strategy}/assignemntTo.d.ts +0 -0
  129. /package/{strategy → cjs/strategy}/assignemntTo.js +0 -0
  130. /package/{strategy → cjs/strategy}/declarationOf.d.ts +0 -0
  131. /package/{strategy → cjs/strategy}/declarationOf.js +0 -0
  132. /package/{strategy → cjs/strategy}/hardCode.d.ts +0 -0
  133. /package/{strategy → cjs/strategy}/hardCode.js +0 -0
  134. /package/{strategy → cjs/strategy}/index.d.ts +0 -0
  135. /package/{strategy → cjs/strategy}/index.js +0 -0
  136. /package/{strategy → cjs/strategy}/inject.d.ts +0 -0
  137. /package/{strategy → cjs/strategy}/inject.js +0 -0
  138. /package/{strategy → cjs/strategy}/namedAttribute.d.ts +0 -0
  139. /package/{strategy → cjs/strategy}/namedAttribute.js +0 -0
  140. /package/{strategy → cjs/strategy}/strategy.d.ts +0 -0
  141. /package/{strategy → cjs/strategy}/strategy.js +0 -0
  142. /package/{strategy → cjs/strategy}/stratgies.test.d.ts +0 -0
  143. /package/{strategy → cjs/strategy}/stratgies.test.js +0 -0
  144. /package/{strategy → cjs/strategy}/texture2D.d.ts +0 -0
  145. /package/{strategy → cjs/strategy}/texture2D.js +0 -0
  146. /package/{strategy → cjs/strategy}/uniform.d.ts +0 -0
  147. /package/{strategy → cjs/strategy}/uniform.js +0 -0
  148. /package/{strategy → cjs/strategy}/variable.d.ts +0 -0
  149. /package/{strategy → cjs/strategy}/variable.js +0 -0
  150. /package/{util → cjs/util}/ast.d.ts +0 -0
  151. /package/{util → cjs/util}/ast.js +0 -0
  152. /package/{util → cjs/util}/ensure.d.ts +0 -0
  153. /package/{util → cjs/util}/ensure.js +0 -0
  154. /package/{util → cjs/util}/id.d.ts +0 -0
  155. /package/{util → cjs/util}/id.js +0 -0
@@ -0,0 +1,15 @@
1
+ import { NodeInput } from '../graph/base-node';
2
+ import { BaseStrategy, ApplyStrategy, StrategyType } from '.';
3
+ /**
4
+ * I don't actually know if anything uses this, nor do I remember how it would
5
+ * be used, since the filler strategy has no effect on the AST. TODO: Remove
6
+ * this strategy if no one uses it!
7
+ */
8
+ export interface HardCodeStrategy extends BaseStrategy {
9
+ type: StrategyType.HARD_CODE_INPUTS;
10
+ config: {
11
+ inputs: NodeInput[];
12
+ };
13
+ }
14
+ export declare const hardCodeStrategy: (inputs: NodeInput[]) => HardCodeStrategy;
15
+ export declare const applyHardCodeStrategy: ApplyStrategy<HardCodeStrategy>;
@@ -0,0 +1,23 @@
1
+ import { StrategyType } from '.';
2
+ export var hardCodeStrategy = function (inputs) { return ({
3
+ type: StrategyType.HARD_CODE_INPUTS,
4
+ config: { inputs: inputs },
5
+ }); };
6
+ export var applyHardCodeStrategy = function (strategy, ast, graphNode, siblingNode) {
7
+ return strategy.config.inputs.map(function (input) {
8
+ // Broken out into two lines to enforce type checking on the array.
9
+ var ci = [
10
+ input,
11
+ // Fillers have to return AstNode | Program, and filler is type Filler,
12
+ // so this awkward branch is to make types line up. But I don't think
13
+ // this code path would ever get called
14
+ function (filler) {
15
+ if (!filler || Array.isArray(filler)) {
16
+ throw new Error('Cannot use void filler');
17
+ }
18
+ return filler;
19
+ },
20
+ ];
21
+ return ci;
22
+ });
23
+ };
@@ -0,0 +1,9 @@
1
+ export * from './hardCode';
2
+ export * from './uniform';
3
+ export * from './assignemntTo';
4
+ export * from './inject';
5
+ export * from './declarationOf';
6
+ export * from './texture2D';
7
+ export * from './namedAttribute';
8
+ export * from './variable';
9
+ export * from './strategy';
@@ -0,0 +1,9 @@
1
+ export * from './hardCode';
2
+ export * from './uniform';
3
+ export * from './assignemntTo';
4
+ export * from './inject';
5
+ export * from './declarationOf';
6
+ export * from './texture2D';
7
+ export * from './namedAttribute';
8
+ export * from './variable';
9
+ export * from './strategy';
@@ -0,0 +1,15 @@
1
+ import { BaseStrategy, ApplyStrategy, StrategyType } from '.';
2
+ export interface InjectStrategy extends BaseStrategy {
3
+ type: StrategyType.INJECT;
4
+ config: {
5
+ find: string;
6
+ insert: 'before' | 'after' | 'replace';
7
+ count: number;
8
+ };
9
+ }
10
+ /**
11
+ * Inject source code into an AST, in a find-and-replace style. This only
12
+ * operates on statements right now
13
+ */
14
+ export declare const injectStrategy: (config: InjectStrategy['config']) => InjectStrategy;
15
+ export declare const applyInjectStrategy: ApplyStrategy<InjectStrategy>;
@@ -0,0 +1,122 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __read = (this && this.__read) || function (o, n) {
13
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
14
+ if (!m) return o;
15
+ var i = m.call(o), r, ar = [], e;
16
+ try {
17
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
18
+ }
19
+ catch (error) { e = { error: error }; }
20
+ finally {
21
+ try {
22
+ if (r && !r.done && (m = i["return"])) m.call(i);
23
+ }
24
+ finally { if (e) throw e.error; }
25
+ }
26
+ return ar;
27
+ };
28
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
29
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
30
+ if (ar || !(i in from)) {
31
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
32
+ ar[i] = from[i];
33
+ }
34
+ }
35
+ return to.concat(ar || Array.prototype.slice.call(from));
36
+ };
37
+ import { generate } from '@shaderfrog/glsl-parser';
38
+ import { nodeInput } from '../graph/base-node';
39
+ import { StrategyType } from '.';
40
+ /**
41
+ * Inject source code into an AST, in a find-and-replace style. This only
42
+ * operates on statements right now
43
+ */
44
+ export var injectStrategy = function (config) { return ({
45
+ type: StrategyType.INJECT,
46
+ config: config,
47
+ }); };
48
+ // Typescript fucked up flat https://stackoverflow.com/a/61420611/743464
49
+ var combineWs = function (a, b) {
50
+ return [a, b].flat(Infinity);
51
+ };
52
+ // Move whitespace from one node to another. Since whitespace is trailing, if a
53
+ // node is injected after a previous node, move the whitespace from the earlier
54
+ // node to the later one. This keeps comments in the same place
55
+ var transferWhitespace = function (to, from) {
56
+ return 'semi' in to && 'semi' in from
57
+ ? [
58
+ __assign(__assign({}, to), { semi: __assign(__assign({}, to.semi), { whitespace: from.semi.whitespace }) }),
59
+ __assign(__assign({}, from), { semi: __assign(__assign({}, from.semi), { whitespace: '\n' }) }),
60
+ ]
61
+ : 'whitespace' in to && 'semi' in from
62
+ ? [
63
+ __assign(__assign({}, to), { whitespace: combineWs(to.whitespace, from.semi.whitespace) }),
64
+ __assign(__assign({}, from), { semi: __assign(__assign({}, from.semi), { whitespace: '\n' }) }),
65
+ ]
66
+ : [to, from];
67
+ };
68
+ export var applyInjectStrategy = function (strategy, ast, graphNode, siblingNode) {
69
+ var program = ast.program;
70
+ var _a = strategy.config, find = _a.find, count = _a.count, insert = _a.insert;
71
+ // Total hack for now. Search each function body for statements that when
72
+ // generated, match the user's "find" string.
73
+ var matchedStatements = program.reduce(function (matches, statement) {
74
+ var newMatches = [];
75
+ if (statement.type === 'function') {
76
+ var bodyStatements_1 = statement.body.statements;
77
+ newMatches = bodyStatements_1.reduce(function (innerMatches, bodyStmt, index) {
78
+ var generated = generate(bodyStmt);
79
+ // console.log(`"${generated}"`);
80
+ var triple = [
81
+ bodyStatements_1,
82
+ bodyStmt,
83
+ index,
84
+ ];
85
+ return __spreadArray(__spreadArray([], __read(innerMatches), false), __read((generated.includes(find) ? [triple] : [])), false);
86
+ }, []);
87
+ }
88
+ return __spreadArray(__spreadArray([], __read(matches), false), __read(newMatches), false);
89
+ }, []);
90
+ var name = "Inject ".concat(strategy.config.insert);
91
+ return [
92
+ [
93
+ nodeInput(name, "filler_".concat(name), 'filler', undefined, // Data type for what plugs into this filler
94
+ ['code', 'data'], false),
95
+ function (fillerAst) {
96
+ var toInsert = Array.isArray(fillerAst)
97
+ ? fillerAst
98
+ : [fillerAst];
99
+ // Loop backwards through the matches because when we inject code into
100
+ // parent nodes, it modifies the statement list arrays
101
+ for (
102
+ // Only go as many count replacements as specified in the config
103
+ var i = Math.min(matchedStatements.length - 1, count); i >= 0; i--) {
104
+ var _a = __read(matchedStatements[i], 3), parent = _a[0], stmt = _a[1], index = _a[2];
105
+ if (insert === 'after') {
106
+ var _b = __read(toInsert), first = _b[0], rest = _b.slice(1);
107
+ var _c = __read(transferWhitespace(first, stmt), 2), newFirst = _c[0], updatedStmt = _c[1];
108
+ var newStatements = __spreadArray([newFirst], __read(rest), false);
109
+ parent.splice.apply(parent, __spreadArray([index, 1, updatedStmt], __read(newStatements), false));
110
+ }
111
+ else if (insert === 'before') {
112
+ parent.splice.apply(parent, __spreadArray([index - 1, 0], __read(toInsert), false));
113
+ }
114
+ else if (insert === 'replace') {
115
+ throw new Error('not yet implemented');
116
+ }
117
+ }
118
+ return ast;
119
+ },
120
+ ],
121
+ ];
122
+ };
@@ -0,0 +1,9 @@
1
+ import { BaseStrategy, ApplyStrategy, StrategyType } from '.';
2
+ export declare const namedAttributeStrategy: (attributeName: string) => NamedAttributeStrategy;
3
+ export interface NamedAttributeStrategy extends BaseStrategy {
4
+ type: StrategyType.NAMED_ATTRIBUTE;
5
+ config: {
6
+ attributeName: string;
7
+ };
8
+ }
9
+ export declare const applyNamedAttributeStrategy: ApplyStrategy<NamedAttributeStrategy>;
@@ -0,0 +1,48 @@
1
+ var __read = (this && this.__read) || function (o, n) {
2
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
3
+ if (!m) return o;
4
+ var i = m.call(o), r, ar = [], e;
5
+ try {
6
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
7
+ }
8
+ catch (error) { e = { error: error }; }
9
+ finally {
10
+ try {
11
+ if (r && !r.done && (m = i["return"])) m.call(i);
12
+ }
13
+ finally { if (e) throw e.error; }
14
+ }
15
+ return ar;
16
+ };
17
+ import { nodeInput } from '../graph/base-node';
18
+ import { StrategyType } from '.';
19
+ import { generateFiller } from '../util/ast';
20
+ export var namedAttributeStrategy = function (attributeName) { return ({
21
+ type: StrategyType.NAMED_ATTRIBUTE,
22
+ config: { attributeName: attributeName },
23
+ }); };
24
+ export var applyNamedAttributeStrategy = function (strategy, ast, graphNode, siblingNode) {
25
+ var program = ast;
26
+ var attributeName = strategy.config.attributeName;
27
+ return [
28
+ [
29
+ nodeInput(attributeName, "filler_".concat(attributeName), 'filler', undefined, // Data type for what plugs into this filler
30
+ ['code', 'data'], true),
31
+ function (fillerAst) {
32
+ Object.entries(program.scopes[0].bindings).forEach(function (_a) {
33
+ var _b = __read(_a, 2), name = _b[0], binding = _b[1];
34
+ binding.references.forEach(function (ref) {
35
+ // Rename the variable usage only if it's not the identifier, to
36
+ // avoid filling in `in vec3 replaceMe;` with `replacer()`
37
+ if (ref.type === 'identifier' &&
38
+ ref !== binding.declaration &&
39
+ ref.identifier === attributeName) {
40
+ ref.identifier = generateFiller(fillerAst);
41
+ }
42
+ });
43
+ });
44
+ return ast;
45
+ },
46
+ ],
47
+ ];
48
+ };
@@ -0,0 +1,28 @@
1
+ import { AstNode, Program } from '@shaderfrog/glsl-parser/ast';
2
+ import { SourceNode } from '../graph/code-nodes';
3
+ import { HardCodeStrategy } from './hardCode';
4
+ import { UniformStrategy } from './uniform';
5
+ import { AssignemntToStrategy } from './assignemntTo';
6
+ import { DeclarationOfStrategy } from './declarationOf';
7
+ import { Texture2DStrategy } from './texture2D';
8
+ import { NamedAttributeStrategy } from './namedAttribute';
9
+ import { VariableStrategy } from './variable';
10
+ import { InjectStrategy } from './inject';
11
+ import { ComputedInput } from '../graph/parsers';
12
+ export declare enum StrategyType {
13
+ VARIABLE = "Variable Names",
14
+ ASSIGNMENT_TO = "Assignment To",
15
+ DECLARATION_OF = "Variable Declaration",
16
+ TEXTURE_2D = "Texture2D",
17
+ NAMED_ATTRIBUTE = "Named Attribute",
18
+ UNIFORM = "Uniform",
19
+ INJECT = "Inject",
20
+ HARD_CODE_INPUTS = "Hard Code Inputs"
21
+ }
22
+ export interface BaseStrategy {
23
+ type: StrategyType;
24
+ config: Object;
25
+ }
26
+ export type Strategy = UniformStrategy | AssignemntToStrategy | Texture2DStrategy | NamedAttributeStrategy | VariableStrategy | HardCodeStrategy | InjectStrategy | DeclarationOfStrategy;
27
+ export type ApplyStrategy<T> = (strategy: T, ast: AstNode | Program, node: SourceNode, sibling: SourceNode) => ComputedInput[];
28
+ export declare const applyStrategy: (strategy: Strategy, ast: AstNode | Program, node: SourceNode, sibling: SourceNode) => ComputedInput[];
@@ -0,0 +1,31 @@
1
+ var _a;
2
+ import { applyHardCodeStrategy } from './hardCode';
3
+ import { applyUniformStrategy } from './uniform';
4
+ import { applyAssignmentToStrategy, } from './assignemntTo';
5
+ import { constApplyDeclarationOf as constApplyDeclarationOfStrategy, } from './declarationOf';
6
+ import { applyTexture2DStrategy } from './texture2D';
7
+ import { applyNamedAttributeStrategy, } from './namedAttribute';
8
+ import { applyVariableStrategy } from './variable';
9
+ import { applyInjectStrategy } from './inject';
10
+ export var StrategyType;
11
+ (function (StrategyType) {
12
+ StrategyType["VARIABLE"] = "Variable Names";
13
+ StrategyType["ASSIGNMENT_TO"] = "Assignment To";
14
+ StrategyType["DECLARATION_OF"] = "Variable Declaration";
15
+ StrategyType["TEXTURE_2D"] = "Texture2D";
16
+ StrategyType["NAMED_ATTRIBUTE"] = "Named Attribute";
17
+ StrategyType["UNIFORM"] = "Uniform";
18
+ StrategyType["INJECT"] = "Inject";
19
+ StrategyType["HARD_CODE_INPUTS"] = "Hard Code Inputs";
20
+ })(StrategyType || (StrategyType = {}));
21
+ var strategyRunners = (_a = {},
22
+ _a[StrategyType.INJECT] = applyInjectStrategy,
23
+ _a[StrategyType.HARD_CODE_INPUTS] = applyHardCodeStrategy,
24
+ _a[StrategyType.UNIFORM] = applyUniformStrategy,
25
+ _a[StrategyType.ASSIGNMENT_TO] = applyAssignmentToStrategy,
26
+ _a[StrategyType.DECLARATION_OF] = constApplyDeclarationOfStrategy,
27
+ _a[StrategyType.TEXTURE_2D] = applyTexture2DStrategy,
28
+ _a[StrategyType.NAMED_ATTRIBUTE] = applyNamedAttributeStrategy,
29
+ _a[StrategyType.VARIABLE] = applyVariableStrategy,
30
+ _a);
31
+ export var applyStrategy = function (strategy, ast, node, sibling) { return strategyRunners[strategy.type](strategy, ast, node, sibling); };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,164 @@
1
+ var __read = (this && this.__read) || function (o, n) {
2
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
3
+ if (!m) return o;
4
+ var i = m.call(o), r, ar = [], e;
5
+ try {
6
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
7
+ }
8
+ catch (error) { e = { error: error }; }
9
+ finally {
10
+ try {
11
+ if (r && !r.done && (m = i["return"])) m.call(i);
12
+ }
13
+ finally { if (e) throw e.error; }
14
+ }
15
+ return ar;
16
+ };
17
+ import { parser } from '@shaderfrog/glsl-parser';
18
+ import { generate } from '@shaderfrog/glsl-parser';
19
+ import { applyStrategy, StrategyType } from '.';
20
+ import * as graphModule from '../graph/graph';
21
+ import { makeExpression } from '../util/ast';
22
+ import preprocess from '@shaderfrog/glsl-parser/preprocessor';
23
+ var orig;
24
+ beforeEach(function () {
25
+ orig = graphModule.mangleName;
26
+ // Terrible hack. in the real world, strategies are applied after mangling
27
+ // @ts-ignore
28
+ graphModule.mangleName = function (name) { return name; };
29
+ });
30
+ afterEach(function () {
31
+ // @ts-ignore
32
+ graphModule.mangleName = orig;
33
+ });
34
+ it('named attribute strategy`', function () {
35
+ var source = "\nin vec3 replaceThisAtrribute;\nvoid main() {\n vec2 y = replaceThisAtrribute;\n}\n";
36
+ var ast = parser.parse(source, { quiet: true });
37
+ var fillers = applyStrategy({
38
+ type: StrategyType.NAMED_ATTRIBUTE,
39
+ config: {
40
+ attributeName: 'replaceThisAtrribute',
41
+ },
42
+ }, ast, { source: source }, {});
43
+ expect(fillers.length).toBe(1);
44
+ fillers[0][1]({
45
+ type: 'literal',
46
+ literal: "myFiller()",
47
+ whitespace: '',
48
+ });
49
+ var result = generate(ast);
50
+ // Should replace the use of the filler, but not the declaration
51
+ expect(result).toBe("\nin vec3 replaceThisAtrribute;\nvoid main() {\n vec2 y = myFiller();\n}\n");
52
+ });
53
+ it('inject strategy after', function () {
54
+ var source = "\nuniform float x;\n// Some comment\nvoid main() {\n/* some comment */\nre(x, y, z);\n// Middle comment\nre(x, y, z);\n// Final comment\n}";
55
+ var ast = parser.parse(source, { quiet: true });
56
+ var fillers = applyStrategy({
57
+ type: StrategyType.INJECT,
58
+ config: {
59
+ find: 're(x, y, z);',
60
+ insert: 'after',
61
+ count: Infinity,
62
+ },
63
+ }, ast, { source: source }, {});
64
+ expect(fillers.length).toBe(1);
65
+ fillers[0][1]({
66
+ type: 'literal',
67
+ literal: "someOtherCall(x, y, z);\nsomeOtherCall(x, y, z);",
68
+ whitespace: '',
69
+ });
70
+ var result = generate(ast);
71
+ // Should fill references
72
+ expect(result).toBe("\nuniform float x;\n// Some comment\nvoid main() {\n/* some comment */\nre(x, y, z);\nsomeOtherCall(x, y, z);\nsomeOtherCall(x, y, z);\n// Middle comment\nre(x, y, z);\nsomeOtherCall(x, y, z);\nsomeOtherCall(x, y, z);\n// Final comment\n}");
73
+ });
74
+ it('inject strategy before', function () {
75
+ var source = "\nuniform float x;\n// Some comment\nvoid main() {\n/* some comment */\nre(x, y, z);\n// Middle comment\nre(x, y, z);\n// Final comment\n}";
76
+ var ast = parser.parse(source, { quiet: true });
77
+ var fillers = applyStrategy({
78
+ type: StrategyType.INJECT,
79
+ config: {
80
+ find: 're(x, y, z);',
81
+ insert: 'before',
82
+ count: Infinity,
83
+ },
84
+ }, ast, { source: source }, {});
85
+ expect(fillers.length).toBe(1);
86
+ fillers[0][1]({
87
+ type: 'literal',
88
+ literal: "someOtherCall(x, y, z);\nsomeOtherCall(x, y, z);",
89
+ whitespace: '\n',
90
+ });
91
+ var result = generate(ast);
92
+ // Should fill references
93
+ expect(result).toBe("\nuniform float x;\n// Some comment\nvoid main() {\n/* some comment */\nsomeOtherCall(x, y, z);\nsomeOtherCall(x, y, z);\nre(x, y, z);\n// Middle comment\nsomeOtherCall(x, y, z);\nsomeOtherCall(x, y, z);\nre(x, y, z);\n// Final comment\n}");
94
+ });
95
+ it('correctly fills with uniform strategy', function () {
96
+ var _a, _b, _c;
97
+ var ast = parser.parse("\nlayout(std140,column_major) uniform;\nuniform sampler2D image;\nuniform vec4 input, output, other;\nuniform vec4 zenput;\nuniform Light0 { vec4 y; } x;\nvec3 topLevel = vec3(0.0);\nvoid other(in vec3 param) {}\nvoid main() {\n vec4 computed = texture2D(image, uvPow * 1.0);\n vec4 x = input;\n vec4 y = output;\n vec4 z = zenput;\n}", { quiet: true });
98
+ var fillers = applyStrategy({ type: StrategyType.UNIFORM, config: {} }, ast, {}, {});
99
+ // It should find uniforms with simple types, excluding sampler2D
100
+ expect(fillers.map(function (_a) {
101
+ var _b = __read(_a, 1), name = _b[0].displayName;
102
+ return name;
103
+ })).toEqual([
104
+ 'image',
105
+ 'input',
106
+ 'output',
107
+ 'other',
108
+ 'zenput',
109
+ ]);
110
+ (_a = fillers.find(function (_a) {
111
+ var _b = __read(_a, 1), name = _b[0].displayName;
112
+ return name === 'input';
113
+ })) === null || _a === void 0 ? void 0 : _a[1](makeExpression('a'));
114
+ (_b = fillers.find(function (_a) {
115
+ var _b = __read(_a, 1), name = _b[0].displayName;
116
+ return name === 'output';
117
+ })) === null || _b === void 0 ? void 0 : _b[1](makeExpression('b'));
118
+ (_c = fillers.find(function (_a) {
119
+ var _b = __read(_a, 1), name = _b[0].displayName;
120
+ return name === 'zenput';
121
+ })) === null || _c === void 0 ? void 0 : _c[1](makeExpression('c'));
122
+ var result = generate(ast);
123
+ // Should fill references
124
+ expect(result).toContain('vec4 x = a;');
125
+ expect(result).toContain('vec4 y = b;');
126
+ expect(result).toContain('vec4 z = c;');
127
+ // Should preserve things it shouldn't touch
128
+ expect(result).toContain('layout(std140,column_major) uniform;');
129
+ expect(result).toContain('uniform sampler2D image;');
130
+ expect(result).toContain('uniform Light0 { vec4 y; } x;');
131
+ // Should remove uniforms from declarator list
132
+ expect(result).toContain('uniform vec4 other;');
133
+ // Should remove uniform lines
134
+ expect(result).not.toContain('uniform vec4 zenput');
135
+ });
136
+ it('uses name without suffix for single call', function () {
137
+ var ast = parser.parse("\nvoid main() {\n vec4 computed = texture2D(noiseImage, uvPow * 1.0);\n}", { quiet: true });
138
+ expect(applyStrategy({ type: StrategyType.TEXTURE_2D, config: {} }, ast, {}, {}).map(function (_a) {
139
+ var _b = __read(_a, 1), name = _b[0].displayName;
140
+ return name;
141
+ })).toEqual(['noiseImage']);
142
+ });
143
+ it('finds multiple texture2D inputs for one uniform', function () {
144
+ var ast = parser.parse("\nvoid main() {\n vec4 computed = texture2D(noiseImage, uvPow * 1.0);\n computed += texture2D(noiseImage, uvPow * 2.0);\n}", { quiet: true });
145
+ expect(applyStrategy({ type: StrategyType.TEXTURE_2D, config: {} }, ast, {}, {}).map(function (_a) {
146
+ var _b = __read(_a, 1), name = _b[0].displayName;
147
+ return name;
148
+ })).toEqual(['noiseImage_0', 'noiseImage_1']);
149
+ });
150
+ it('Make sure texture2D finds preprocessed texture() call', function () {
151
+ // I thought this was a regression, but it wasn't a real bug, but tests seems
152
+ // benign to keep anyway
153
+ var program = "\n#define texture2DBias texture\n\nuniform sampler2D normalMap;\n\nvoid getNormal() {\n vec3 normalMap = unpackNormal(texture2DBias(normalMap, vUv0, textureBias));\n}";
154
+ var pp = preprocess(program, {
155
+ preserve: {
156
+ version: function () { return true; },
157
+ },
158
+ });
159
+ var ast = parser.parse(pp, { quiet: true });
160
+ expect(applyStrategy({ type: StrategyType.TEXTURE_2D, config: {} }, ast, {}, {}).map(function (_a) {
161
+ var _b = __read(_a, 1), name = _b[0].displayName;
162
+ return name;
163
+ })).toEqual(['normalMapx']);
164
+ });
@@ -0,0 +1,6 @@
1
+ import { BaseStrategy, ApplyStrategy, StrategyType } from '.';
2
+ export interface Texture2DStrategy extends BaseStrategy {
3
+ type: StrategyType.TEXTURE_2D;
4
+ }
5
+ export declare const texture2DStrategy: () => Texture2DStrategy;
6
+ export declare const applyTexture2DStrategy: ApplyStrategy<Texture2DStrategy>;
@@ -0,0 +1,83 @@
1
+ var __read = (this && this.__read) || function (o, n) {
2
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
3
+ if (!m) return o;
4
+ var i = m.call(o), r, ar = [], e;
5
+ try {
6
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
7
+ }
8
+ catch (error) { e = { error: error }; }
9
+ finally {
10
+ try {
11
+ if (r && !r.done && (m = i["return"])) m.call(i);
12
+ }
13
+ finally { if (e) throw e.error; }
14
+ }
15
+ return ar;
16
+ };
17
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
18
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
19
+ if (ar || !(i in from)) {
20
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
21
+ ar[i] = from[i];
22
+ }
23
+ }
24
+ return to.concat(ar || Array.prototype.slice.call(from));
25
+ };
26
+ import { generate } from '@shaderfrog/glsl-parser';
27
+ import { visit, } from '@shaderfrog/glsl-parser/ast';
28
+ import { nodeInput } from '../graph/base-node';
29
+ import { StrategyType } from '.';
30
+ export var texture2DStrategy = function () { return ({
31
+ type: StrategyType.TEXTURE_2D,
32
+ config: {},
33
+ }); };
34
+ export var applyTexture2DStrategy = function (strategy, ast, graphNode, siblingNode) {
35
+ var texture2Dcalls = [];
36
+ var seen = {};
37
+ var visitors = {
38
+ function_call: {
39
+ enter: function (path) {
40
+ var identifier = path.node.identifier;
41
+ if (
42
+ // TODO: 100 vs 300
43
+ ((identifier === null || identifier === void 0 ? void 0 : identifier.identifier) === 'texture2D' ||
44
+ (identifier === null || identifier === void 0 ? void 0 : identifier.identifier) === 'texture') &&
45
+ path.key) {
46
+ if (!path.parent) {
47
+ throw new Error('This error is impossible. A function call always has a parent.');
48
+ }
49
+ var name = generate(path.node.args[0]);
50
+ seen[name] = (seen[name] || 0) + 1;
51
+ texture2Dcalls.push([
52
+ name,
53
+ path.parent,
54
+ path.key,
55
+ // Remove the first argument and comma
56
+ path.node.args.slice(2),
57
+ ]);
58
+ }
59
+ },
60
+ },
61
+ };
62
+ visit(ast, visitors);
63
+ var names = new Set(Object.entries(seen).reduce(function (arr, _a) {
64
+ var _b = __read(_a, 2), name = _b[0], count = _b[1];
65
+ return __spreadArray(__spreadArray([], __read(arr), false), __read((count > 1 ? [name] : [])), false);
66
+ }, []));
67
+ var inputs = texture2Dcalls.map(function (_a, index) {
68
+ var _b = __read(_a, 4), name = _b[0], parent = _b[1], key = _b[2], texture2dArgs = _b[3];
69
+ // Suffix input name if it's used more than once
70
+ var iName = names.has(name) ? "".concat(name, "_").concat(index) : name;
71
+ return [
72
+ nodeInput(iName, "filler_".concat(iName), 'filler', 'vector4', // Data type for what plugs into this filler
73
+ ['code', 'data'], false),
74
+ function (fillerAst) {
75
+ // @ts-ignore
76
+ parent[key] = fillerAst;
77
+ return ast;
78
+ },
79
+ texture2dArgs,
80
+ ];
81
+ });
82
+ return inputs;
83
+ };
@@ -0,0 +1,6 @@
1
+ import { BaseStrategy, ApplyStrategy, StrategyType } from '.';
2
+ export interface UniformStrategy extends BaseStrategy {
3
+ type: StrategyType.UNIFORM;
4
+ }
5
+ export declare const uniformStrategy: () => UniformStrategy;
6
+ export declare const applyUniformStrategy: ApplyStrategy<UniformStrategy>;