@babylonjs/smart-filters 1.0.12 → 8.18.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 (259) hide show
  1. package/dist/blockFoundation/aggregateBlock.d.ts +3 -3
  2. package/dist/blockFoundation/aggregateBlock.d.ts.map +1 -1
  3. package/dist/blockFoundation/aggregateBlock.js +1 -2
  4. package/dist/blockFoundation/aggregateBlock.js.map +1 -1
  5. package/dist/blockFoundation/baseBlock.d.ts +2 -2
  6. package/dist/blockFoundation/baseBlock.d.ts.map +1 -1
  7. package/dist/blockFoundation/baseBlock.js +5 -6
  8. package/dist/blockFoundation/baseBlock.js.map +1 -1
  9. package/dist/blockFoundation/customAggregateBlock.d.ts.map +1 -1
  10. package/dist/blockFoundation/customAggregateBlock.js +2 -2
  11. package/dist/blockFoundation/customAggregateBlock.js.map +1 -1
  12. package/dist/blockFoundation/customShaderBlock.d.ts.map +1 -1
  13. package/dist/blockFoundation/customShaderBlock.js +4 -6
  14. package/dist/blockFoundation/customShaderBlock.js.map +1 -1
  15. package/dist/blockFoundation/disableableShaderBlock.d.ts.map +1 -1
  16. package/dist/blockFoundation/disableableShaderBlock.js +4 -4
  17. package/dist/blockFoundation/disableableShaderBlock.js.map +1 -1
  18. package/dist/blockFoundation/index.js +0 -2
  19. package/dist/blockFoundation/index.js.map +1 -1
  20. package/dist/blockFoundation/inputBlock.d.ts +8 -8
  21. package/dist/blockFoundation/inputBlock.d.ts.map +1 -1
  22. package/dist/blockFoundation/inputBlock.deserializer.d.ts +1 -1
  23. package/dist/blockFoundation/inputBlock.deserializer.d.ts.map +1 -1
  24. package/dist/blockFoundation/inputBlock.deserializer.js +1 -1
  25. package/dist/blockFoundation/inputBlock.deserializer.js.map +1 -1
  26. package/dist/blockFoundation/inputBlock.js +7 -7
  27. package/dist/blockFoundation/inputBlock.js.map +1 -1
  28. package/dist/blockFoundation/inputBlock.serialization.types.d.ts.map +1 -1
  29. package/dist/blockFoundation/inputBlock.serializer.d.ts +1 -1
  30. package/dist/blockFoundation/inputBlock.serializer.js +26 -28
  31. package/dist/blockFoundation/inputBlock.serializer.js.map +1 -1
  32. package/dist/blockFoundation/outputBlock.d.ts +4 -9
  33. package/dist/blockFoundation/outputBlock.d.ts.map +1 -1
  34. package/dist/blockFoundation/outputBlock.js +13 -14
  35. package/dist/blockFoundation/outputBlock.js.map +1 -1
  36. package/dist/blockFoundation/shaderBlock.d.ts +4 -4
  37. package/dist/blockFoundation/shaderBlock.d.ts.map +1 -1
  38. package/dist/blockFoundation/shaderBlock.js +13 -19
  39. package/dist/blockFoundation/shaderBlock.js.map +1 -1
  40. package/dist/blockFoundation/textureOptions.d.ts +1 -1
  41. package/dist/blockFoundation/textureOptions.js +1 -1
  42. package/dist/command/command.d.ts +1 -1
  43. package/dist/command/command.js +1 -1
  44. package/dist/command/commandBuffer.d.ts +1 -1
  45. package/dist/command/commandBuffer.d.ts.map +1 -1
  46. package/dist/command/commandBuffer.js +2 -2
  47. package/dist/command/commandBufferDebugger.d.ts +2 -2
  48. package/dist/command/commandBufferDebugger.d.ts.map +1 -1
  49. package/dist/command/commandBufferDebugger.js +1 -1
  50. package/dist/command/commandBufferDebugger.js.map +1 -1
  51. package/dist/command/index.d.ts +3 -1
  52. package/dist/command/index.d.ts.map +1 -1
  53. package/dist/command/index.js +5 -1
  54. package/dist/command/index.js.map +1 -1
  55. package/dist/connection/connectionPoint.d.ts +3 -3
  56. package/dist/connection/connectionPoint.d.ts.map +1 -1
  57. package/dist/connection/connectionPoint.js +2 -2
  58. package/dist/connection/connectionPoint.js.map +1 -1
  59. package/dist/connection/connectionPointCompatibilityState.d.ts +1 -1
  60. package/dist/connection/connectionPointCompatibilityState.js +1 -1
  61. package/dist/connection/connectionPointType.d.ts +3 -3
  62. package/dist/connection/connectionPointType.d.ts.map +1 -1
  63. package/dist/connection/connectionPointWithDefault.d.ts +3 -3
  64. package/dist/connection/connectionPointWithDefault.d.ts.map +1 -1
  65. package/dist/connection/connectionPointWithDefault.js.map +1 -1
  66. package/dist/connection/index.d.ts +2 -1
  67. package/dist/connection/index.d.ts.map +1 -1
  68. package/dist/connection/index.js +3 -3
  69. package/dist/connection/index.js.map +1 -1
  70. package/dist/editorUtils/editableInPropertyPage.d.ts +2 -2
  71. package/dist/editorUtils/editableInPropertyPage.d.ts.map +1 -1
  72. package/dist/editorUtils/editableInPropertyPage.js +2 -2
  73. package/dist/editorUtils/editableInPropertyPage.js.map +1 -1
  74. package/dist/editorUtils/index.d.ts +1 -0
  75. package/dist/editorUtils/index.d.ts.map +1 -1
  76. package/dist/editorUtils/index.js +2 -0
  77. package/dist/editorUtils/index.js.map +1 -1
  78. package/dist/index.d.ts.map +1 -1
  79. package/dist/index.js +1 -1
  80. package/dist/index.js.map +1 -1
  81. package/dist/optimization/dependencyGraph.js.map +1 -1
  82. package/dist/optimization/optimizedShaderBlock.d.ts +4 -4
  83. package/dist/optimization/optimizedShaderBlock.d.ts.map +1 -1
  84. package/dist/optimization/optimizedShaderBlock.js.map +1 -1
  85. package/dist/optimization/smartFilterOptimizer.d.ts +2 -2
  86. package/dist/optimization/smartFilterOptimizer.d.ts.map +1 -1
  87. package/dist/optimization/smartFilterOptimizer.js +34 -57
  88. package/dist/optimization/smartFilterOptimizer.js.map +1 -1
  89. package/dist/runtime/index.d.ts +2 -1
  90. package/dist/runtime/index.d.ts.map +1 -1
  91. package/dist/runtime/index.js +3 -3
  92. package/dist/runtime/index.js.map +1 -1
  93. package/dist/runtime/renderTargetGenerator.d.ts +1 -1
  94. package/dist/runtime/renderTargetGenerator.d.ts.map +1 -1
  95. package/dist/runtime/renderTargetGenerator.js +5 -7
  96. package/dist/runtime/renderTargetGenerator.js.map +1 -1
  97. package/dist/runtime/shaderRuntime.d.ts +7 -7
  98. package/dist/runtime/shaderRuntime.d.ts.map +1 -1
  99. package/dist/runtime/shaderRuntime.js +7 -8
  100. package/dist/runtime/shaderRuntime.js.map +1 -1
  101. package/dist/runtime/smartFilterRuntime.d.ts +3 -3
  102. package/dist/runtime/smartFilterRuntime.d.ts.map +1 -1
  103. package/dist/runtime/smartFilterRuntime.js.map +1 -1
  104. package/dist/runtime/strongRef.d.ts +1 -1
  105. package/dist/runtime/strongRef.js +1 -1
  106. package/dist/serialization/importCustomBlockDefinition.d.ts +1 -1
  107. package/dist/serialization/importCustomBlockDefinition.js +8 -9
  108. package/dist/serialization/importCustomBlockDefinition.js.map +1 -1
  109. package/dist/serialization/index.d.ts +1 -0
  110. package/dist/serialization/index.d.ts.map +1 -1
  111. package/dist/serialization/index.js +3 -0
  112. package/dist/serialization/index.js.map +1 -1
  113. package/dist/serialization/serializedBlockDefinition.d.ts +2 -2
  114. package/dist/serialization/serializedBlockDefinition.d.ts.map +1 -1
  115. package/dist/serialization/serializedShaderBlockDefinition.d.ts +1 -1
  116. package/dist/serialization/serializedShaderBlockDefinition.d.ts.map +1 -1
  117. package/dist/serialization/serializedSmartFilter.d.ts +1 -1
  118. package/dist/serialization/serializedSmartFilter.d.ts.map +1 -1
  119. package/dist/serialization/smartFilterDeserializer.d.ts +6 -6
  120. package/dist/serialization/smartFilterDeserializer.d.ts.map +1 -1
  121. package/dist/serialization/smartFilterDeserializer.js +14 -12
  122. package/dist/serialization/smartFilterDeserializer.js.map +1 -1
  123. package/dist/serialization/smartFilterSerializer.d.ts +2 -2
  124. package/dist/serialization/smartFilterSerializer.d.ts.map +1 -1
  125. package/dist/serialization/smartFilterSerializer.js +10 -13
  126. package/dist/serialization/smartFilterSerializer.js.map +1 -1
  127. package/dist/serialization/v1/defaultBlockSerializer.d.ts +2 -2
  128. package/dist/serialization/v1/defaultBlockSerializer.d.ts.map +1 -1
  129. package/dist/serialization/v1/defaultBlockSerializer.js +3 -1
  130. package/dist/serialization/v1/defaultBlockSerializer.js.map +1 -1
  131. package/dist/serialization/v1/index.d.ts +1 -0
  132. package/dist/serialization/v1/index.d.ts.map +1 -1
  133. package/dist/serialization/v1/index.js +2 -0
  134. package/dist/serialization/v1/index.js.map +1 -1
  135. package/dist/serialization/v1/shaderBlockSerialization.types.d.ts +3 -3
  136. package/dist/serialization/v1/shaderBlockSerialization.types.d.ts.map +1 -1
  137. package/dist/serialization/v1/smartFilterSerialization.types.d.ts +5 -2
  138. package/dist/serialization/v1/smartFilterSerialization.types.d.ts.map +1 -1
  139. package/dist/smartFilter.d.ts +8 -8
  140. package/dist/smartFilter.d.ts.map +1 -1
  141. package/dist/smartFilter.js +6 -7
  142. package/dist/smartFilter.js.map +1 -1
  143. package/dist/utils/buildTools/buildShaders.d.ts +3 -2
  144. package/dist/utils/buildTools/buildShaders.d.ts.map +1 -1
  145. package/dist/utils/buildTools/buildShaders.js +7 -6
  146. package/dist/utils/buildTools/buildShaders.js.map +1 -1
  147. package/dist/utils/buildTools/convertGlslIntoBlock.d.ts +4 -2
  148. package/dist/utils/buildTools/convertGlslIntoBlock.d.ts.map +1 -1
  149. package/dist/utils/buildTools/convertGlslIntoBlock.js +136 -141
  150. package/dist/utils/buildTools/convertGlslIntoBlock.js.map +1 -1
  151. package/dist/utils/buildTools/convertGlslIntoShaderProgram.d.ts +4 -4
  152. package/dist/utils/buildTools/convertGlslIntoShaderProgram.d.ts.map +1 -1
  153. package/dist/utils/buildTools/convertGlslIntoShaderProgram.js +55 -48
  154. package/dist/utils/buildTools/convertGlslIntoShaderProgram.js.map +1 -1
  155. package/dist/utils/buildTools/convertShaders.d.ts +8 -5
  156. package/dist/utils/buildTools/convertShaders.d.ts.map +1 -1
  157. package/dist/utils/buildTools/convertShaders.js +38 -14
  158. package/dist/utils/buildTools/convertShaders.js.map +1 -1
  159. package/dist/utils/buildTools/shaderConverter.d.ts +4 -4
  160. package/dist/utils/buildTools/shaderConverter.d.ts.map +1 -1
  161. package/dist/utils/buildTools/shaderConverter.js +17 -21
  162. package/dist/utils/buildTools/shaderConverter.js.map +1 -1
  163. package/dist/utils/buildTools/watchShaders.d.ts +3 -2
  164. package/dist/utils/buildTools/watchShaders.d.ts.map +1 -1
  165. package/dist/utils/buildTools/watchShaders.js +10 -8
  166. package/dist/utils/buildTools/watchShaders.js.map +1 -1
  167. package/dist/utils/index.d.ts +1 -0
  168. package/dist/utils/index.d.ts.map +1 -1
  169. package/dist/utils/index.js +2 -1
  170. package/dist/utils/index.js.map +1 -1
  171. package/dist/utils/renderTargetUtils.d.ts +3 -3
  172. package/dist/utils/renderTargetUtils.d.ts.map +1 -1
  173. package/dist/utils/renderTargetUtils.js +4 -4
  174. package/dist/utils/renderTargetUtils.js.map +1 -1
  175. package/dist/utils/shaderCodeUtils.d.ts +8 -8
  176. package/dist/utils/shaderCodeUtils.d.ts.map +1 -1
  177. package/dist/utils/shaderCodeUtils.js +16 -28
  178. package/dist/utils/shaderCodeUtils.js.map +1 -1
  179. package/dist/utils/textureLoaders.d.ts +2 -2
  180. package/dist/utils/textureLoaders.d.ts.map +1 -1
  181. package/dist/utils/textureLoaders.js +2 -3
  182. package/dist/utils/textureLoaders.js.map +1 -1
  183. package/dist/utils/textureUtils.d.ts +5 -5
  184. package/dist/utils/textureUtils.d.ts.map +1 -1
  185. package/dist/utils/textureUtils.js +1 -1
  186. package/dist/utils/textureUtils.js.map +1 -1
  187. package/dist/version.d.ts +2 -2
  188. package/dist/version.js +2 -2
  189. package/license.md +21 -21
  190. package/package.json +14 -9
  191. package/src/blockFoundation/aggregateBlock.ts +148 -151
  192. package/src/blockFoundation/baseBlock.ts +339 -364
  193. package/src/blockFoundation/customAggregateBlock.ts +88 -104
  194. package/src/blockFoundation/customShaderBlock.ts +312 -326
  195. package/src/blockFoundation/disableableShaderBlock.ts +91 -100
  196. package/src/blockFoundation/index.ts +9 -9
  197. package/src/blockFoundation/inputBlock.deserializer.ts +72 -97
  198. package/src/blockFoundation/inputBlock.serialization.types.ts +126 -132
  199. package/src/blockFoundation/inputBlock.serializer.ts +150 -150
  200. package/src/blockFoundation/inputBlock.ts +181 -192
  201. package/src/blockFoundation/outputBlock.ts +144 -151
  202. package/src/blockFoundation/shaderBlock.ts +156 -163
  203. package/src/blockFoundation/textureOptions.ts +57 -57
  204. package/src/command/command.ts +59 -59
  205. package/src/command/commandBuffer.ts +71 -71
  206. package/src/command/commandBufferDebugger.ts +14 -14
  207. package/src/command/index.ts +7 -3
  208. package/src/connection/connectionPoint.ts +205 -214
  209. package/src/connection/connectionPointCompatibilityState.ts +31 -31
  210. package/src/connection/connectionPointType.ts +45 -45
  211. package/src/connection/connectionPointWithDefault.ts +27 -35
  212. package/src/connection/index.ts +8 -9
  213. package/src/editorUtils/editableInPropertyPage.ts +106 -106
  214. package/src/editorUtils/index.ts +3 -1
  215. package/src/index.ts +16 -15
  216. package/src/optimization/dependencyGraph.ts +96 -96
  217. package/src/optimization/index.ts +1 -1
  218. package/src/optimization/optimizedShaderBlock.ts +131 -134
  219. package/src/optimization/smartFilterOptimizer.ts +757 -825
  220. package/src/runtime/index.ts +8 -6
  221. package/src/runtime/renderTargetGenerator.ts +222 -248
  222. package/src/runtime/shaderRuntime.ts +174 -173
  223. package/src/runtime/smartFilterRuntime.ts +112 -112
  224. package/src/runtime/strongRef.ts +18 -18
  225. package/src/serialization/importCustomBlockDefinition.ts +86 -86
  226. package/src/serialization/index.ts +10 -7
  227. package/src/serialization/serializedBlockDefinition.ts +12 -12
  228. package/src/serialization/serializedShaderBlockDefinition.ts +7 -7
  229. package/src/serialization/serializedSmartFilter.ts +6 -6
  230. package/src/serialization/smartFilterDeserializer.ts +190 -214
  231. package/src/serialization/smartFilterSerializer.ts +110 -121
  232. package/src/serialization/v1/defaultBlockSerializer.ts +21 -19
  233. package/src/serialization/v1/index.ts +4 -2
  234. package/src/serialization/v1/shaderBlockSerialization.types.ts +85 -85
  235. package/src/serialization/v1/smartFilterSerialization.types.ts +129 -129
  236. package/src/smartFilter.ts +255 -260
  237. package/src/utils/buildTools/buildShaders.ts +14 -13
  238. package/src/utils/buildTools/convertGlslIntoBlock.ts +370 -385
  239. package/src/utils/buildTools/convertGlslIntoShaderProgram.ts +173 -172
  240. package/src/utils/buildTools/convertShaders.ts +65 -43
  241. package/src/utils/buildTools/recordVersionNumber.js +17 -0
  242. package/src/utils/buildTools/shaderConverter.ts +466 -478
  243. package/src/utils/buildTools/watchShaders.ts +44 -42
  244. package/src/utils/index.ts +4 -2
  245. package/src/utils/renderTargetUtils.ts +30 -35
  246. package/src/utils/shaderCodeUtils.ts +192 -207
  247. package/src/utils/textureLoaders.ts +31 -43
  248. package/src/utils/textureUtils.ts +28 -32
  249. package/src/version.ts +2 -2
  250. package/dist/utils/buildTools/determineVersion.d.ts +0 -36
  251. package/dist/utils/buildTools/determineVersion.d.ts.map +0 -1
  252. package/dist/utils/buildTools/determineVersion.js +0 -109
  253. package/dist/utils/buildTools/determineVersion.js.map +0 -1
  254. package/dist/utils/buildTools/versionUp.d.ts +0 -2
  255. package/dist/utils/buildTools/versionUp.d.ts.map +0 -1
  256. package/dist/utils/buildTools/versionUp.js +0 -53
  257. package/dist/utils/buildTools/versionUp.js.map +0 -1
  258. package/src/utils/buildTools/determineVersion.ts +0 -128
  259. package/src/utils/buildTools/versionUp.ts +0 -61
