@onerjs/core 8.53.6 → 8.53.8

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.
@@ -10,6 +10,19 @@ import { type IAssetContainer } from "../IAssetContainer.js";
10
10
  import { FlowGraphEventType } from "./flowGraphEventType.js";
11
11
  import { FlowGraphSceneEventCoordinator } from "./flowGraphSceneEventCoordinator.js";
12
12
  import { type IFlowGraphValidationResult } from "./flowGraphValidator.js";
13
+ /**
14
+ * Interface used to configure the launch of the flow graph editor.
15
+ */
16
+ export interface IFlowGraphEditorLaunchOptions {
17
+ /** Define the URL to load the flow graph editor script from */
18
+ editorURL?: string;
19
+ /** Additional configuration forwarded to `FlowGraphEditor.Show()` (e.g. hostScene, hostElement) */
20
+ flowGraphEditorConfig?: {
21
+ hostScene?: Scene;
22
+ hostElement?: HTMLElement;
23
+ attachToLiveScene?: boolean;
24
+ };
25
+ }
13
26
  export declare enum FlowGraphState {
14
27
  /**
15
28
  * The graph is stopped
@@ -85,6 +98,13 @@ export declare class FlowGraph {
85
98
  * A unique identifier for this graph. Auto-generated if not provided.
86
99
  */
87
100
  uniqueId: string;
101
+ /**
102
+ * Define the URL to load the flow graph editor script from.
103
+ */
104
+ static EditorURL: string;
105
+ private _BJSFLOWGRAPHEDITOR;
106
+ /** @returns the flow graph editor from a UMD bundle or the BABYLON global, or undefined if not loaded */
107
+ private _getGlobalFlowGraphEditor;
88
108
  /**
89
109
  * An observable that is triggered when the state of the graph changes.
90
110
  */
@@ -232,4 +252,16 @@ export declare class FlowGraph {
232
252
  * @param valueSerializeFunction a function to serialize complex values
233
253
  */
234
254
  serialize(serializationObject?: any, valueSerializeFunction?: (key: string, value: any, serializationObject: any) => void): void;
255
+ /**
256
+ * Launches the flow graph editor for this graph.
257
+ * The editor is lazy-loaded from {@link FlowGraph.EditorURL} the first time it is used.
258
+ * @param config defines the configuration of the editor
259
+ * @returns a promise fulfilled when the editor is visible
260
+ */
261
+ edit(config?: IFlowGraphEditorLaunchOptions): Promise<void>;
262
+ /**
263
+ * Creates the flow graph editor window.
264
+ * @param additionalConfig additional configuration forwarded to `FlowGraphEditor.Show()`
265
+ */
266
+ private _createFlowGraphEditor;
235
267
  }
@@ -6,6 +6,8 @@ import { FlowGraphSceneEventCoordinator } from "./flowGraphSceneEventCoordinator
6
6
  import { _IsDescendantOf } from "./utils.js";
7
7
  import { ValidateFlowGraphWithBlockList } from "./flowGraphValidator.js";
8
8
  import { RandomGUID } from "../Misc/guid.js";
9
+ import { Tools } from "../Misc/tools.pure.js";
10
+ import { AbstractEngine } from "../Engines/abstractEngine.js";
9
11
  export var FlowGraphState;
10
12
  (function (FlowGraphState) {
11
13
  /**
@@ -30,6 +32,24 @@ export var FlowGraphState;
30
32
  * @experimental FlowGraph is still in development and is subject to change.
31
33
  */
32
34
  export class FlowGraph {
35
+ /** @returns the flow graph editor from a UMD bundle or the BABYLON global, or undefined if not loaded */
36
+ _getGlobalFlowGraphEditor() {
37
+ // UMD global name detection from bundle metadata. rollup-built UMD bundles may expose the
38
+ // editor class on `.default.FlowGraphEditor`, so unwrap that case before falling back to
39
+ // the BABYLON global emitted from the editor entry point.
40
+ if (typeof FLOWGRAPHEDITOR !== "undefined") {
41
+ if (FLOWGRAPHEDITOR.FlowGraphEditor) {
42
+ return FLOWGRAPHEDITOR;
43
+ }
44
+ if (FLOWGRAPHEDITOR.default?.FlowGraphEditor) {
45
+ return FLOWGRAPHEDITOR.default;
46
+ }
47
+ }
48
+ if (typeof BABYLON !== "undefined" && typeof BABYLON.FlowGraphEditor !== "undefined") {
49
+ return BABYLON;
50
+ }
51
+ return undefined;
52
+ }
33
53
  /**
34
54
  * The scene associated with this flow graph.
35
55
  */
@@ -67,6 +87,7 @@ export class FlowGraph {
67
87
  * @param params construction parameters. currently only the scene
68
88
  */
69
89
  constructor(params) {
90
+ this._BJSFLOWGRAPHEDITOR = this._getGlobalFlowGraphEditor();
70
91
  /**
71
92
  * An observable that is triggered when the state of the graph changes.
72
93
  */
@@ -418,7 +439,17 @@ export class FlowGraph {
418
439
  * Disposes of the flow graph. Cancels any pending tasks and removes all event listeners.
419
440
  */
420
441
  dispose() {
442
+ // Always release the scene-event wiring, even for a stopped or never-started graph.
443
+ // The scene event coordinator attaches per-frame, pointer and keyboard observers to the
444
+ // scene in its constructor, so a graph that is removed from its coordinator (or disposed)
445
+ // while stopped would otherwise leak those observers and keep incurring per-frame overhead.
446
+ this._detachEventObserver();
447
+ this._sceneEventCoordinator.dispose();
421
448
  if (this.state === 0 /* FlowGraphState.Stopped */) {
449
+ // Nothing is executing, so there is no run state to clear. Authored blocks are left
450
+ // intact on purpose: the editor re-points a stopped graph across preview scenes via
451
+ // setScene(), and each preview scene disposal raises a SceneDispose event that calls
452
+ // dispose() here. Wiping the blocks would destroy the user's graph on every reset.
422
453
  return;
423
454
  }
424
455
  this.state = 0 /* FlowGraphState.Stopped */;
@@ -431,8 +462,6 @@ export class FlowGraph {
431
462
  this._eventBlocks[type].length = 0;
432
463
  }
433
464
  this._allBlocks.length = 0;
434
- this._detachEventObserver();
435
- this._sceneEventCoordinator.dispose();
436
465
  }
437
466
  /**
438
467
  * Executes a function in all blocks of a flow graph, starting with the event blocks.
@@ -510,5 +539,50 @@ export class FlowGraph {
510
539
  serializationObject.executionContexts.push(serializedContext);
511
540
  }
512
541
  }
542
+ /**
543
+ * Launches the flow graph editor for this graph.
544
+ * The editor is lazy-loaded from {@link FlowGraph.EditorURL} the first time it is used.
545
+ * @param config defines the configuration of the editor
546
+ * @returns a promise fulfilled when the editor is visible
547
+ */
548
+ // eslint-disable-next-line @typescript-eslint/naming-convention
549
+ async edit(config) {
550
+ return await new Promise((resolve) => {
551
+ this._BJSFLOWGRAPHEDITOR = this._BJSFLOWGRAPHEDITOR || this._getGlobalFlowGraphEditor();
552
+ if (typeof this._BJSFLOWGRAPHEDITOR === "undefined") {
553
+ const editorUrl = config && config.editorURL ? config.editorURL : FlowGraph.EditorURL;
554
+ // Load the editor bundle and add it to the DOM.
555
+ Tools.LoadBabylonScript(editorUrl, () => {
556
+ this._BJSFLOWGRAPHEDITOR = this._BJSFLOWGRAPHEDITOR || this._getGlobalFlowGraphEditor();
557
+ this._createFlowGraphEditor(config?.flowGraphEditorConfig);
558
+ resolve();
559
+ });
560
+ }
561
+ else {
562
+ this._createFlowGraphEditor(config?.flowGraphEditorConfig);
563
+ resolve();
564
+ }
565
+ });
566
+ }
567
+ /**
568
+ * Creates the flow graph editor window.
569
+ * @param additionalConfig additional configuration forwarded to `FlowGraphEditor.Show()`
570
+ */
571
+ _createFlowGraphEditor(additionalConfig) {
572
+ const editorConfig = {
573
+ flowGraph: this,
574
+ hostScene: this._scene,
575
+ // edit() always targets the developer's own live graph and scene, so the editor should
576
+ // attach to that scene instead of spinning up a throwaway preview scene. A caller can
577
+ // still override this via additionalConfig.
578
+ attachToLiveScene: true,
579
+ ...additionalConfig,
580
+ };
581
+ this._BJSFLOWGRAPHEDITOR.FlowGraphEditor.Show(editorConfig);
582
+ }
513
583
  }
584
+ /**
585
+ * Define the URL to load the flow graph editor script from.
586
+ */
587
+ FlowGraph.EditorURL = `${Tools._DefaultCdnUrl}/v${AbstractEngine.Version}/flowGraphEditor/babylon.flowGraphEditor.js`;
514
588
  //# sourceMappingURL=flowGraph.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"flowGraph.js","sourceRoot":"","sources":["../../../../dev/core/src/FlowGraph/flowGraph.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Observer, Observable } from \"../Misc/observable\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type FlowGraphEventBlock } from \"./flowGraphEventBlock\";\r\nimport { FlowGraphContext } from \"./flowGraphContext\";\r\nimport { type FlowGraphBlock } from \"./flowGraphBlock\";\r\nimport { FlowGraphExecutionBlock } from \"./flowGraphExecutionBlock\";\r\nimport { FlowGraphAsyncExecutionBlock } from \"./flowGraphAsyncExecutionBlock\";\r\nimport { type FlowGraphCoordinator } from \"./flowGraphCoordinator\";\r\nimport { type IObjectAccessor } from \"./typeDefinitions\";\r\nimport { type IPathToObjectConverter } from \"../ObjectModel/objectModelInterfaces\";\r\nimport { type IAssetContainer } from \"core/IAssetContainer\";\r\nimport { FlowGraphEventType } from \"./flowGraphEventType\";\r\nimport { type IFlowGraphEventTrigger, FlowGraphSceneEventCoordinator } from \"./flowGraphSceneEventCoordinator\";\r\nimport { type FlowGraphMeshPickEventBlock } from \"./Blocks/Event/flowGraphMeshPickEventBlock\";\r\nimport { _IsDescendantOf } from \"./utils\";\r\nimport { type IFlowGraphValidationResult, ValidateFlowGraphWithBlockList } from \"./flowGraphValidator\";\r\nimport { RandomGUID } from \"../Misc/guid\";\r\n\r\nexport const enum FlowGraphState {\r\n /**\r\n * The graph is stopped\r\n */\r\n Stopped,\r\n /**\r\n * The graph is running\r\n */\r\n Started,\r\n /**\r\n * The graph is paused (contexts kept, pending tasks cancelled)\r\n */\r\n Paused,\r\n}\r\n\r\n/**\r\n * Parameters used to create a flow graph.\r\n */\r\nexport interface IFlowGraphParams {\r\n /**\r\n * The scene that the flow graph belongs to.\r\n */\r\n scene: Scene;\r\n /**\r\n * The event coordinator used by the flow graph.\r\n */\r\n coordinator: FlowGraphCoordinator;\r\n /**\r\n * Optional human-readable name for the graph.\r\n * Defaults to \"Graph\" if not provided.\r\n */\r\n name?: string;\r\n /**\r\n * Optional unique identifier for the graph.\r\n * If not provided, a random UUID is generated.\r\n */\r\n uniqueId?: string;\r\n}\r\n\r\n/**\r\n * Options for parsing a flow graph.\r\n */\r\nexport interface IFlowGraphParseOptions {\r\n /**\r\n * A function that parses complex values in a scene.\r\n * @param key the key of the value\r\n * @param serializationObject the object to read the value from\r\n * @param assetsContainer the assets container to read assets from\r\n * @param scene the scene to read the value from\r\n */\r\n valueParseFunction?: (key: string, serializationObject: any, assetsContainer: IAssetContainer, scene: Scene) => any;\r\n /**\r\n * The flow graph coordinator.\r\n */\r\n coordinator: FlowGraphCoordinator;\r\n /**\r\n * A function that converts a path to an object accessor.\r\n */\r\n pathConverter?: IPathToObjectConverter<IObjectAccessor>;\r\n}\r\n/**\r\n * Class used to represent a flow graph.\r\n * A flow graph is a graph of blocks that can be used to create complex logic.\r\n * Blocks can be added to the graph and connected to each other.\r\n * The graph can then be started, which will init and start all of its event blocks.\r\n *\r\n * @experimental FlowGraph is still in development and is subject to change.\r\n */\r\nexport class FlowGraph {\r\n /**\r\n * A human-readable name for this graph.\r\n */\r\n public name: string;\r\n\r\n /**\r\n * A unique identifier for this graph. Auto-generated if not provided.\r\n */\r\n public uniqueId: string;\r\n\r\n /**\r\n * An observable that is triggered when the state of the graph changes.\r\n */\r\n public onStateChangedObservable: Observable<FlowGraphState> = new Observable();\r\n /** @internal */\r\n public _eventBlocks: { [keyof in FlowGraphEventType]: FlowGraphEventBlock[] } = {\r\n [FlowGraphEventType.SceneReady]: [],\r\n [FlowGraphEventType.SceneDispose]: [],\r\n [FlowGraphEventType.SceneBeforeRender]: [],\r\n [FlowGraphEventType.MeshPick]: [],\r\n [FlowGraphEventType.PointerDown]: [],\r\n [FlowGraphEventType.PointerUp]: [],\r\n [FlowGraphEventType.PointerMove]: [],\r\n [FlowGraphEventType.PointerOver]: [],\r\n [FlowGraphEventType.PointerOut]: [],\r\n [FlowGraphEventType.KeyDown]: [],\r\n [FlowGraphEventType.KeyUp]: [],\r\n [FlowGraphEventType.SceneAfterRender]: [],\r\n [FlowGraphEventType.NoTrigger]: [],\r\n };\r\n\r\n /**\r\n * All blocks that belong to this graph, including unreachable ones.\r\n * @internal\r\n */\r\n public _allBlocks: FlowGraphBlock[] = [];\r\n /**\r\n * @internal\r\n */\r\n public readonly _scene: Scene;\r\n\r\n /**\r\n * The scene associated with this flow graph.\r\n */\r\n public get scene(): Scene {\r\n return this._scene;\r\n }\r\n private _coordinator: FlowGraphCoordinator;\r\n\r\n /**\r\n * The coordinator that owns this flow graph.\r\n */\r\n public get coordinator(): FlowGraphCoordinator {\r\n return this._coordinator;\r\n }\r\n private _executionContexts: FlowGraphContext[] = [];\r\n private _sceneEventCoordinator: FlowGraphSceneEventCoordinator;\r\n\r\n /**\r\n * The scene event coordinator for this graph.\r\n * Provides access to runtime event state such as currently pressed keys.\r\n */\r\n public get sceneEventCoordinator(): FlowGraphSceneEventCoordinator {\r\n return this._sceneEventCoordinator;\r\n }\r\n\r\n private _eventObserver: Nullable<Observer<IFlowGraphEventTrigger>>;\r\n\r\n /**\r\n * The state of the graph\r\n */\r\n private _state: FlowGraphState = FlowGraphState.Stopped;\r\n\r\n /**\r\n * The state of the graph\r\n */\r\n public get state() {\r\n return this._state;\r\n }\r\n\r\n /**\r\n * The state of the graph\r\n */\r\n public set state(value: FlowGraphState) {\r\n this._state = value;\r\n this.onStateChangedObservable.notifyObservers(value);\r\n }\r\n\r\n /**\r\n * Construct a Flow Graph\r\n * @param params construction parameters. currently only the scene\r\n */\r\n public constructor(params: IFlowGraphParams) {\r\n this._scene = params.scene;\r\n this._sceneEventCoordinator = new FlowGraphSceneEventCoordinator(this._scene);\r\n this._coordinator = params.coordinator;\r\n this.name = params.name ?? \"Graph\";\r\n this.uniqueId = params.uniqueId ?? RandomGUID();\r\n }\r\n\r\n private _attachEventObserver() {\r\n if (this._eventObserver) {\r\n return;\r\n }\r\n this._eventObserver = this._sceneEventCoordinator.onEventTriggeredObservable.add((event) => {\r\n if (event.type === FlowGraphEventType.SceneDispose) {\r\n this.dispose();\r\n return;\r\n }\r\n\r\n if (this.state !== FlowGraphState.Started) {\r\n return;\r\n }\r\n\r\n for (const context of this._executionContexts) {\r\n const order = this._getContextualOrder(event.type, context);\r\n for (const block of order) {\r\n // iterate contexts\r\n if (!block._executeEvent(context, event.payload)) {\r\n break;\r\n }\r\n }\r\n }\r\n // custom behavior(s) of specific events\r\n switch (event.type) {\r\n case FlowGraphEventType.SceneReady:\r\n this._sceneEventCoordinator.sceneReadyTriggered = true;\r\n break;\r\n case FlowGraphEventType.SceneBeforeRender:\r\n for (const context of this._executionContexts) {\r\n context._notifyOnTick(event.payload);\r\n }\r\n break;\r\n }\r\n });\r\n }\r\n\r\n private _detachEventObserver() {\r\n this._eventObserver?.remove();\r\n this._eventObserver = null;\r\n }\r\n\r\n /**\r\n * Sets a new scene for this flow graph, re-wiring all event listeners.\r\n * This is useful when the scene the flow graph should listen to changes\r\n * (e.g. when a new scene is loaded in an editor preview).\r\n * If the graph is currently running, it will be stopped first and must be\r\n * restarted manually after calling this method.\r\n * @param scene the new scene to attach to\r\n */\r\n public setScene(scene: Scene): void {\r\n if (scene === this._scene) {\r\n return;\r\n }\r\n if (this.state === FlowGraphState.Started) {\r\n this.stop();\r\n }\r\n // Tear down old event coordinator\r\n this._detachEventObserver();\r\n this._sceneEventCoordinator.dispose();\r\n // Clear execution contexts so start() creates fresh ones with the new scene.\r\n // NOTE: This intentionally discards user variables and connection values.\r\n // Callers that need to preserve them (e.g. the Flow Graph Editor) should\r\n // snapshot context state BEFORE calling setScene() and restore it in a\r\n // wrapped createContext() callback after start() re-creates contexts.\r\n this._executionContexts.length = 0;\r\n // Rebuild with the new scene\r\n (this as { _scene: Scene })._scene = scene;\r\n this._scene.constantlyUpdateMeshUnderPointer = true; // ensure pointer info is always up to date for event blocks that need it\r\n // Re-resolve node references (e.g. meshes targeted by Get/Set property blocks) against the\r\n // new scene. This is required when the graph was parsed before its scene was populated (for\r\n // example an editor that loads a graph from a snippet first and the referenced scene second):\r\n // the references would otherwise stay bound to nodes from the old/disposed scene.\r\n for (const block of this._allBlocks) {\r\n for (const input of block.dataInputs) {\r\n input._reresolveDefaultValueForScene(scene);\r\n }\r\n }\r\n this._sceneEventCoordinator = new FlowGraphSceneEventCoordinator(this._scene);\r\n // Pre-attach the event observer so that events from the new\r\n // coordinator are routed to the graph immediately. The handler\r\n // guards against processing events while the graph is stopped,\r\n // but having the observer in place ensures no events are lost\r\n // when start() is called shortly after.\r\n this._attachEventObserver();\r\n }\r\n\r\n /**\r\n * Create a context. A context represents one self contained execution for the graph, with its own variables.\r\n * @returns the context, where you can get and set variables\r\n */\r\n public createContext() {\r\n const context = new FlowGraphContext({ scene: this._scene, coordinator: this._coordinator, sceneEventCoordinator: this._sceneEventCoordinator });\r\n this._executionContexts.push(context);\r\n return context;\r\n }\r\n\r\n /**\r\n * Returns the execution context at a given index\r\n * @param index the index of the context\r\n * @returns the execution context at that index\r\n */\r\n public getContext(index: number) {\r\n return this._executionContexts[index];\r\n }\r\n\r\n /**\r\n * Returns the number of execution contexts currently attached to this graph.\r\n */\r\n public get contextCount(): number {\r\n return this._executionContexts.length;\r\n }\r\n\r\n /**\r\n * Remove an execution context by index. Any pending async blocks on\r\n * the context are cleared before removal.\r\n * @param index the index of the context to remove\r\n * @returns the removed context, or undefined if the index was out of range\r\n */\r\n public removeContext(index: number): FlowGraphContext | undefined {\r\n if (index < 0 || index >= this._executionContexts.length) {\r\n return undefined;\r\n }\r\n const [removed] = this._executionContexts.splice(index, 1);\r\n removed._clearPendingBlocks();\r\n return removed;\r\n }\r\n\r\n /**\r\n * Returns all blocks registered in this graph, including disconnected ones.\r\n * @returns a read-only array of all blocks\r\n */\r\n public getAllBlocks(): readonly FlowGraphBlock[] {\r\n return this._allBlocks;\r\n }\r\n\r\n /**\r\n * Register a block with the graph. This does not wire any connections;\r\n * it simply ensures the block is tracked so that serialization, editor\r\n * display, and validation see it even when it is not reachable from an\r\n * event block.\r\n * @param block the block to register\r\n */\r\n public addBlock(block: FlowGraphBlock): void {\r\n if (this._allBlocks.indexOf(block) === -1) {\r\n this._allBlocks.push(block);\r\n }\r\n }\r\n\r\n /**\r\n * Remove a block from the graph. Disconnects all of its ports and, if it\r\n * is an event block, unregisters it from the event-block lists.\r\n * @param block the block to remove\r\n */\r\n public removeBlock(block: FlowGraphBlock): void {\r\n const idx = this._allBlocks.indexOf(block);\r\n if (idx !== -1) {\r\n this._allBlocks.splice(idx, 1);\r\n }\r\n // If it is an event block, remove from the event-block registry\r\n if (block instanceof FlowGraphExecutionBlock && \"type\" in block) {\r\n const eventBlock = block as unknown as FlowGraphEventBlock;\r\n const list = this._eventBlocks[eventBlock.type];\r\n if (list) {\r\n const eIdx = list.indexOf(eventBlock);\r\n if (eIdx !== -1) {\r\n list.splice(eIdx, 1);\r\n }\r\n }\r\n }\r\n // If the block has pending async tasks (e.g. event subscriptions),\r\n // cancel them in all active execution contexts so deletion takes\r\n // effect immediately even while the graph is running.\r\n if (block instanceof FlowGraphAsyncExecutionBlock) {\r\n for (const context of this._executionContexts) {\r\n block._cancelPendingTasks(context);\r\n block._resetAfterCanceled(context);\r\n }\r\n }\r\n // Disconnect all ports\r\n for (const input of block.dataInputs) {\r\n input.disconnectFromAll();\r\n }\r\n for (const output of block.dataOutputs) {\r\n output.disconnectFromAll();\r\n }\r\n if (block instanceof FlowGraphExecutionBlock) {\r\n for (const signalIn of block.signalInputs) {\r\n signalIn.disconnectFromAll();\r\n }\r\n for (const signalOut of block.signalOutputs) {\r\n signalOut.disconnectFromAll();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Add an event block. When the graph is started, it will start listening to events\r\n * from the block and execute the graph when they are triggered.\r\n * @param block the event block to be added\r\n */\r\n public addEventBlock(block: FlowGraphEventBlock): void {\r\n this.addBlock(block);\r\n if (block.type === FlowGraphEventType.PointerOver || block.type === FlowGraphEventType.PointerOut) {\r\n this._scene.constantlyUpdateMeshUnderPointer = true;\r\n }\r\n\r\n this._eventBlocks[block.type].push(block);\r\n\r\n // if already started, sort and add to the pending\r\n if (this.state === FlowGraphState.Started) {\r\n for (const context of this._executionContexts) {\r\n block._startPendingTasks(context);\r\n }\r\n } else {\r\n this.onStateChangedObservable.addOnce((state) => {\r\n if (state === FlowGraphState.Started) {\r\n for (const context of this._executionContexts) {\r\n block._startPendingTasks(context);\r\n }\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Stops the flow graph. Cancels all pending tasks and clears execution contexts,\r\n * but keeps event blocks so the graph can be restarted.\r\n */\r\n public stop() {\r\n if (this.state === FlowGraphState.Stopped) {\r\n return;\r\n }\r\n this._detachEventObserver();\r\n this.state = FlowGraphState.Stopped;\r\n for (const context of this._executionContexts) {\r\n context._clearPendingBlocks();\r\n context._clearPendingActivation();\r\n }\r\n this._executionContexts.length = 0;\r\n }\r\n\r\n /**\r\n * Pauses the flow graph. Cancels pending tasks but keeps execution contexts and event blocks.\r\n * Call start() to resume.\r\n */\r\n public pause() {\r\n if (this.state !== FlowGraphState.Started) {\r\n return;\r\n }\r\n this._detachEventObserver();\r\n this.state = FlowGraphState.Paused;\r\n for (const context of this._executionContexts) {\r\n context._clearPendingBlocks();\r\n }\r\n }\r\n\r\n /**\r\n * Starts the flow graph. Initializes the event blocks and starts listening to events.\r\n * Can also be called to resume from a paused state.\r\n */\r\n public start() {\r\n if (this.state === FlowGraphState.Started) {\r\n return;\r\n }\r\n const resumingFromPause = this.state === FlowGraphState.Paused;\r\n if (this._executionContexts.length === 0) {\r\n this.createContext();\r\n }\r\n this._attachEventObserver();\r\n this.state = FlowGraphState.Started;\r\n this._startPendingEvents();\r\n // On a fresh start (not resume), fire the SceneReady event.\r\n // The coordinator's own scene-ready observer may have already\r\n // fired (and been lost) while the graph was stopped, so reset\r\n // the flag and handle the ready state ourselves.\r\n if (!resumingFromPause) {\r\n this._sceneEventCoordinator.sceneReadyTriggered = false;\r\n if (this._scene.isReady(true)) {\r\n this._sceneEventCoordinator.sceneReadyTriggered = true;\r\n this._sceneEventCoordinator.onEventTriggeredObservable.notifyObservers({ type: FlowGraphEventType.SceneReady });\r\n } else {\r\n // Scene isn't ready yet (e.g. pending shader compilations after\r\n // a scene swap). Use executeWhenReady(true) which restarts the\r\n // readiness check loop — a plain addOnce on onReadyObservable\r\n // may never fire if the check loop already completed.\r\n this._scene.executeWhenReady(() => {\r\n if (this.state === FlowGraphState.Started && !this._sceneEventCoordinator.sceneReadyTriggered) {\r\n this._sceneEventCoordinator.sceneReadyTriggered = true;\r\n this._sceneEventCoordinator.onEventTriggeredObservable.notifyObservers({ type: FlowGraphEventType.SceneReady });\r\n }\r\n }, true);\r\n }\r\n }\r\n }\r\n\r\n private _startPendingEvents() {\r\n for (const context of this._executionContexts) {\r\n for (const type in this._eventBlocks) {\r\n const order = this._getContextualOrder(type as FlowGraphEventType, context);\r\n for (const block of order) {\r\n block._startPendingTasks(context);\r\n }\r\n }\r\n }\r\n }\r\n\r\n private _getContextualOrder(type: FlowGraphEventType, context: FlowGraphContext): FlowGraphEventBlock[] {\r\n const order = this._eventBlocks[type].sort((a, b) => b.initPriority - a.initPriority);\r\n\r\n if (type === FlowGraphEventType.MeshPick) {\r\n const meshPickOrder = [] as FlowGraphEventBlock[];\r\n for (const block1 of order) {\r\n // If the block is a mesh pick, guarantee that picks of children meshes come before picks of parent meshes\r\n const mesh1 = (block1 as FlowGraphMeshPickEventBlock).asset.getValue(context);\r\n let i = 0;\r\n for (; i < order.length; i++) {\r\n const block2 = order[i];\r\n const mesh2 = (block2 as FlowGraphMeshPickEventBlock).asset.getValue(context);\r\n if (mesh1 && mesh2 && _IsDescendantOf(mesh1, mesh2)) {\r\n break;\r\n }\r\n }\r\n meshPickOrder.splice(i, 0, block1);\r\n }\r\n return meshPickOrder;\r\n }\r\n return order;\r\n }\r\n\r\n /**\r\n * Disposes of the flow graph. Cancels any pending tasks and removes all event listeners.\r\n */\r\n public dispose() {\r\n if (this.state === FlowGraphState.Stopped) {\r\n return;\r\n }\r\n this.state = FlowGraphState.Stopped;\r\n for (const context of this._executionContexts) {\r\n context._clearPendingBlocks();\r\n context._clearPendingActivation();\r\n }\r\n this._executionContexts.length = 0;\r\n for (const type in this._eventBlocks) {\r\n this._eventBlocks[type as FlowGraphEventType].length = 0;\r\n }\r\n this._allBlocks.length = 0;\r\n this._detachEventObserver();\r\n this._sceneEventCoordinator.dispose();\r\n }\r\n\r\n /**\r\n * Executes a function in all blocks of a flow graph, starting with the event blocks.\r\n * @param visitor the function to execute.\r\n */\r\n public visitAllBlocks(visitor: (block: FlowGraphBlock) => void) {\r\n const visitList: FlowGraphBlock[] = [];\r\n const idsAddedToVisitList = new Set<string>();\r\n for (const type in this._eventBlocks) {\r\n for (const block of this._eventBlocks[type as FlowGraphEventType]) {\r\n visitList.push(block);\r\n idsAddedToVisitList.add(block.uniqueId);\r\n }\r\n }\r\n\r\n while (visitList.length > 0) {\r\n const block = visitList.pop()!;\r\n visitor(block);\r\n\r\n for (const dataIn of block.dataInputs) {\r\n for (const connection of dataIn._connectedPoint) {\r\n if (!idsAddedToVisitList.has(connection._ownerBlock.uniqueId)) {\r\n visitList.push(connection._ownerBlock);\r\n idsAddedToVisitList.add(connection._ownerBlock.uniqueId);\r\n }\r\n }\r\n }\r\n if (block instanceof FlowGraphExecutionBlock) {\r\n for (const signalOut of block.signalOutputs) {\r\n for (const connection of signalOut._connectedPoint) {\r\n if (!idsAddedToVisitList.has(connection._ownerBlock.uniqueId)) {\r\n visitList.push(connection._ownerBlock);\r\n idsAddedToVisitList.add(connection._ownerBlock.uniqueId);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Validates the flow graph and returns all issues found.\r\n * Uses the tracked block list for complete validation including unreachable block detection.\r\n * @returns The validation result containing errors and warnings.\r\n */\r\n public validate(): IFlowGraphValidationResult {\r\n return ValidateFlowGraphWithBlockList(this, this._allBlocks);\r\n }\r\n\r\n /**\r\n * Serializes a graph\r\n * @param serializationObject the object to write the values in\r\n * @param valueSerializeFunction a function to serialize complex values\r\n */\r\n public serialize(serializationObject: any = {}, valueSerializeFunction?: (key: string, value: any, serializationObject: any) => void) {\r\n serializationObject.name = this.name;\r\n serializationObject.uniqueId = this.uniqueId;\r\n serializationObject.allBlocks = [];\r\n // Collect all blocks: traversal-reachable ones plus any registered\r\n // orphans in _allBlocks (e.g. disconnected blocks in the editor).\r\n const seen = new Set<string>();\r\n const serializeBlock = (block: FlowGraphBlock) => {\r\n if (seen.has(block.uniqueId)) {\r\n return;\r\n }\r\n seen.add(block.uniqueId);\r\n const serializedBlock: any = {};\r\n block.serialize(serializedBlock);\r\n serializationObject.allBlocks.push(serializedBlock);\r\n };\r\n this.visitAllBlocks(serializeBlock);\r\n for (const block of this._allBlocks) {\r\n serializeBlock(block);\r\n }\r\n serializationObject.executionContexts = [];\r\n for (const context of this._executionContexts) {\r\n const serializedContext: any = {};\r\n context.serialize(serializedContext, valueSerializeFunction);\r\n serializationObject.executionContexts.push(serializedContext);\r\n }\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"flowGraph.js","sourceRoot":"","sources":["../../../../dev/core/src/FlowGraph/flowGraph.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Observer, Observable } from \"../Misc/observable\";\r\nimport { type Nullable } from \"../types\";\r\nimport { type Scene } from \"../scene\";\r\nimport { type FlowGraphEventBlock } from \"./flowGraphEventBlock\";\r\nimport { FlowGraphContext } from \"./flowGraphContext\";\r\nimport { type FlowGraphBlock } from \"./flowGraphBlock\";\r\nimport { FlowGraphExecutionBlock } from \"./flowGraphExecutionBlock\";\r\nimport { FlowGraphAsyncExecutionBlock } from \"./flowGraphAsyncExecutionBlock\";\r\nimport { type FlowGraphCoordinator } from \"./flowGraphCoordinator\";\r\nimport { type IObjectAccessor } from \"./typeDefinitions\";\r\nimport { type IPathToObjectConverter } from \"../ObjectModel/objectModelInterfaces\";\r\nimport { type IAssetContainer } from \"core/IAssetContainer\";\r\nimport { FlowGraphEventType } from \"./flowGraphEventType\";\r\nimport { type IFlowGraphEventTrigger, FlowGraphSceneEventCoordinator } from \"./flowGraphSceneEventCoordinator\";\r\nimport { type FlowGraphMeshPickEventBlock } from \"./Blocks/Event/flowGraphMeshPickEventBlock\";\r\nimport { _IsDescendantOf } from \"./utils\";\r\nimport { type IFlowGraphValidationResult, ValidateFlowGraphWithBlockList } from \"./flowGraphValidator\";\r\nimport { RandomGUID } from \"../Misc/guid\";\r\nimport { Tools } from \"../Misc/tools.pure\";\r\nimport { AbstractEngine } from \"../Engines/abstractEngine\";\r\n\r\n// UMD global names for the flow graph editor bundle (mirrors nodeGeometry.ts / nodeRenderGraph.ts).\r\ndeclare let FLOWGRAPHEDITOR: any;\r\ndeclare let BABYLON: any;\r\n\r\n/**\r\n * Interface used to configure the launch of the flow graph editor.\r\n */\r\nexport interface IFlowGraphEditorLaunchOptions {\r\n /** Define the URL to load the flow graph editor script from */\r\n editorURL?: string;\r\n /** Additional configuration forwarded to `FlowGraphEditor.Show()` (e.g. hostScene, hostElement) */\r\n flowGraphEditorConfig?: {\r\n hostScene?: Scene;\r\n hostElement?: HTMLElement;\r\n attachToLiveScene?: boolean;\r\n };\r\n}\r\n\r\nexport const enum FlowGraphState {\r\n /**\r\n * The graph is stopped\r\n */\r\n Stopped,\r\n /**\r\n * The graph is running\r\n */\r\n Started,\r\n /**\r\n * The graph is paused (contexts kept, pending tasks cancelled)\r\n */\r\n Paused,\r\n}\r\n\r\n/**\r\n * Parameters used to create a flow graph.\r\n */\r\nexport interface IFlowGraphParams {\r\n /**\r\n * The scene that the flow graph belongs to.\r\n */\r\n scene: Scene;\r\n /**\r\n * The event coordinator used by the flow graph.\r\n */\r\n coordinator: FlowGraphCoordinator;\r\n /**\r\n * Optional human-readable name for the graph.\r\n * Defaults to \"Graph\" if not provided.\r\n */\r\n name?: string;\r\n /**\r\n * Optional unique identifier for the graph.\r\n * If not provided, a random UUID is generated.\r\n */\r\n uniqueId?: string;\r\n}\r\n\r\n/**\r\n * Options for parsing a flow graph.\r\n */\r\nexport interface IFlowGraphParseOptions {\r\n /**\r\n * A function that parses complex values in a scene.\r\n * @param key the key of the value\r\n * @param serializationObject the object to read the value from\r\n * @param assetsContainer the assets container to read assets from\r\n * @param scene the scene to read the value from\r\n */\r\n valueParseFunction?: (key: string, serializationObject: any, assetsContainer: IAssetContainer, scene: Scene) => any;\r\n /**\r\n * The flow graph coordinator.\r\n */\r\n coordinator: FlowGraphCoordinator;\r\n /**\r\n * A function that converts a path to an object accessor.\r\n */\r\n pathConverter?: IPathToObjectConverter<IObjectAccessor>;\r\n}\r\n/**\r\n * Class used to represent a flow graph.\r\n * A flow graph is a graph of blocks that can be used to create complex logic.\r\n * Blocks can be added to the graph and connected to each other.\r\n * The graph can then be started, which will init and start all of its event blocks.\r\n *\r\n * @experimental FlowGraph is still in development and is subject to change.\r\n */\r\nexport class FlowGraph {\r\n /**\r\n * A human-readable name for this graph.\r\n */\r\n public name: string;\r\n\r\n /**\r\n * A unique identifier for this graph. Auto-generated if not provided.\r\n */\r\n public uniqueId: string;\r\n\r\n /**\r\n * Define the URL to load the flow graph editor script from.\r\n */\r\n public static EditorURL = `${Tools._DefaultCdnUrl}/v${AbstractEngine.Version}/flowGraphEditor/babylon.flowGraphEditor.js`;\r\n\r\n private _BJSFLOWGRAPHEDITOR = this._getGlobalFlowGraphEditor();\r\n\r\n /** @returns the flow graph editor from a UMD bundle or the BABYLON global, or undefined if not loaded */\r\n private _getGlobalFlowGraphEditor(): any {\r\n // UMD global name detection from bundle metadata. rollup-built UMD bundles may expose the\r\n // editor class on `.default.FlowGraphEditor`, so unwrap that case before falling back to\r\n // the BABYLON global emitted from the editor entry point.\r\n if (typeof FLOWGRAPHEDITOR !== \"undefined\") {\r\n if ((FLOWGRAPHEDITOR as any).FlowGraphEditor) {\r\n return FLOWGRAPHEDITOR;\r\n }\r\n if ((FLOWGRAPHEDITOR as any).default?.FlowGraphEditor) {\r\n return (FLOWGRAPHEDITOR as any).default;\r\n }\r\n }\r\n\r\n if (typeof BABYLON !== \"undefined\" && typeof BABYLON.FlowGraphEditor !== \"undefined\") {\r\n return BABYLON;\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n /**\r\n * An observable that is triggered when the state of the graph changes.\r\n */\r\n public onStateChangedObservable: Observable<FlowGraphState> = new Observable();\r\n /** @internal */\r\n public _eventBlocks: { [keyof in FlowGraphEventType]: FlowGraphEventBlock[] } = {\r\n [FlowGraphEventType.SceneReady]: [],\r\n [FlowGraphEventType.SceneDispose]: [],\r\n [FlowGraphEventType.SceneBeforeRender]: [],\r\n [FlowGraphEventType.MeshPick]: [],\r\n [FlowGraphEventType.PointerDown]: [],\r\n [FlowGraphEventType.PointerUp]: [],\r\n [FlowGraphEventType.PointerMove]: [],\r\n [FlowGraphEventType.PointerOver]: [],\r\n [FlowGraphEventType.PointerOut]: [],\r\n [FlowGraphEventType.KeyDown]: [],\r\n [FlowGraphEventType.KeyUp]: [],\r\n [FlowGraphEventType.SceneAfterRender]: [],\r\n [FlowGraphEventType.NoTrigger]: [],\r\n };\r\n\r\n /**\r\n * All blocks that belong to this graph, including unreachable ones.\r\n * @internal\r\n */\r\n public _allBlocks: FlowGraphBlock[] = [];\r\n /**\r\n * @internal\r\n */\r\n public readonly _scene: Scene;\r\n\r\n /**\r\n * The scene associated with this flow graph.\r\n */\r\n public get scene(): Scene {\r\n return this._scene;\r\n }\r\n private _coordinator: FlowGraphCoordinator;\r\n\r\n /**\r\n * The coordinator that owns this flow graph.\r\n */\r\n public get coordinator(): FlowGraphCoordinator {\r\n return this._coordinator;\r\n }\r\n private _executionContexts: FlowGraphContext[] = [];\r\n private _sceneEventCoordinator: FlowGraphSceneEventCoordinator;\r\n\r\n /**\r\n * The scene event coordinator for this graph.\r\n * Provides access to runtime event state such as currently pressed keys.\r\n */\r\n public get sceneEventCoordinator(): FlowGraphSceneEventCoordinator {\r\n return this._sceneEventCoordinator;\r\n }\r\n\r\n private _eventObserver: Nullable<Observer<IFlowGraphEventTrigger>>;\r\n\r\n /**\r\n * The state of the graph\r\n */\r\n private _state: FlowGraphState = FlowGraphState.Stopped;\r\n\r\n /**\r\n * The state of the graph\r\n */\r\n public get state() {\r\n return this._state;\r\n }\r\n\r\n /**\r\n * The state of the graph\r\n */\r\n public set state(value: FlowGraphState) {\r\n this._state = value;\r\n this.onStateChangedObservable.notifyObservers(value);\r\n }\r\n\r\n /**\r\n * Construct a Flow Graph\r\n * @param params construction parameters. currently only the scene\r\n */\r\n public constructor(params: IFlowGraphParams) {\r\n this._scene = params.scene;\r\n this._sceneEventCoordinator = new FlowGraphSceneEventCoordinator(this._scene);\r\n this._coordinator = params.coordinator;\r\n this.name = params.name ?? \"Graph\";\r\n this.uniqueId = params.uniqueId ?? RandomGUID();\r\n }\r\n\r\n private _attachEventObserver() {\r\n if (this._eventObserver) {\r\n return;\r\n }\r\n this._eventObserver = this._sceneEventCoordinator.onEventTriggeredObservable.add((event) => {\r\n if (event.type === FlowGraphEventType.SceneDispose) {\r\n this.dispose();\r\n return;\r\n }\r\n\r\n if (this.state !== FlowGraphState.Started) {\r\n return;\r\n }\r\n\r\n for (const context of this._executionContexts) {\r\n const order = this._getContextualOrder(event.type, context);\r\n for (const block of order) {\r\n // iterate contexts\r\n if (!block._executeEvent(context, event.payload)) {\r\n break;\r\n }\r\n }\r\n }\r\n // custom behavior(s) of specific events\r\n switch (event.type) {\r\n case FlowGraphEventType.SceneReady:\r\n this._sceneEventCoordinator.sceneReadyTriggered = true;\r\n break;\r\n case FlowGraphEventType.SceneBeforeRender:\r\n for (const context of this._executionContexts) {\r\n context._notifyOnTick(event.payload);\r\n }\r\n break;\r\n }\r\n });\r\n }\r\n\r\n private _detachEventObserver() {\r\n this._eventObserver?.remove();\r\n this._eventObserver = null;\r\n }\r\n\r\n /**\r\n * Sets a new scene for this flow graph, re-wiring all event listeners.\r\n * This is useful when the scene the flow graph should listen to changes\r\n * (e.g. when a new scene is loaded in an editor preview).\r\n * If the graph is currently running, it will be stopped first and must be\r\n * restarted manually after calling this method.\r\n * @param scene the new scene to attach to\r\n */\r\n public setScene(scene: Scene): void {\r\n if (scene === this._scene) {\r\n return;\r\n }\r\n if (this.state === FlowGraphState.Started) {\r\n this.stop();\r\n }\r\n // Tear down old event coordinator\r\n this._detachEventObserver();\r\n this._sceneEventCoordinator.dispose();\r\n // Clear execution contexts so start() creates fresh ones with the new scene.\r\n // NOTE: This intentionally discards user variables and connection values.\r\n // Callers that need to preserve them (e.g. the Flow Graph Editor) should\r\n // snapshot context state BEFORE calling setScene() and restore it in a\r\n // wrapped createContext() callback after start() re-creates contexts.\r\n this._executionContexts.length = 0;\r\n // Rebuild with the new scene\r\n (this as { _scene: Scene })._scene = scene;\r\n this._scene.constantlyUpdateMeshUnderPointer = true; // ensure pointer info is always up to date for event blocks that need it\r\n // Re-resolve node references (e.g. meshes targeted by Get/Set property blocks) against the\r\n // new scene. This is required when the graph was parsed before its scene was populated (for\r\n // example an editor that loads a graph from a snippet first and the referenced scene second):\r\n // the references would otherwise stay bound to nodes from the old/disposed scene.\r\n for (const block of this._allBlocks) {\r\n for (const input of block.dataInputs) {\r\n input._reresolveDefaultValueForScene(scene);\r\n }\r\n }\r\n this._sceneEventCoordinator = new FlowGraphSceneEventCoordinator(this._scene);\r\n // Pre-attach the event observer so that events from the new\r\n // coordinator are routed to the graph immediately. The handler\r\n // guards against processing events while the graph is stopped,\r\n // but having the observer in place ensures no events are lost\r\n // when start() is called shortly after.\r\n this._attachEventObserver();\r\n }\r\n\r\n /**\r\n * Create a context. A context represents one self contained execution for the graph, with its own variables.\r\n * @returns the context, where you can get and set variables\r\n */\r\n public createContext() {\r\n const context = new FlowGraphContext({ scene: this._scene, coordinator: this._coordinator, sceneEventCoordinator: this._sceneEventCoordinator });\r\n this._executionContexts.push(context);\r\n return context;\r\n }\r\n\r\n /**\r\n * Returns the execution context at a given index\r\n * @param index the index of the context\r\n * @returns the execution context at that index\r\n */\r\n public getContext(index: number) {\r\n return this._executionContexts[index];\r\n }\r\n\r\n /**\r\n * Returns the number of execution contexts currently attached to this graph.\r\n */\r\n public get contextCount(): number {\r\n return this._executionContexts.length;\r\n }\r\n\r\n /**\r\n * Remove an execution context by index. Any pending async blocks on\r\n * the context are cleared before removal.\r\n * @param index the index of the context to remove\r\n * @returns the removed context, or undefined if the index was out of range\r\n */\r\n public removeContext(index: number): FlowGraphContext | undefined {\r\n if (index < 0 || index >= this._executionContexts.length) {\r\n return undefined;\r\n }\r\n const [removed] = this._executionContexts.splice(index, 1);\r\n removed._clearPendingBlocks();\r\n return removed;\r\n }\r\n\r\n /**\r\n * Returns all blocks registered in this graph, including disconnected ones.\r\n * @returns a read-only array of all blocks\r\n */\r\n public getAllBlocks(): readonly FlowGraphBlock[] {\r\n return this._allBlocks;\r\n }\r\n\r\n /**\r\n * Register a block with the graph. This does not wire any connections;\r\n * it simply ensures the block is tracked so that serialization, editor\r\n * display, and validation see it even when it is not reachable from an\r\n * event block.\r\n * @param block the block to register\r\n */\r\n public addBlock(block: FlowGraphBlock): void {\r\n if (this._allBlocks.indexOf(block) === -1) {\r\n this._allBlocks.push(block);\r\n }\r\n }\r\n\r\n /**\r\n * Remove a block from the graph. Disconnects all of its ports and, if it\r\n * is an event block, unregisters it from the event-block lists.\r\n * @param block the block to remove\r\n */\r\n public removeBlock(block: FlowGraphBlock): void {\r\n const idx = this._allBlocks.indexOf(block);\r\n if (idx !== -1) {\r\n this._allBlocks.splice(idx, 1);\r\n }\r\n // If it is an event block, remove from the event-block registry\r\n if (block instanceof FlowGraphExecutionBlock && \"type\" in block) {\r\n const eventBlock = block as unknown as FlowGraphEventBlock;\r\n const list = this._eventBlocks[eventBlock.type];\r\n if (list) {\r\n const eIdx = list.indexOf(eventBlock);\r\n if (eIdx !== -1) {\r\n list.splice(eIdx, 1);\r\n }\r\n }\r\n }\r\n // If the block has pending async tasks (e.g. event subscriptions),\r\n // cancel them in all active execution contexts so deletion takes\r\n // effect immediately even while the graph is running.\r\n if (block instanceof FlowGraphAsyncExecutionBlock) {\r\n for (const context of this._executionContexts) {\r\n block._cancelPendingTasks(context);\r\n block._resetAfterCanceled(context);\r\n }\r\n }\r\n // Disconnect all ports\r\n for (const input of block.dataInputs) {\r\n input.disconnectFromAll();\r\n }\r\n for (const output of block.dataOutputs) {\r\n output.disconnectFromAll();\r\n }\r\n if (block instanceof FlowGraphExecutionBlock) {\r\n for (const signalIn of block.signalInputs) {\r\n signalIn.disconnectFromAll();\r\n }\r\n for (const signalOut of block.signalOutputs) {\r\n signalOut.disconnectFromAll();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Add an event block. When the graph is started, it will start listening to events\r\n * from the block and execute the graph when they are triggered.\r\n * @param block the event block to be added\r\n */\r\n public addEventBlock(block: FlowGraphEventBlock): void {\r\n this.addBlock(block);\r\n if (block.type === FlowGraphEventType.PointerOver || block.type === FlowGraphEventType.PointerOut) {\r\n this._scene.constantlyUpdateMeshUnderPointer = true;\r\n }\r\n\r\n this._eventBlocks[block.type].push(block);\r\n\r\n // if already started, sort and add to the pending\r\n if (this.state === FlowGraphState.Started) {\r\n for (const context of this._executionContexts) {\r\n block._startPendingTasks(context);\r\n }\r\n } else {\r\n this.onStateChangedObservable.addOnce((state) => {\r\n if (state === FlowGraphState.Started) {\r\n for (const context of this._executionContexts) {\r\n block._startPendingTasks(context);\r\n }\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Stops the flow graph. Cancels all pending tasks and clears execution contexts,\r\n * but keeps event blocks so the graph can be restarted.\r\n */\r\n public stop() {\r\n if (this.state === FlowGraphState.Stopped) {\r\n return;\r\n }\r\n this._detachEventObserver();\r\n this.state = FlowGraphState.Stopped;\r\n for (const context of this._executionContexts) {\r\n context._clearPendingBlocks();\r\n context._clearPendingActivation();\r\n }\r\n this._executionContexts.length = 0;\r\n }\r\n\r\n /**\r\n * Pauses the flow graph. Cancels pending tasks but keeps execution contexts and event blocks.\r\n * Call start() to resume.\r\n */\r\n public pause() {\r\n if (this.state !== FlowGraphState.Started) {\r\n return;\r\n }\r\n this._detachEventObserver();\r\n this.state = FlowGraphState.Paused;\r\n for (const context of this._executionContexts) {\r\n context._clearPendingBlocks();\r\n }\r\n }\r\n\r\n /**\r\n * Starts the flow graph. Initializes the event blocks and starts listening to events.\r\n * Can also be called to resume from a paused state.\r\n */\r\n public start() {\r\n if (this.state === FlowGraphState.Started) {\r\n return;\r\n }\r\n const resumingFromPause = this.state === FlowGraphState.Paused;\r\n if (this._executionContexts.length === 0) {\r\n this.createContext();\r\n }\r\n this._attachEventObserver();\r\n this.state = FlowGraphState.Started;\r\n this._startPendingEvents();\r\n // On a fresh start (not resume), fire the SceneReady event.\r\n // The coordinator's own scene-ready observer may have already\r\n // fired (and been lost) while the graph was stopped, so reset\r\n // the flag and handle the ready state ourselves.\r\n if (!resumingFromPause) {\r\n this._sceneEventCoordinator.sceneReadyTriggered = false;\r\n if (this._scene.isReady(true)) {\r\n this._sceneEventCoordinator.sceneReadyTriggered = true;\r\n this._sceneEventCoordinator.onEventTriggeredObservable.notifyObservers({ type: FlowGraphEventType.SceneReady });\r\n } else {\r\n // Scene isn't ready yet (e.g. pending shader compilations after\r\n // a scene swap). Use executeWhenReady(true) which restarts the\r\n // readiness check loop — a plain addOnce on onReadyObservable\r\n // may never fire if the check loop already completed.\r\n this._scene.executeWhenReady(() => {\r\n if (this.state === FlowGraphState.Started && !this._sceneEventCoordinator.sceneReadyTriggered) {\r\n this._sceneEventCoordinator.sceneReadyTriggered = true;\r\n this._sceneEventCoordinator.onEventTriggeredObservable.notifyObservers({ type: FlowGraphEventType.SceneReady });\r\n }\r\n }, true);\r\n }\r\n }\r\n }\r\n\r\n private _startPendingEvents() {\r\n for (const context of this._executionContexts) {\r\n for (const type in this._eventBlocks) {\r\n const order = this._getContextualOrder(type as FlowGraphEventType, context);\r\n for (const block of order) {\r\n block._startPendingTasks(context);\r\n }\r\n }\r\n }\r\n }\r\n\r\n private _getContextualOrder(type: FlowGraphEventType, context: FlowGraphContext): FlowGraphEventBlock[] {\r\n const order = this._eventBlocks[type].sort((a, b) => b.initPriority - a.initPriority);\r\n\r\n if (type === FlowGraphEventType.MeshPick) {\r\n const meshPickOrder = [] as FlowGraphEventBlock[];\r\n for (const block1 of order) {\r\n // If the block is a mesh pick, guarantee that picks of children meshes come before picks of parent meshes\r\n const mesh1 = (block1 as FlowGraphMeshPickEventBlock).asset.getValue(context);\r\n let i = 0;\r\n for (; i < order.length; i++) {\r\n const block2 = order[i];\r\n const mesh2 = (block2 as FlowGraphMeshPickEventBlock).asset.getValue(context);\r\n if (mesh1 && mesh2 && _IsDescendantOf(mesh1, mesh2)) {\r\n break;\r\n }\r\n }\r\n meshPickOrder.splice(i, 0, block1);\r\n }\r\n return meshPickOrder;\r\n }\r\n return order;\r\n }\r\n\r\n /**\r\n * Disposes of the flow graph. Cancels any pending tasks and removes all event listeners.\r\n */\r\n public dispose() {\r\n // Always release the scene-event wiring, even for a stopped or never-started graph.\r\n // The scene event coordinator attaches per-frame, pointer and keyboard observers to the\r\n // scene in its constructor, so a graph that is removed from its coordinator (or disposed)\r\n // while stopped would otherwise leak those observers and keep incurring per-frame overhead.\r\n this._detachEventObserver();\r\n this._sceneEventCoordinator.dispose();\r\n if (this.state === FlowGraphState.Stopped) {\r\n // Nothing is executing, so there is no run state to clear. Authored blocks are left\r\n // intact on purpose: the editor re-points a stopped graph across preview scenes via\r\n // setScene(), and each preview scene disposal raises a SceneDispose event that calls\r\n // dispose() here. Wiping the blocks would destroy the user's graph on every reset.\r\n return;\r\n }\r\n this.state = FlowGraphState.Stopped;\r\n for (const context of this._executionContexts) {\r\n context._clearPendingBlocks();\r\n context._clearPendingActivation();\r\n }\r\n this._executionContexts.length = 0;\r\n for (const type in this._eventBlocks) {\r\n this._eventBlocks[type as FlowGraphEventType].length = 0;\r\n }\r\n this._allBlocks.length = 0;\r\n }\r\n\r\n /**\r\n * Executes a function in all blocks of a flow graph, starting with the event blocks.\r\n * @param visitor the function to execute.\r\n */\r\n public visitAllBlocks(visitor: (block: FlowGraphBlock) => void) {\r\n const visitList: FlowGraphBlock[] = [];\r\n const idsAddedToVisitList = new Set<string>();\r\n for (const type in this._eventBlocks) {\r\n for (const block of this._eventBlocks[type as FlowGraphEventType]) {\r\n visitList.push(block);\r\n idsAddedToVisitList.add(block.uniqueId);\r\n }\r\n }\r\n\r\n while (visitList.length > 0) {\r\n const block = visitList.pop()!;\r\n visitor(block);\r\n\r\n for (const dataIn of block.dataInputs) {\r\n for (const connection of dataIn._connectedPoint) {\r\n if (!idsAddedToVisitList.has(connection._ownerBlock.uniqueId)) {\r\n visitList.push(connection._ownerBlock);\r\n idsAddedToVisitList.add(connection._ownerBlock.uniqueId);\r\n }\r\n }\r\n }\r\n if (block instanceof FlowGraphExecutionBlock) {\r\n for (const signalOut of block.signalOutputs) {\r\n for (const connection of signalOut._connectedPoint) {\r\n if (!idsAddedToVisitList.has(connection._ownerBlock.uniqueId)) {\r\n visitList.push(connection._ownerBlock);\r\n idsAddedToVisitList.add(connection._ownerBlock.uniqueId);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Validates the flow graph and returns all issues found.\r\n * Uses the tracked block list for complete validation including unreachable block detection.\r\n * @returns The validation result containing errors and warnings.\r\n */\r\n public validate(): IFlowGraphValidationResult {\r\n return ValidateFlowGraphWithBlockList(this, this._allBlocks);\r\n }\r\n\r\n /**\r\n * Serializes a graph\r\n * @param serializationObject the object to write the values in\r\n * @param valueSerializeFunction a function to serialize complex values\r\n */\r\n public serialize(serializationObject: any = {}, valueSerializeFunction?: (key: string, value: any, serializationObject: any) => void) {\r\n serializationObject.name = this.name;\r\n serializationObject.uniqueId = this.uniqueId;\r\n serializationObject.allBlocks = [];\r\n // Collect all blocks: traversal-reachable ones plus any registered\r\n // orphans in _allBlocks (e.g. disconnected blocks in the editor).\r\n const seen = new Set<string>();\r\n const serializeBlock = (block: FlowGraphBlock) => {\r\n if (seen.has(block.uniqueId)) {\r\n return;\r\n }\r\n seen.add(block.uniqueId);\r\n const serializedBlock: any = {};\r\n block.serialize(serializedBlock);\r\n serializationObject.allBlocks.push(serializedBlock);\r\n };\r\n this.visitAllBlocks(serializeBlock);\r\n for (const block of this._allBlocks) {\r\n serializeBlock(block);\r\n }\r\n serializationObject.executionContexts = [];\r\n for (const context of this._executionContexts) {\r\n const serializedContext: any = {};\r\n context.serialize(serializedContext, valueSerializeFunction);\r\n serializationObject.executionContexts.push(serializedContext);\r\n }\r\n }\r\n\r\n /**\r\n * Launches the flow graph editor for this graph.\r\n * The editor is lazy-loaded from {@link FlowGraph.EditorURL} the first time it is used.\r\n * @param config defines the configuration of the editor\r\n * @returns a promise fulfilled when the editor is visible\r\n */\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n public async edit(config?: IFlowGraphEditorLaunchOptions): Promise<void> {\r\n return await new Promise((resolve) => {\r\n this._BJSFLOWGRAPHEDITOR = this._BJSFLOWGRAPHEDITOR || this._getGlobalFlowGraphEditor();\r\n if (typeof this._BJSFLOWGRAPHEDITOR === \"undefined\") {\r\n const editorUrl = config && config.editorURL ? config.editorURL : FlowGraph.EditorURL;\r\n\r\n // Load the editor bundle and add it to the DOM.\r\n Tools.LoadBabylonScript(editorUrl, () => {\r\n this._BJSFLOWGRAPHEDITOR = this._BJSFLOWGRAPHEDITOR || this._getGlobalFlowGraphEditor();\r\n this._createFlowGraphEditor(config?.flowGraphEditorConfig);\r\n resolve();\r\n });\r\n } else {\r\n this._createFlowGraphEditor(config?.flowGraphEditorConfig);\r\n resolve();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Creates the flow graph editor window.\r\n * @param additionalConfig additional configuration forwarded to `FlowGraphEditor.Show()`\r\n */\r\n private _createFlowGraphEditor(additionalConfig?: any) {\r\n const editorConfig: any = {\r\n flowGraph: this,\r\n hostScene: this._scene,\r\n // edit() always targets the developer's own live graph and scene, so the editor should\r\n // attach to that scene instead of spinning up a throwaway preview scene. A caller can\r\n // still override this via additionalConfig.\r\n attachToLiveScene: true,\r\n ...additionalConfig,\r\n };\r\n this._BJSFLOWGRAPHEDITOR.FlowGraphEditor.Show(editorConfig);\r\n }\r\n}\r\n"]}
@@ -1,4 +1,4 @@
1
- import { Observable } from "../Misc/observable.js";
1
+ import { type IReadonlyObservable, Observable } from "../Misc/observable.js";
2
2
  import { type Scene } from "../scene.js";
3
3
  import { FlowGraph } from "./flowGraph.js";
4
4
  import { type IPathToObjectConverter } from "../ObjectModel/objectModelInterfaces.js";
@@ -60,6 +60,18 @@ export declare class FlowGraphCoordinator {
60
60
  * A list of all the coordinators per scene. Will be used by the inspector
61
61
  */
62
62
  static readonly SceneCoordinators: Map<Scene, FlowGraphCoordinator[]>;
63
+ /**
64
+ * Observable raised when a flow graph is added to any coordinator. Used by the inspector to keep
65
+ * the flow graph list in sync. The payload is the newly added flow graph.
66
+ */
67
+ static get OnFlowGraphAddedObservable(): IReadonlyObservable<FlowGraph>;
68
+ private static readonly _OnFlowGraphAddedObservable;
69
+ /**
70
+ * Observable raised when a flow graph is removed from any coordinator. Used by the inspector to keep
71
+ * the flow graph list in sync. The payload is the removed flow graph.
72
+ */
73
+ static get OnFlowGraphRemovedObservable(): IReadonlyObservable<FlowGraph>;
74
+ private static readonly _OnFlowGraphRemovedObservable;
63
75
  /**
64
76
  * When set to true (default) custom events will be dispatched synchronously.
65
77
  * This means that the events will be dispatched immediately when they are triggered.
@@ -8,6 +8,20 @@ import { Logger } from "../Misc/logger.js";
8
8
  * @experimental This class is still in development and is subject to change.
9
9
  */
10
10
  export class FlowGraphCoordinator {
11
+ /**
12
+ * Observable raised when a flow graph is added to any coordinator. Used by the inspector to keep
13
+ * the flow graph list in sync. The payload is the newly added flow graph.
14
+ */
15
+ static get OnFlowGraphAddedObservable() {
16
+ return this._OnFlowGraphAddedObservable;
17
+ }
18
+ /**
19
+ * Observable raised when a flow graph is removed from any coordinator. Used by the inspector to keep
20
+ * the flow graph list in sync. The payload is the removed flow graph.
21
+ */
22
+ static get OnFlowGraphRemovedObservable() {
23
+ return this._OnFlowGraphRemovedObservable;
24
+ }
11
25
  constructor(
12
26
  /**
13
27
  * the configuration of the block
@@ -62,6 +76,7 @@ export class FlowGraphCoordinator {
62
76
  const graphName = name ?? `Graph ${this._flowGraphs.length + 1}`;
63
77
  const graph = new FlowGraph({ scene: this.config.scene, coordinator: this, name: graphName });
64
78
  this._flowGraphs.push(graph);
79
+ FlowGraphCoordinator._OnFlowGraphAddedObservable.notifyObservers(graph);
65
80
  return graph;
66
81
  }
67
82
  /**
@@ -73,6 +88,7 @@ export class FlowGraphCoordinator {
73
88
  if (index !== -1) {
74
89
  graph.dispose();
75
90
  this._flowGraphs.splice(index, 1);
91
+ FlowGraphCoordinator._OnFlowGraphRemovedObservable.notifyObservers(graph);
76
92
  }
77
93
  }
78
94
  /**
@@ -89,6 +105,7 @@ export class FlowGraphCoordinator {
89
105
  dispose() {
90
106
  for (const graph of this._flowGraphs) {
91
107
  graph.dispose();
108
+ FlowGraphCoordinator._OnFlowGraphRemovedObservable.notifyObservers(graph);
92
109
  }
93
110
  this._flowGraphs.length = 0;
94
111
  this._disposeObserver?.remove();
@@ -180,4 +197,6 @@ FlowGraphCoordinator.MaxEventTypeExecutionPerFrame = 30;
180
197
  * A list of all the coordinators per scene. Will be used by the inspector
181
198
  */
182
199
  FlowGraphCoordinator.SceneCoordinators = new Map();
200
+ FlowGraphCoordinator._OnFlowGraphAddedObservable = new Observable();
201
+ FlowGraphCoordinator._OnFlowGraphRemovedObservable = new Observable();
183
202
  //# sourceMappingURL=flowGraphCoordinator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"flowGraphCoordinator.js","sourceRoot":"","sources":["../../../../dev/core/src/FlowGraph/flowGraphCoordinator.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Observer, Observable } from \"core/Misc/observable\";\r\nimport { type Scene } from \"../scene\";\r\nimport { FlowGraph } from \"./flowGraph\";\r\nimport { type IPathToObjectConverter } from \"../ObjectModel/objectModelInterfaces\";\r\nimport { type IObjectAccessor } from \"./typeDefinitions\";\r\nimport { type IAssetContainer } from \"core/IAssetContainer\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\n/**\r\n * Parameters used to create a flow graph engine.\r\n */\r\nexport interface IFlowGraphCoordinatorConfiguration {\r\n /**\r\n * The scene that the flow graph engine belongs to.\r\n */\r\n scene: Scene;\r\n}\r\n\r\n/**\r\n * Parameters used to parse a flow graph coordinator.\r\n */\r\nexport interface IFlowGraphCoordinatorParseOptions {\r\n /**\r\n * A function that will be called to parse the value of a property.\r\n * @param key the key of the property\r\n * @param serializationObject the serialization object where the property is located\r\n * @param assetsContainer the assets container\r\n * @param scene the scene that the block is being parsed in\r\n */\r\n valueParseFunction?: (key: string, serializationObject: any, assetsContainer: IAssetContainer, scene: Scene) => any;\r\n /**\r\n * The path converter to use to convert the path to an object accessor.\r\n */\r\n pathConverter?: IPathToObjectConverter<IObjectAccessor>;\r\n /**\r\n * The scene that the flow graph coordinator belongs to.\r\n */\r\n scene: Scene;\r\n}\r\n/**\r\n * This class holds all of the existing flow graphs and is responsible for creating new ones.\r\n * It also handles starting/stopping multiple graphs and communication between them through an Event Coordinator\r\n * This is the entry point for the flow graph system.\r\n * @experimental This class is still in development and is subject to change.\r\n */\r\nexport class FlowGraphCoordinator {\r\n /**\r\n * The maximum number of events per type.\r\n * This is used to limit the number of events that can be created in a single scene.\r\n * This is to prevent infinite loops.\r\n */\r\n public static MaxEventsPerType: number = 30;\r\n\r\n /**\r\n * The maximum number of execution of a specific event in a single frame.\r\n */\r\n public static MaxEventTypeExecutionPerFrame: number = 30;\r\n /**\r\n * @internal\r\n * A list of all the coordinators per scene. Will be used by the inspector\r\n */\r\n public static readonly SceneCoordinators: Map<Scene, FlowGraphCoordinator[]> = new Map();\r\n\r\n /**\r\n * When set to true (default) custom events will be dispatched synchronously.\r\n * This means that the events will be dispatched immediately when they are triggered.\r\n */\r\n public dispatchEventsSynchronously: boolean = true;\r\n\r\n private readonly _flowGraphs: FlowGraph[] = [];\r\n\r\n private _customEventsMap: Map<string, Observable<any>> = new Map();\r\n\r\n private _eventExecutionCounter: Map<string, number> = new Map();\r\n\r\n private _disposeObserver: Observer<Scene>;\r\n private _onBeforeRenderObserver: Observer<Scene>;\r\n private _executeOnNextFrame: { id: string; data?: any; uniqueId: number }[] = [];\r\n private _eventUniqueId: number = 0;\r\n\r\n public constructor(\r\n /**\r\n * the configuration of the block\r\n */\r\n public config: IFlowGraphCoordinatorConfiguration\r\n ) {\r\n // When the scene is disposed, dispose all graphs currently running on it.\r\n this._disposeObserver = this.config.scene.onDisposeObservable.add(() => {\r\n this.dispose();\r\n });\r\n\r\n this._onBeforeRenderObserver = this.config.scene.onBeforeRenderObservable.add(() => {\r\n // Reset the event execution counter at the beginning of each frame.\r\n this._eventExecutionCounter.clear();\r\n // duplicate the _executeOnNextFrame array to avoid modifying it while iterating over it\r\n const executeOnNextFrame = this._executeOnNextFrame.slice(0);\r\n if (executeOnNextFrame.length) {\r\n // Execute the events that were triggered on the next frame.\r\n for (const event of executeOnNextFrame) {\r\n this.notifyCustomEvent(event.id, event.data, false);\r\n // remove the event from the array\r\n const index = this._executeOnNextFrame.findIndex((e) => e.uniqueId === event.uniqueId);\r\n if (index !== -1) {\r\n this._executeOnNextFrame.splice(index, 1);\r\n }\r\n }\r\n }\r\n });\r\n\r\n // Add itself to the SceneCoordinators list for the Inspector.\r\n let coordinators = FlowGraphCoordinator.SceneCoordinators.get(this.config.scene);\r\n if (!coordinators) {\r\n coordinators = [];\r\n FlowGraphCoordinator.SceneCoordinators.set(this.config.scene, coordinators);\r\n }\r\n coordinators.push(this);\r\n }\r\n\r\n /**\r\n * Creates a new flow graph and adds it to the list of existing flow graphs\r\n * @param name - optional name for the new graph. If not provided, an auto-generated name is used.\r\n * @returns a new flow graph\r\n */\r\n public createGraph(name?: string): FlowGraph {\r\n const graphName = name ?? `Graph ${this._flowGraphs.length + 1}`;\r\n const graph = new FlowGraph({ scene: this.config.scene, coordinator: this, name: graphName });\r\n this._flowGraphs.push(graph);\r\n return graph;\r\n }\r\n\r\n /**\r\n * Removes a flow graph from the list of existing flow graphs and disposes it\r\n * @param graph the graph to remove\r\n */\r\n public removeGraph(graph: FlowGraph) {\r\n const index = this._flowGraphs.indexOf(graph);\r\n if (index !== -1) {\r\n graph.dispose();\r\n this._flowGraphs.splice(index, 1);\r\n }\r\n }\r\n\r\n /**\r\n * Starts all graphs\r\n */\r\n public start() {\r\n for (const graph of this._flowGraphs) {\r\n graph.start();\r\n }\r\n }\r\n\r\n /**\r\n * Disposes all graphs\r\n */\r\n public dispose() {\r\n for (const graph of this._flowGraphs) {\r\n graph.dispose();\r\n }\r\n this._flowGraphs.length = 0;\r\n this._disposeObserver?.remove();\r\n this._onBeforeRenderObserver?.remove();\r\n\r\n // Remove itself from the SceneCoordinators list for the Inspector.\r\n const coordinators = FlowGraphCoordinator.SceneCoordinators.get(this.config.scene) ?? [];\r\n const index = coordinators.indexOf(this);\r\n if (index !== -1) {\r\n coordinators.splice(index, 1);\r\n }\r\n }\r\n\r\n /**\r\n * Serializes this coordinator to a JSON object.\r\n * @param serializationObject the object to serialize to\r\n * @param valueSerializeFunction the function to use to serialize the value\r\n */\r\n public serialize(serializationObject: any, valueSerializeFunction?: (key: string, value: any, serializationObject: any) => void) {\r\n serializationObject._flowGraphs = [];\r\n for (const graph of this._flowGraphs) {\r\n const serializedGraph = {};\r\n graph.serialize(serializedGraph, valueSerializeFunction);\r\n serializationObject._flowGraphs.push(serializedGraph);\r\n }\r\n serializationObject.dispatchEventsSynchronously = this.dispatchEventsSynchronously;\r\n }\r\n\r\n /**\r\n * Gets the list of flow graphs\r\n */\r\n public get flowGraphs() {\r\n return this._flowGraphs;\r\n }\r\n\r\n /**\r\n * Get an observable that will be notified when the event with the given id is fired.\r\n * @param id the id of the event\r\n * @returns the observable for the event\r\n */\r\n public getCustomEventObservable(id: string): Observable<any> {\r\n let observable = this._customEventsMap.get(id);\r\n if (!observable) {\r\n // receive event is initialized before scene start, so no need to notify if triggered. but possible!\r\n observable = new Observable<any>(/*undefined, true*/);\r\n this._customEventsMap.set(id, observable);\r\n }\r\n return observable;\r\n }\r\n\r\n /**\r\n * Notifies the observable for the given event id with the given data.\r\n * @param id the id of the event\r\n * @param data the data to send with the event\r\n * @param async if true, the event will be dispatched asynchronously\r\n */\r\n public notifyCustomEvent(id: string, data: any, async: boolean = !this.dispatchEventsSynchronously) {\r\n if (async) {\r\n this._executeOnNextFrame.push({ id, data, uniqueId: this._eventUniqueId++ });\r\n return;\r\n }\r\n // check if we are not exceeding the max number of events\r\n if (this._eventExecutionCounter.has(id)) {\r\n const count = this._eventExecutionCounter.get(id)!;\r\n this._eventExecutionCounter.set(id, count + 1);\r\n if (count >= FlowGraphCoordinator.MaxEventTypeExecutionPerFrame) {\r\n if (count === FlowGraphCoordinator.MaxEventTypeExecutionPerFrame) {\r\n Logger.Warn(`FlowGraphCoordinator: Too many executions of event \"${id}\".`);\r\n }\r\n return;\r\n }\r\n } else {\r\n this._eventExecutionCounter.set(id, 1);\r\n }\r\n const observable = this._customEventsMap.get(id);\r\n if (observable) {\r\n observable.notifyObservers(data);\r\n }\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"flowGraphCoordinator.js","sourceRoot":"","sources":["../../../../dev/core/src/FlowGraph/flowGraphCoordinator.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Observer, type IReadonlyObservable, Observable } from \"core/Misc/observable\";\r\nimport { type Scene } from \"../scene\";\r\nimport { FlowGraph } from \"./flowGraph\";\r\nimport { type IPathToObjectConverter } from \"../ObjectModel/objectModelInterfaces\";\r\nimport { type IObjectAccessor } from \"./typeDefinitions\";\r\nimport { type IAssetContainer } from \"core/IAssetContainer\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\n/**\r\n * Parameters used to create a flow graph engine.\r\n */\r\nexport interface IFlowGraphCoordinatorConfiguration {\r\n /**\r\n * The scene that the flow graph engine belongs to.\r\n */\r\n scene: Scene;\r\n}\r\n\r\n/**\r\n * Parameters used to parse a flow graph coordinator.\r\n */\r\nexport interface IFlowGraphCoordinatorParseOptions {\r\n /**\r\n * A function that will be called to parse the value of a property.\r\n * @param key the key of the property\r\n * @param serializationObject the serialization object where the property is located\r\n * @param assetsContainer the assets container\r\n * @param scene the scene that the block is being parsed in\r\n */\r\n valueParseFunction?: (key: string, serializationObject: any, assetsContainer: IAssetContainer, scene: Scene) => any;\r\n /**\r\n * The path converter to use to convert the path to an object accessor.\r\n */\r\n pathConverter?: IPathToObjectConverter<IObjectAccessor>;\r\n /**\r\n * The scene that the flow graph coordinator belongs to.\r\n */\r\n scene: Scene;\r\n}\r\n/**\r\n * This class holds all of the existing flow graphs and is responsible for creating new ones.\r\n * It also handles starting/stopping multiple graphs and communication between them through an Event Coordinator\r\n * This is the entry point for the flow graph system.\r\n * @experimental This class is still in development and is subject to change.\r\n */\r\nexport class FlowGraphCoordinator {\r\n /**\r\n * The maximum number of events per type.\r\n * This is used to limit the number of events that can be created in a single scene.\r\n * This is to prevent infinite loops.\r\n */\r\n public static MaxEventsPerType: number = 30;\r\n\r\n /**\r\n * The maximum number of execution of a specific event in a single frame.\r\n */\r\n public static MaxEventTypeExecutionPerFrame: number = 30;\r\n /**\r\n * @internal\r\n * A list of all the coordinators per scene. Will be used by the inspector\r\n */\r\n public static readonly SceneCoordinators: Map<Scene, FlowGraphCoordinator[]> = new Map();\r\n\r\n /**\r\n * Observable raised when a flow graph is added to any coordinator. Used by the inspector to keep\r\n * the flow graph list in sync. The payload is the newly added flow graph.\r\n */\r\n public static get OnFlowGraphAddedObservable(): IReadonlyObservable<FlowGraph> {\r\n return this._OnFlowGraphAddedObservable;\r\n }\r\n private static readonly _OnFlowGraphAddedObservable = new Observable<FlowGraph>();\r\n\r\n /**\r\n * Observable raised when a flow graph is removed from any coordinator. Used by the inspector to keep\r\n * the flow graph list in sync. The payload is the removed flow graph.\r\n */\r\n public static get OnFlowGraphRemovedObservable(): IReadonlyObservable<FlowGraph> {\r\n return this._OnFlowGraphRemovedObservable;\r\n }\r\n private static readonly _OnFlowGraphRemovedObservable = new Observable<FlowGraph>();\r\n\r\n /**\r\n * When set to true (default) custom events will be dispatched synchronously.\r\n * This means that the events will be dispatched immediately when they are triggered.\r\n */\r\n public dispatchEventsSynchronously: boolean = true;\r\n\r\n private readonly _flowGraphs: FlowGraph[] = [];\r\n\r\n private _customEventsMap: Map<string, Observable<any>> = new Map();\r\n\r\n private _eventExecutionCounter: Map<string, number> = new Map();\r\n\r\n private _disposeObserver: Observer<Scene>;\r\n private _onBeforeRenderObserver: Observer<Scene>;\r\n private _executeOnNextFrame: { id: string; data?: any; uniqueId: number }[] = [];\r\n private _eventUniqueId: number = 0;\r\n\r\n public constructor(\r\n /**\r\n * the configuration of the block\r\n */\r\n public config: IFlowGraphCoordinatorConfiguration\r\n ) {\r\n // When the scene is disposed, dispose all graphs currently running on it.\r\n this._disposeObserver = this.config.scene.onDisposeObservable.add(() => {\r\n this.dispose();\r\n });\r\n\r\n this._onBeforeRenderObserver = this.config.scene.onBeforeRenderObservable.add(() => {\r\n // Reset the event execution counter at the beginning of each frame.\r\n this._eventExecutionCounter.clear();\r\n // duplicate the _executeOnNextFrame array to avoid modifying it while iterating over it\r\n const executeOnNextFrame = this._executeOnNextFrame.slice(0);\r\n if (executeOnNextFrame.length) {\r\n // Execute the events that were triggered on the next frame.\r\n for (const event of executeOnNextFrame) {\r\n this.notifyCustomEvent(event.id, event.data, false);\r\n // remove the event from the array\r\n const index = this._executeOnNextFrame.findIndex((e) => e.uniqueId === event.uniqueId);\r\n if (index !== -1) {\r\n this._executeOnNextFrame.splice(index, 1);\r\n }\r\n }\r\n }\r\n });\r\n\r\n // Add itself to the SceneCoordinators list for the Inspector.\r\n let coordinators = FlowGraphCoordinator.SceneCoordinators.get(this.config.scene);\r\n if (!coordinators) {\r\n coordinators = [];\r\n FlowGraphCoordinator.SceneCoordinators.set(this.config.scene, coordinators);\r\n }\r\n coordinators.push(this);\r\n }\r\n\r\n /**\r\n * Creates a new flow graph and adds it to the list of existing flow graphs\r\n * @param name - optional name for the new graph. If not provided, an auto-generated name is used.\r\n * @returns a new flow graph\r\n */\r\n public createGraph(name?: string): FlowGraph {\r\n const graphName = name ?? `Graph ${this._flowGraphs.length + 1}`;\r\n const graph = new FlowGraph({ scene: this.config.scene, coordinator: this, name: graphName });\r\n this._flowGraphs.push(graph);\r\n FlowGraphCoordinator._OnFlowGraphAddedObservable.notifyObservers(graph);\r\n return graph;\r\n }\r\n\r\n /**\r\n * Removes a flow graph from the list of existing flow graphs and disposes it\r\n * @param graph the graph to remove\r\n */\r\n public removeGraph(graph: FlowGraph) {\r\n const index = this._flowGraphs.indexOf(graph);\r\n if (index !== -1) {\r\n graph.dispose();\r\n this._flowGraphs.splice(index, 1);\r\n FlowGraphCoordinator._OnFlowGraphRemovedObservable.notifyObservers(graph);\r\n }\r\n }\r\n\r\n /**\r\n * Starts all graphs\r\n */\r\n public start() {\r\n for (const graph of this._flowGraphs) {\r\n graph.start();\r\n }\r\n }\r\n\r\n /**\r\n * Disposes all graphs\r\n */\r\n public dispose() {\r\n for (const graph of this._flowGraphs) {\r\n graph.dispose();\r\n FlowGraphCoordinator._OnFlowGraphRemovedObservable.notifyObservers(graph);\r\n }\r\n this._flowGraphs.length = 0;\r\n this._disposeObserver?.remove();\r\n this._onBeforeRenderObserver?.remove();\r\n\r\n // Remove itself from the SceneCoordinators list for the Inspector.\r\n const coordinators = FlowGraphCoordinator.SceneCoordinators.get(this.config.scene) ?? [];\r\n const index = coordinators.indexOf(this);\r\n if (index !== -1) {\r\n coordinators.splice(index, 1);\r\n }\r\n }\r\n\r\n /**\r\n * Serializes this coordinator to a JSON object.\r\n * @param serializationObject the object to serialize to\r\n * @param valueSerializeFunction the function to use to serialize the value\r\n */\r\n public serialize(serializationObject: any, valueSerializeFunction?: (key: string, value: any, serializationObject: any) => void) {\r\n serializationObject._flowGraphs = [];\r\n for (const graph of this._flowGraphs) {\r\n const serializedGraph = {};\r\n graph.serialize(serializedGraph, valueSerializeFunction);\r\n serializationObject._flowGraphs.push(serializedGraph);\r\n }\r\n serializationObject.dispatchEventsSynchronously = this.dispatchEventsSynchronously;\r\n }\r\n\r\n /**\r\n * Gets the list of flow graphs\r\n */\r\n public get flowGraphs() {\r\n return this._flowGraphs;\r\n }\r\n\r\n /**\r\n * Get an observable that will be notified when the event with the given id is fired.\r\n * @param id the id of the event\r\n * @returns the observable for the event\r\n */\r\n public getCustomEventObservable(id: string): Observable<any> {\r\n let observable = this._customEventsMap.get(id);\r\n if (!observable) {\r\n // receive event is initialized before scene start, so no need to notify if triggered. but possible!\r\n observable = new Observable<any>(/*undefined, true*/);\r\n this._customEventsMap.set(id, observable);\r\n }\r\n return observable;\r\n }\r\n\r\n /**\r\n * Notifies the observable for the given event id with the given data.\r\n * @param id the id of the event\r\n * @param data the data to send with the event\r\n * @param async if true, the event will be dispatched asynchronously\r\n */\r\n public notifyCustomEvent(id: string, data: any, async: boolean = !this.dispatchEventsSynchronously) {\r\n if (async) {\r\n this._executeOnNextFrame.push({ id, data, uniqueId: this._eventUniqueId++ });\r\n return;\r\n }\r\n // check if we are not exceeding the max number of events\r\n if (this._eventExecutionCounter.has(id)) {\r\n const count = this._eventExecutionCounter.get(id)!;\r\n this._eventExecutionCounter.set(id, count + 1);\r\n if (count >= FlowGraphCoordinator.MaxEventTypeExecutionPerFrame) {\r\n if (count === FlowGraphCoordinator.MaxEventTypeExecutionPerFrame) {\r\n Logger.Warn(`FlowGraphCoordinator: Too many executions of event \"${id}\".`);\r\n }\r\n return;\r\n }\r\n } else {\r\n this._eventExecutionCounter.set(id, 1);\r\n }\r\n const observable = this._customEventsMap.get(id);\r\n if (observable) {\r\n observable.notifyObservers(data);\r\n }\r\n }\r\n}\r\n"]}
@@ -35,6 +35,18 @@ interface ISogPackInternal {
35
35
  shCoeffCount: number;
36
36
  positions: Float32Array;
37
37
  }
38
+ /**
39
+ * Safe-orbit camera limits embedded in a Gaussian Splatting file's metadata (Adobe safe-orbit
40
+ * extension). Exposed on the loaded mesh via {@link GaussianSplattingMeshBase.safeOrbitCameraLimits}
41
+ * so consumers can read/apply the limits independently of the scene's active camera — the loader's
42
+ * automatic application only affects an active ArcRotateCamera at load time.
43
+ */
44
+ export interface ISafeOrbitCameraLimits {
45
+ /** Minimum safe orbit radius (distance from the camera to its target), if the file specifies one. */
46
+ radiusMin?: number;
47
+ /** Safe elevation range as `[minElevation, maxElevation]` in radians, if the file specifies one. */
48
+ elevationMinMax?: [number, number];
49
+ }
38
50
  interface IUpdateOptions {
39
51
  flipY?: boolean;
40
52
  /** @internal When set, skips reprocessing splats [0, previousVertexCount) and copies from cached arrays instead. */
@@ -270,6 +282,13 @@ export declare class GaussianSplattingMeshBase extends Mesh {
270
282
  * Off by default; intended for performance investigation only.
271
283
  */
272
284
  static LogSortPerformance: boolean;
285
+ /**
286
+ * Safe-orbit camera limits parsed from the source file's metadata, or `null` when the file
287
+ * carries none. The loader also auto-applies these to an active ArcRotateCamera at load time
288
+ * (unless `disableAutoCameraLimits` is set); this field exposes the raw values so they can be
289
+ * applied or tracked regardless of the active camera type. See {@link ISafeOrbitCameraLimits}.
290
+ */
291
+ safeOrbitCameraLimits: Nullable<ISafeOrbitCameraLimits>;
273
292
  /** @internal */
274
293
  _vertexCount: number;
275
294
  protected _worker: Nullable<Worker>;
@@ -709,6 +709,13 @@ export class GaussianSplattingMeshBase extends Mesh {
709
709
  */
710
710
  constructor(name, url = null, scene = null, keepInRam = false) {
711
711
  super(name, scene);
712
+ /**
713
+ * Safe-orbit camera limits parsed from the source file's metadata, or `null` when the file
714
+ * carries none. The loader also auto-applies these to an active ArcRotateCamera at load time
715
+ * (unless `disableAutoCameraLimits` is set); this field exposes the raw values so they can be
716
+ * applied or tracked regardless of the active camera type. See {@link ISafeOrbitCameraLimits}.
717
+ */
718
+ this.safeOrbitCameraLimits = null;
712
719
  /** @internal */
713
720
  this._vertexCount = 0;
714
721
  this._worker = null;