@@ -1,364 +1,339 @@
1
- import type { Nullable } from "@babylonjs/core/types";
2
- import { ConnectionPointType, type ConnectionPointValue } from "../connection/connectionPointType.js";
3
- import type { InitializationData, SmartFilter } from "../smartFilter.js";
4
- import type { ICommandOwner } from "../command/command.js";
5
- import { ConnectionPoint, type RuntimeData } from "../connection/connectionPoint.js";
6
- import { ConnectionPointWithDefault } from "../connection/connectionPointWithDefault.js";
7
- import { ConnectionPointDirection } from "../connection/connectionPointDirection.js";
8
- import { UniqueIdGenerator } from "../utils/uniqueIdGenerator.js";
9
-
10
- /**
11
- * Defines a callback function that is triggered when visiting a block,
12
- * It also carries over extra data preventing the need to use global variables or closures.
13
- */
14
- export type BlockVisitor<T extends object> = (block: BaseBlock, extraData: T) => void;
15
-
16
- /**
17
- * This class represents the base class for all smart filter blocks.
18
- *
19
- * It defines the basic structure of a smart filter block and provides the base implementation for
20
- * managing the connection points.
21
- *
22
- * It enforces common behavior for all smart filter blocks.
23
- */
24
- export abstract class BaseBlock implements ICommandOwner {
25
- protected static _alreadyVisitedBlocks = new Set<BaseBlock>();
26
-
27
- /**
28
- * The class name of the block.
29
- */
30
- public static ClassName = "BaseBlock";
31
-
32
- /**
33
- * The namespace of the block, which is used to reduce name collisions between blocks and also to group blocks in the editor UI.
34
- * By convention, sub namespaces are separated by a period (e.g. "Babylon.Demo.Effects").
35
- */
36
- public static Namespace: Nullable<string> = null;
37
-
38
- /**
39
- * The smart filter the block belongs to.
40
- */
41
- public readonly smartFilter: SmartFilter;
42
-
43
- /**
44
- * Global unique id of the block (This is unique for the current session).
45
- */
46
- public uniqueId: number;
47
-
48
- /**
49
- * The name of the block. This is used to identify the block in the smart filter or in debug.
50
- */
51
- public readonly name: string;
52
-
53
- /**
54
- * The type of the block - used when serializing / deserializing the block, and in the editor.
55
- * For programmatically created blocks, this should be the class name of the block.
56
- * For custom blocks, this is specified in the block definition.
57
- */
58
- public get blockType(): string {
59
- return this.getClassName();
60
- }
61
-
62
- /**
63
- * The namespace of the block, which is used to reduce name collisions between blocks and also to group blocks in the editor UI.
64
- * By convention, sub namespaces are separated by a period (e.g. "Babylon.Demo.Effects").
65
- */
66
- public get namespace(): Nullable<string> {
67
- // Note that we use a static property instead of doing this.constructor.name to avoid problems with minifiers that would change the name of the class
68
- return (this.constructor as typeof BaseBlock).Namespace;
69
- }
70
-
71
- /**
72
- * User provided comments about the block. It can be used to document the block.
73
- */
74
- public comments: Nullable<string> = null;
75
-
76
- private readonly _inputs: ConnectionPoint[] = [];
77
- private readonly _outputs: ConnectionPoint[] = [];
78
-
79
- /**
80
- * Instantiates a new block.
81
- * @param smartFilter - Defines the smart filter the block belongs to
82
- * @param name - Defines the name of the block
83
- * @param disableOptimization - Defines if the block is optimizable or not
84
- */
85
- constructor(
86
- smartFilter: SmartFilter,
87
- name: string,
88
- public readonly disableOptimization = false
89
- ) {
90
- this.uniqueId = UniqueIdGenerator.UniqueId;
91
- this.name = name;
92
- this.smartFilter = smartFilter;
93
-
94
- // Register the block in the smart filter
95
- smartFilter.registerBlock(this);
96
- }
97
-
98
- /**
99
- * Returns the inputs connection points of the current block.
100
- */
101
- public get inputs(): ReadonlyArray<ConnectionPoint> {
102
- return this._inputs;
103
- }
104
-
105
- /**
106
- * Returns the outputs connection points of the current block.
107
- */
108
- public get outputs(): ReadonlyArray<ConnectionPoint> {
109
- return this._outputs;
110
- }
111
-
112
- /**
113
- * Returns if the block is an input block.
114
- */
115
- public get isInput(): boolean {
116
- return this._inputs.length === 0;
117
- }
118
-
119
- /**
120
- * Returns if the block is an output block.
121
- */
122
- public get isOutput(): boolean {
123
- return this._outputs.length === 0;
124
- }
125
-
126
- /**
127
- * @returns the class name of the block
128
- */
129
- public getClassName(): string {
130
- // Note that we use a static property instead of doing this.constructor.name to avoid problems with minifiers that would change the name of the class
131
- return (this.constructor as typeof BaseBlock).ClassName;
132
- }
133
-
134
- /**
135
- * Checks if the block is an "ancestor" of another giving block.
136
- * @param block - Defines the block to check against
137
- * @returns True if the block is an ancestor of the given block, otherwise false
138
- */
139
- public isAnAncestorOf(block: BaseBlock): boolean {
140
- for (const output of this._outputs) {
141
- if (!output.endpoints.length) {
142
- continue;
143
- }
144
-
145
- for (const endpoint of output.endpoints) {
146
- if (endpoint.ownerBlock === block) {
147
- return true;
148
- }
149
- if (endpoint.ownerBlock.isAnAncestorOf(block)) {
150
- return true;
151
- }
152
- }
153
- }
154
-
155
- return false;
156
- }
157
-
158
- protected _visitInputs<T extends object>(
159
- extraData: T,
160
- callback: BlockVisitor<T>,
161
- alreadyVisited: Set<BaseBlock>
162
- ): void {
163
- for (const input of this.inputs) {
164
- if (!input.connectedTo) {
165
- continue;
166
- }
167
-
168
- const block = input.connectedTo.ownerBlock;
169
-
170
- block.visit(extraData, callback, alreadyVisited);
171
- }
172
- }
173
-
174
- /**
175
- * Visits the block and its inputs recursively.
176
- * When starting from the smart filter output block, this will visit all the blocks in the smart filter.
177
- * Note that it's a depth first visit: the callback is called on the block AFTER visiting its inputs.
178
- * @param extraData - The extra data to pass to the callback
179
- * @param callback - The callback to call on each block
180
- * @param alreadyVisitedBlocks - Defines the set of blocks already visited (if not provided, a new set will be created)
181
- */
182
- public visit<T extends object>(
183
- extraData: T,
184
- callback: BlockVisitor<T>,
185
- alreadyVisitedBlocks?: Set<BaseBlock>
186
- ): void {
187
- if (!alreadyVisitedBlocks) {
188
- alreadyVisitedBlocks = BaseBlock._alreadyVisitedBlocks;
189
- alreadyVisitedBlocks.clear();
190
- }
191
-
192
- if (!alreadyVisitedBlocks.has(this)) {
193
- alreadyVisitedBlocks.add(this);
194
-
195
- this._visitInputs(extraData, callback, alreadyVisitedBlocks);
196
-
197
- callback(this, extraData);
198
- }
199
- }
200
-
201
- /**
202
- * Finds the input connection point with the given name.
203
- * @param name - Name of the input to find
204
- * @returns The connection point with the given name or null if not found
205
- */
206
- public findInput<U extends ConnectionPointType>(name: string): Nullable<ConnectionPoint<U>> {
207
- for (const input of this._inputs) {
208
- if (input.name === name) {
209
- return input as ConnectionPoint<U>;
210
- }
211
- }
212
-
213
- return null;
214
- }
215
-
216
- /**
217
- * Disconnects the block from the graph.
218
- * @param _disconnectedConnections - Stores the connections that have been broken in the process. You can reconnect them later if needed.
219
- */
220
- public disconnectFromGraph(_disconnectedConnections?: [ConnectionPoint, ConnectionPoint][]): void {}
221
-
222
- /**
223
- * Prepares the block for runtime.
224
- * This is called by the smart filter just before creating the smart filter runtime, and by the optimizer.
225
- */
226
- public prepareForRuntime(): void {}
227
-
228
- /**
229
- * Propagates the runtime data - telling all outputs to propagate their runtime data forward through the graph
230
- */
231
- public propagateRuntimeData(): void {
232
- for (const output of this._outputs) {
233
- output.propagateRuntimeData();
234
- }
235
- }
236
-
237
- /**
238
- * Generates the commands needed to execute the block at runtime and gathers promises for initialization work
239
- * @param initializationData - The initialization data to use
240
- * @param _finalOutput - Defines if the block is the final output of the smart filter
241
- */
242
- public generateCommandsAndGatherInitPromises(initializationData: InitializationData, _finalOutput: boolean): void {
243
- // Check if any inputs are Textures which aren't yet ready, and if so, ensure init waits for them to be ready
244
- for (const input of this._inputs) {
245
- if (input.type === ConnectionPointType.Texture) {
246
- const texture = input.runtimeData?.value as ConnectionPointValue<ConnectionPointType.Texture>;
247
- if (texture && !texture.isReady()) {
248
- const internalTexture = texture.getInternalTexture();
249
- if (internalTexture) {
250
- const textureReadyPromise = new Promise<void>((resolve, reject) => {
251
- internalTexture.onLoadedObservable.add(() => {
252
- resolve();
253
- });
254
- internalTexture.onErrorObservable.add((error) => {
255
- reject(error);
256
- });
257
- });
258
- initializationData.initializationPromises.push(textureReadyPromise);
259
- }
260
- }
261
- }
262
- }
263
- }
264
-
265
- /**
266
- * Disconnects all the inputs and outputs from the Block.
267
- */
268
- public disconnect(): void {
269
- // Detach inputs
270
- for (const input of this._inputs) {
271
- input.connectedTo?.disconnectFrom(input);
272
- }
273
-
274
- // Detach outputs
275
- for (const output of this._outputs) {
276
- output.disconnectAllEndpoints();
277
- }
278
- }
279
-
280
- /**
281
- * Registers a new input connection point in the block which must have a connection before the graph can be used.
282
- * @param name - Defines the name of the input connection point
283
- * @param type - Defines the type of the input connection point
284
- * @param defaultValue - Defines the optional default value of the input connection point to use if not connection is made
285
- * @returns The new ConnectionPoint
286
- * @internal
287
- */
288
- public _registerInput<U extends ConnectionPointType>(
289
- name: string,
290
- type: U,
291
- defaultValue: Nullable<RuntimeData<U>> = null
292
- ): ConnectionPoint<U> {
293
- const input = new ConnectionPoint(name, this, type, ConnectionPointDirection.Input, defaultValue);
294
- this._inputs.push(input);
295
- return input;
296
- }
297
-
298
- /**
299
- * Registers a new input connection point in the block which doesn't require a connection because it has a default value.
300
- * @param name - Defines the name of the input connection point
301
- * @param type - Defines the type of the input connection point
302
- * @param defaultValue - Defines the default value to use if nothing is connected to this connection point
303
- * @returns The new ConnectionPointWithDefault
304
- * @internal
305
- */
306
- public _registerOptionalInput<U extends ConnectionPointType>(
307
- name: string,
308
- type: U,
309
- defaultValue: RuntimeData<U>
310
- ): ConnectionPointWithDefault<U> {
311
- const input = new ConnectionPointWithDefault(name, this, type, ConnectionPointDirection.Input, defaultValue);
312
- this._inputs.push(input);
313
- return input;
314
- }
315
-
316
- /**
317
- * Registers a new output connection point in the block.
318
- * @param name - Defines the name of the output connection point
319
- * @param type - Defines the type of the output connection point
320
- * @returns The new output connection point
321
- * @internal
322
- */
323
- public _registerOutput<U extends ConnectionPointType>(name: string, type: U): ConnectionPoint<U> {
324
- const output = new ConnectionPoint(name, this, type, ConnectionPointDirection.Output);
325
- this._outputs.push(output);
326
- return output;
327
- }
328
-
329
- /**
330
- * Registers a new output connection point in the block that always has runtimeData because it has a default value and doesn't allow it to be overwritten with null.
331
- * @param name - Defines the name of the output connection point
332
- * @param type - Defines the type of the output connection point
333
- * @param initialValue - Defines the initial value of the output connection point
334
- * @returns The new output connection point with a default value
335
- * @internal
336
- */
337
- public _registerOutputWithDefault<U extends ConnectionPointType>(
338
- name: string,
339
- type: U,
340
- initialValue: RuntimeData<U>
341
- ): ConnectionPointWithDefault<U> {
342
- const output = new ConnectionPointWithDefault(name, this, type, ConnectionPointDirection.Output, initialValue);
343
- this._outputs.push(output);
344
- return output;
345
- }
346
-
347
- /**
348
- * Gets the required RuntimeData for the given input, throwing with a clear message if it is null
349
- * @param input - The input to get the runtime data for
350
- * @returns The runtimeData or throws if it was undefined
351
- */
352
- protected _confirmRuntimeDataSupplied<U extends ConnectionPointType = ConnectionPointType>(
353
- input: ConnectionPoint<U>
354
- ): RuntimeData<U> {
355
- if (!input.runtimeData) {
356
- throw new Error(
357
- `The ${ConnectionPointType[input.type]} input named "${
358
- input.name
359
- }" is missing for the ${this.getClassName()} named "${this.name}"`
360
- );
361
- }
362
- return input.runtimeData;
363
- }
364
- }
1
+ import type { Nullable } from "core/types.js";
2
+ import { ConnectionPointType, type ConnectionPointValue } from "../connection/connectionPointType.js";
3
+ import type { InitializationData, SmartFilter } from "../smartFilter.js";
4
+ import type { ICommandOwner } from "../command/command.js";
5
+ import { ConnectionPoint, type RuntimeData } from "../connection/connectionPoint.js";
6
+ import { ConnectionPointWithDefault } from "../connection/connectionPointWithDefault.js";
7
+ import { ConnectionPointDirection } from "../connection/connectionPointDirection.js";
8
+ import { UniqueIdGenerator } from "../utils/uniqueIdGenerator.js";
9
+
10
+ /**
11
+ * Defines a callback function that is triggered when visiting a block,
12
+ * It also carries over extra data preventing the need to use global variables or closures.
13
+ */
14
+ export type BlockVisitor<T extends object> = (block: BaseBlock, extraData: T) => void;
15
+
16
+ /**
17
+ * This class represents the base class for all smart filter blocks.
18
+ *
19
+ * It defines the basic structure of a smart filter block and provides the base implementation for
20
+ * managing the connection points.
21
+ *
22
+ * It enforces common behavior for all smart filter blocks.
23
+ */
24
+ export abstract class BaseBlock implements ICommandOwner {
25
+ protected static _AlreadyVisitedBlocks = new Set<BaseBlock>();
26
+
27
+ /**
28
+ * The class name of the block.
29
+ */
30
+ public static ClassName = "BaseBlock";
31
+
32
+ /**
33
+ * The namespace of the block, which is used to reduce name collisions between blocks and also to group blocks in the editor UI.
34
+ * By convention, sub namespaces are separated by a period (e.g. "Babylon.Demo.Effects").
35
+ */
36
+ public static Namespace: Nullable<string> = null;
37
+
38
+ /**
39
+ * The smart filter the block belongs to.
40
+ */
41
+ public readonly smartFilter: SmartFilter;
42
+
43
+ /**
44
+ * Global unique id of the block (This is unique for the current session).
45
+ */
46
+ public uniqueId: number;
47
+
48
+ /**
49
+ * The name of the block. This is used to identify the block in the smart filter or in debug.
50
+ */
51
+ public readonly name: string;
52
+
53
+ /**
54
+ * The type of the block - used when serializing / deserializing the block, and in the editor.
55
+ * For programmatically created blocks, this should be the class name of the block.
56
+ * For custom blocks, this is specified in the block definition.
57
+ */
58
+ public get blockType(): string {
59
+ return this.getClassName();
60
+ }
61
+
62
+ /**
63
+ * The namespace of the block, which is used to reduce name collisions between blocks and also to group blocks in the editor UI.
64
+ * By convention, sub namespaces are separated by a period (e.g. "Babylon.Demo.Effects").
65
+ */
66
+ public get namespace(): Nullable<string> {
67
+ // Note that we use a static property instead of doing this.constructor.name to avoid problems with minifiers that would change the name of the class
68
+ return (this.constructor as typeof BaseBlock).Namespace;
69
+ }
70
+
71
+ /**
72
+ * User provided comments about the block. It can be used to document the block.
73
+ */
74
+ public comments: Nullable<string> = null;
75
+
76
+ private readonly _inputs: ConnectionPoint[] = [];
77
+ private readonly _outputs: ConnectionPoint[] = [];
78
+
79
+ /**
80
+ * Instantiates a new block.
81
+ * @param smartFilter - Defines the smart filter the block belongs to
82
+ * @param name - Defines the name of the block
83
+ * @param disableOptimization - Defines if the block is optimizable or not
84
+ */
85
+ constructor(
86
+ smartFilter: SmartFilter,
87
+ name: string,
88
+ public readonly disableOptimization = false
89
+ ) {
90
+ this.uniqueId = UniqueIdGenerator.UniqueId;
91
+ this.name = name;
92
+ this.smartFilter = smartFilter;
93
+
94
+ // Register the block in the smart filter
95
+ smartFilter.registerBlock(this);
96
+ }
97
+
98
+ /**
99
+ * Returns the inputs connection points of the current block.
100
+ */
101
+ public get inputs(): ReadonlyArray<ConnectionPoint> {
102
+ return this._inputs;
103
+ }
104
+
105
+ /**
106
+ * Returns the outputs connection points of the current block.
107
+ */
108
+ public get outputs(): ReadonlyArray<ConnectionPoint> {
109
+ return this._outputs;
110
+ }
111
+
112
+ /**
113
+ * Returns if the block is an input block.
114
+ */
115
+ public get isInput(): boolean {
116
+ return this._inputs.length === 0;
117
+ }
118
+
119
+ /**
120
+ * Returns if the block is an output block.
121
+ */
122
+ public get isOutput(): boolean {
123
+ return this._outputs.length === 0;
124
+ }
125
+
126
+ /**
127
+ * @returns the class name of the block
128
+ */
129
+ public getClassName(): string {
130
+ // Note that we use a static property instead of doing this.constructor.name to avoid problems with minifiers that would change the name of the class
131
+ return (this.constructor as typeof BaseBlock).ClassName;
132
+ }
133
+
134
+ /**
135
+ * Checks if the block is an "ancestor" of another giving block.
136
+ * @param block - Defines the block to check against
137
+ * @returns True if the block is an ancestor of the given block, otherwise false
138
+ */
139
+ public isAnAncestorOf(block: BaseBlock): boolean {
140
+ for (const output of this._outputs) {
141
+ if (!output.endpoints.length) {
142
+ continue;
143
+ }
144
+
145
+ for (const endpoint of output.endpoints) {
146
+ if (endpoint.ownerBlock === block) {
147
+ return true;
148
+ }
149
+ if (endpoint.ownerBlock.isAnAncestorOf(block)) {
150
+ return true;
151
+ }
152
+ }
153
+ }
154
+
155
+ return false;
156
+ }
157
+
158
+ protected _visitInputs<T extends object>(extraData: T, callback: BlockVisitor<T>, alreadyVisited: Set<BaseBlock>): void {
159
+ for (const input of this.inputs) {
160
+ if (!input.connectedTo) {
161
+ continue;
162
+ }
163
+
164
+ const block = input.connectedTo.ownerBlock;
165
+
166
+ block.visit(extraData, callback, alreadyVisited);
167
+ }
168
+ }
169
+
170
+ /**
171
+ * Visits the block and its inputs recursively.
172
+ * When starting from the smart filter output block, this will visit all the blocks in the smart filter.
173
+ * Note that it's a depth first visit: the callback is called on the block AFTER visiting its inputs.
174
+ * @param extraData - The extra data to pass to the callback
175
+ * @param callback - The callback to call on each block
176
+ * @param alreadyVisitedBlocks - Defines the set of blocks already visited (if not provided, a new set will be created)
177
+ */
178
+ public visit<T extends object>(extraData: T, callback: BlockVisitor<T>, alreadyVisitedBlocks?: Set<BaseBlock>): void {
179
+ if (!alreadyVisitedBlocks) {
180
+ alreadyVisitedBlocks = BaseBlock._AlreadyVisitedBlocks;
181
+ alreadyVisitedBlocks.clear();
182
+ }
183
+
184
+ if (!alreadyVisitedBlocks.has(this)) {
185
+ alreadyVisitedBlocks.add(this);
186
+
187
+ this._visitInputs(extraData, callback, alreadyVisitedBlocks);
188
+
189
+ callback(this, extraData);
190
+ }
191
+ }
192
+
193
+ /**
194
+ * Finds the input connection point with the given name.
195
+ * @param name - Name of the input to find
196
+ * @returns The connection point with the given name or null if not found
197
+ */
198
+ public findInput<U extends ConnectionPointType>(name: string): Nullable<ConnectionPoint<U>> {
199
+ for (const input of this._inputs) {
200
+ if (input.name === name) {
201
+ return input as ConnectionPoint<U>;
202
+ }
203
+ }
204
+
205
+ return null;
206
+ }
207
+
208
+ /**
209
+ * Disconnects the block from the graph.
210
+ * @param _disconnectedConnections - Stores the connections that have been broken in the process. You can reconnect them later if needed.
211
+ */
212
+ public disconnectFromGraph(_disconnectedConnections?: [ConnectionPoint, ConnectionPoint][]): void {}
213
+
214
+ /**
215
+ * Prepares the block for runtime.
216
+ * This is called by the smart filter just before creating the smart filter runtime, and by the optimizer.
217
+ */
218
+ public prepareForRuntime(): void {}
219
+
220
+ /**
221
+ * Propagates the runtime data - telling all outputs to propagate their runtime data forward through the graph
222
+ */
223
+ public propagateRuntimeData(): void {
224
+ for (const output of this._outputs) {
225
+ output.propagateRuntimeData();
226
+ }
227
+ }
228
+
229
+ /**
230
+ * Generates the commands needed to execute the block at runtime and gathers promises for initialization work
231
+ * @param initializationData - The initialization data to use
232
+ * @param _finalOutput - Defines if the block is the final output of the smart filter
233
+ */
234
+ public generateCommandsAndGatherInitPromises(initializationData: InitializationData, _finalOutput: boolean): void {
235
+ // Check if any inputs are Textures which aren't yet ready, and if so, ensure init waits for them to be ready
236
+ for (const input of this._inputs) {
237
+ if (input.type === ConnectionPointType.Texture) {
238
+ const texture = input.runtimeData?.value as ConnectionPointValue<ConnectionPointType.Texture>;
239
+ if (texture && !texture.isReady()) {
240
+ const internalTexture = texture.getInternalTexture();
241
+ if (internalTexture) {
242
+ const textureReadyPromise = new Promise<void>((resolve, reject) => {
243
+ internalTexture.onLoadedObservable.add(() => {
244
+ resolve();
245
+ });
246
+ internalTexture.onErrorObservable.add((error) => {
247
+ // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
248
+ reject(error);
249
+ });
250
+ });
251
+ initializationData.initializationPromises.push(textureReadyPromise);
252
+ }
253
+ }
254
+ }
255
+ }
256
+ }
257
+
258
+ /**
259
+ * Disconnects all the inputs and outputs from the Block.
260
+ */
261
+ public disconnect(): void {
262
+ // Detach inputs
263
+ for (const input of this._inputs) {
264
+ input.connectedTo?.disconnectFrom(input);
265
+ }
266
+
267
+ // Detach outputs
268
+ for (const output of this._outputs) {
269
+ output.disconnectAllEndpoints();
270
+ }
271
+ }
272
+
273
+ /**
274
+ * Registers a new input connection point in the block which must have a connection before the graph can be used.
275
+ * @param name - Defines the name of the input connection point
276
+ * @param type - Defines the type of the input connection point
277
+ * @param defaultValue - Defines the optional default value of the input connection point to use if not connection is made
278
+ * @returns The new ConnectionPoint
279
+ * @internal
280
+ */
281
+ public _registerInput<U extends ConnectionPointType>(name: string, type: U, defaultValue: Nullable<RuntimeData<U>> = null): ConnectionPoint<U> {
282
+ const input = new ConnectionPoint(name, this, type, ConnectionPointDirection.Input, defaultValue);
283
+ this._inputs.push(input);
284
+ return input;
285
+ }
286
+
287
+ /**
288
+ * Registers a new input connection point in the block which doesn't require a connection because it has a default value.
289
+ * @param name - Defines the name of the input connection point
290
+ * @param type - Defines the type of the input connection point
291
+ * @param defaultValue - Defines the default value to use if nothing is connected to this connection point
292
+ * @returns The new ConnectionPointWithDefault
293
+ * @internal
294
+ */
295
+ public _registerOptionalInput<U extends ConnectionPointType>(name: string, type: U, defaultValue: RuntimeData<U>): ConnectionPointWithDefault<U> {
296
+ const input = new ConnectionPointWithDefault(name, this, type, ConnectionPointDirection.Input, defaultValue);
297
+ this._inputs.push(input);
298
+ return input;
299
+ }
300
+
301
+ /**
302
+ * Registers a new output connection point in the block.
303
+ * @param name - Defines the name of the output connection point
304
+ * @param type - Defines the type of the output connection point
305
+ * @returns The new output connection point
306
+ * @internal
307
+ */
308
+ public _registerOutput<U extends ConnectionPointType>(name: string, type: U): ConnectionPoint<U> {
309
+ const output = new ConnectionPoint(name, this, type, ConnectionPointDirection.Output);
310
+ this._outputs.push(output);
311
+ return output;
312
+ }
313
+
314
+ /**
315
+ * Registers a new output connection point in the block that always has runtimeData because it has a default value and doesn't allow it to be overwritten with null.
316
+ * @param name - Defines the name of the output connection point
317
+ * @param type - Defines the type of the output connection point
318
+ * @param initialValue - Defines the initial value of the output connection point
319
+ * @returns The new output connection point with a default value
320
+ * @internal
321
+ */
322
+ public _registerOutputWithDefault<U extends ConnectionPointType>(name: string, type: U, initialValue: RuntimeData<U>): ConnectionPointWithDefault<U> {
323
+ const output = new ConnectionPointWithDefault(name, this, type, ConnectionPointDirection.Output, initialValue);
324
+ this._outputs.push(output);
325
+ return output;
326
+ }
327
+
328
+ /**
329
+ * Gets the required RuntimeData for the given input, throwing with a clear message if it is null
330
+ * @param input - The input to get the runtime data for
331
+ * @returns The runtimeData or throws if it was undefined
332
+ */
333
+ protected _confirmRuntimeDataSupplied<U extends ConnectionPointType = ConnectionPointType>(input: ConnectionPoint<U>): RuntimeData<U> {
334
+ if (!input.runtimeData) {
335
+ throw new Error(`The ${ConnectionPointType[input.type]} input named "${input.name}" is missing for the ${this.getClassName()} named "${this.name}"`);
336
+ }
337
+ return input.runtimeData;
338
+ }
339
+ }