@babylonjs/inspector 8.39.1-preview → 8.39.2-preview

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.
@@ -32,8 +32,8 @@ import { PerfCollectionStrategy } from '@babylonjs/core/Misc/PerformanceViewer/p
32
32
  import '@babylonjs/core/Misc/PerformanceViewer/performanceViewerSceneExtension.js';
33
33
  import { PressureObserverWrapper } from '@babylonjs/core/Misc/pressureObserverWrapper.js';
34
34
  import { AbstractEngine } from '@babylonjs/core/Engines/abstractEngine.js';
35
- import { createRoot } from 'react-dom/client';
36
35
  import { Logger } from '@babylonjs/core/Misc/logger.js';
36
+ import { createRoot } from 'react-dom/client';
37
37
  import { FrameGraphUtils } from '@babylonjs/core/FrameGraph/frameGraphUtils.js';
38
38
  import { CameraGizmo } from '@babylonjs/core/Gizmos/cameraGizmo.js';
39
39
  import { LightGizmo } from '@babylonjs/core/Gizmos/lightGizmo.js';
@@ -2062,11 +2062,13 @@ function MakeShellServiceDefinition({ leftPaneDefaultWidth = 350, leftPaneMinWid
2062
2062
  const onSelectSidePane = new Observable(undefined, true);
2063
2063
  const onDockChanged = new Observable(undefined, true);
2064
2064
  const leftSidePaneContainerState = {
2065
+ isPresent: false,
2065
2066
  isDocked: true,
2066
2067
  dock: () => onDockChanged.notifyObservers({ location: "left", dock: true }),
2067
2068
  undock: () => onDockChanged.notifyObservers({ location: "left", dock: false }),
2068
2069
  };
2069
2070
  const rightSidePaneContainerState = {
2071
+ isPresent: false,
2070
2072
  isDocked: true,
2071
2073
  dock: () => onDockChanged.notifyObservers({ location: "right", dock: true }),
2072
2074
  undock: () => onDockChanged.notifyObservers({ location: "right", dock: false }),
@@ -2174,6 +2176,14 @@ function MakeShellServiceDefinition({ leftPaneDefaultWidth = 350, leftPaneMinWid
2174
2176
  }, [coercedSidePanes]);
2175
2177
  const hasLeftPanes = coercedSidePanes.some((entry) => entry.horizontalLocation === "left");
2176
2178
  const hasRightPanes = coercedSidePanes.some((entry) => entry.horizontalLocation === "right");
2179
+ useEffect(() => {
2180
+ leftSidePaneContainerState.isPresent = hasLeftPanes;
2181
+ rightSidePaneContainerState.isPresent = hasRightPanes;
2182
+ return () => {
2183
+ leftSidePaneContainerState.isPresent = false;
2184
+ rightSidePaneContainerState.isPresent = false;
2185
+ };
2186
+ }, [hasLeftPanes, hasRightPanes]);
2177
2187
  // If we are in compact toolbar mode, we may need to move toolbar items from the left to the right or vice versa,
2178
2188
  // depending on whether there are any side panes on that side.
2179
2189
  const coerceToolBarItemHorizontalLocation = useMemo(() => (item) => {
@@ -2240,8 +2250,12 @@ function MakeShellServiceDefinition({ leftPaneDefaultWidth = 350, leftPaneMinWid
2240
2250
  },
2241
2251
  addCentralContent: (entry) => centralContentCollection.add(entry),
2242
2252
  resetSidePaneLayout: () => localStorage.removeItem("Babylon/Settings/SidePaneDockOverrides"),
2243
- leftSidePaneContainer: leftSidePaneContainerState,
2244
- rightSidePaneContainer: rightSidePaneContainerState,
2253
+ get leftSidePaneContainer() {
2254
+ return leftSidePaneContainerState.isPresent ? leftSidePaneContainerState : null;
2255
+ },
2256
+ get rightSidePaneContainer() {
2257
+ return rightSidePaneContainerState.isPresent ? rightSidePaneContainerState : null;
2258
+ },
2245
2259
  onDockChanged,
2246
2260
  get sidePanes() {
2247
2261
  return [...sidePaneCollection.items].map((sidePaneDefinition) => {
@@ -3646,7 +3660,7 @@ const DefaultInspectorExtensionFeed = new BuiltInsExtensionFeed("Inspector", [
3646
3660
  keywords: ["export", "gltf", "glb", "babylon", "exporter", "tools"],
3647
3661
  ...BabylonWebResources,
3648
3662
  author: { name: "Alex Chuber", forumUserName: "alexchuber" },
3649
- getExtensionModuleAsync: async () => await import('./exportService-BqnzQ5KY.js'),
3663
+ getExtensionModuleAsync: async () => await import('./exportService-BtAoouDO.js'),
3650
3664
  },
3651
3665
  {
3652
3666
  name: "Capture Tools",
@@ -3654,7 +3668,7 @@ const DefaultInspectorExtensionFeed = new BuiltInsExtensionFeed("Inspector", [
3654
3668
  keywords: ["capture", "screenshot", "gif", "video", "tools"],
3655
3669
  ...BabylonWebResources,
3656
3670
  author: { name: "Alex Chuber", forumUserName: "alexchuber" },
3657
- getExtensionModuleAsync: async () => await import('./captureService-BNAvQLVs.js'),
3671
+ getExtensionModuleAsync: async () => await import('./captureService-Drl3-xpS.js'),
3658
3672
  },
3659
3673
  {
3660
3674
  name: "Import Tools",
@@ -3662,7 +3676,7 @@ const DefaultInspectorExtensionFeed = new BuiltInsExtensionFeed("Inspector", [
3662
3676
  keywords: ["import", "tools"],
3663
3677
  ...BabylonWebResources,
3664
3678
  author: { name: "Alex Chuber", forumUserName: "alexchuber" },
3665
- getExtensionModuleAsync: async () => await import('./importService-Bv9STG4_.js'),
3679
+ getExtensionModuleAsync: async () => await import('./importService-BhIQoWkj.js'),
3666
3680
  },
3667
3681
  ]);
3668
3682
 
@@ -4770,7 +4784,7 @@ function MakeModularTool(options) {
4770
4784
  });
4771
4785
  // Register the extension list service (for browsing/installing extensions) if extension feeds are provided.
4772
4786
  if (extensionFeeds.length > 0) {
4773
- const { ExtensionListServiceDefinition } = await import('./extensionsListService-CvofHYEa.js');
4787
+ const { ExtensionListServiceDefinition } = await import('./extensionsListService-C7fWebOE.js');
4774
4788
  await serviceContainer.addServiceAsync(ExtensionListServiceDefinition);
4775
4789
  }
4776
4790
  // Register the theme selector service (for selecting the theme) if theming is configured.
@@ -4851,11 +4865,15 @@ function MakeModularTool(options) {
4851
4865
  // Create and render the react root component.
4852
4866
  const reactRoot = createRoot(containerElement);
4853
4867
  reactRoot.render(createElement(modularToolRootComponent));
4868
+ let disposed = false;
4854
4869
  return {
4855
4870
  dispose: () => {
4856
4871
  // Unmount and restore the original container element display.
4857
- reactRoot.unmount();
4858
- containerElement.style.display = originalContainerElementDisplay;
4872
+ if (!disposed) {
4873
+ disposed = true;
4874
+ reactRoot.unmount();
4875
+ containerElement.style.display = originalContainerElementDisplay;
4876
+ }
4859
4877
  },
4860
4878
  };
4861
4879
  }
@@ -9429,185 +9447,217 @@ const UserFeedbackServiceDefinition = {
9429
9447
  // If it is called for a different scene that is rendering to the same canvas, then we should probably
9430
9448
  // switch the inspector instance to that scene (once this is supported).
9431
9449
  const InspectorTokens = new WeakMap();
9450
+ // This async lock is used to sequentialize all calls to ShowInspector and dispose of existing inspectors.
9451
+ // This is needed because each time Inspector is shown or hidden, it is potentially mutating the same DOM element.
9452
+ const InspectorLock = new AsyncLock();
9432
9453
  function ShowInspector(scene, options = {}) {
9454
+ // Dispose of any existing inspector for this scene.
9455
+ InspectorTokens.get(scene)?.dispose();
9456
+ // Default the dispose logic to a no-op until we know that we are actually going
9457
+ // to show the Inspector and there will be cleanup work to do.
9458
+ let disposeAsync = async () => await Promise.resolve();
9459
+ // Create an inspector dispose token. The dispose will use the same async lock to
9460
+ // make sure async dispose (hide) does not actually start until async show is finished.
9461
+ const inspectorToken = {
9462
+ dispose: () => {
9463
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
9464
+ InspectorLock.lockAsync(async () => {
9465
+ await disposeAsync();
9466
+ });
9467
+ },
9468
+ };
9469
+ // Track the inspector token for the scene.
9470
+ InspectorTokens.set(scene, inspectorToken);
9471
+ // Set default options.
9433
9472
  options = {
9434
9473
  autoResizeEngine: true,
9435
9474
  ...options,
9436
9475
  };
9437
- const inspectorToken = {
9438
- dispose: () => { },
9439
- };
9440
- let parentElement = options.containerElement ?? null;
9441
- if (!parentElement) {
9442
- parentElement = scene.getEngine().getRenderingCanvas()?.parentElement ?? null;
9443
- while (parentElement) {
9444
- const rootNode = parentElement.getRootNode();
9445
- // TODO: Right now we never parent the inspector within a ShadowRoot because we need to do more work to get FluentProvider to work correctly in this context.
9446
- if (!(rootNode instanceof ShadowRoot)) {
9447
- break;
9476
+ // Sequentialize showing the inspector (e.g. don't start showing until after a previous hide (for example) is finished).
9477
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
9478
+ InspectorLock.lockAsync(async () => {
9479
+ let parentElement = options.containerElement ?? null;
9480
+ // If a container element was not found, find an appropriate one above the engine's rendering canvas.
9481
+ if (!parentElement) {
9482
+ parentElement = scene.getEngine().getRenderingCanvas()?.parentElement ?? null;
9483
+ while (parentElement) {
9484
+ const rootNode = parentElement.getRootNode();
9485
+ // TODO: Right now we never parent the inspector within a ShadowRoot because we need to do more work to get FluentProvider to work correctly in this context.
9486
+ if (!(rootNode instanceof ShadowRoot)) {
9487
+ break;
9488
+ }
9489
+ parentElement = rootNode.host.parentElement;
9448
9490
  }
9449
- parentElement = rootNode.host.parentElement;
9450
9491
  }
9451
- }
9452
- if (!parentElement) {
9453
- return inspectorToken;
9454
- }
9455
- const existingToken = InspectorTokens.get(scene);
9456
- if (existingToken) {
9457
- existingToken.dispose();
9458
- InspectorTokens.delete(scene);
9459
- }
9460
- InspectorTokens.set(scene, inspectorToken);
9461
- const disposeActions = [];
9462
- const canvasContainerDisplay = parentElement.style.display;
9463
- const canvasContainerChildren = [];
9464
- canvasContainerChildren.push(...parentElement.childNodes);
9465
- disposeActions.push(() => {
9466
- canvasContainerChildren.forEach((child) => parentElement.appendChild(child));
9467
- });
9468
- // This service is responsible for injecting the passed in canvas as the "central content" of the shell UI (the main area between the side panes and toolbars).
9469
- const canvasInjectorServiceDefinition = {
9470
- friendlyName: "Canvas Injector",
9471
- consumes: [ShellServiceIdentity],
9472
- factory: (shellService) => {
9473
- const useStyles = makeStyles({
9474
- canvasContainer: {
9475
- display: canvasContainerDisplay,
9476
- width: "100%",
9477
- height: "100%",
9478
- },
9479
- });
9480
- const registration = shellService.addCentralContent({
9481
- key: "Canvas Injector",
9482
- component: () => {
9483
- const classes = useStyles();
9484
- const canvasContainerRef = useRef(null);
9485
- useEffect(() => {
9486
- if (canvasContainerRef.current) {
9487
- for (const child of canvasContainerChildren) {
9488
- canvasContainerRef.current.appendChild(child);
9489
- }
9490
- }
9491
- }, []);
9492
- return jsx("div", { ref: canvasContainerRef, className: classes.canvasContainer });
9493
- },
9494
- });
9495
- return {
9496
- dispose: () => {
9497
- registration.dispose();
9498
- },
9499
- };
9500
- },
9501
- };
9502
- // This service exposes the scene that was passed into Inspector through ISceneContext, which is used by other services that may be used in other contexts outside of Inspector.
9503
- const sceneContextServiceDefinition = {
9504
- friendlyName: "Inspector Scene Context",
9505
- produces: [SceneContextIdentity],
9506
- factory: () => {
9507
- return {
9508
- currentScene: scene,
9509
- currentSceneObservable: new Observable(),
9510
- };
9511
- },
9512
- };
9513
- if (options.autoResizeEngine) {
9514
- const observer = scene.onBeforeRenderObservable.add(() => scene.getEngine().resize());
9515
- disposeActions.push(() => observer.remove());
9516
- }
9517
- const modularTool = MakeModularTool({
9518
- containerElement: parentElement,
9519
- serviceDefinitions: [
9520
- // Injects the canvas the scene is rendering to into the central "content" area of the shell UI.
9521
- canvasInjectorServiceDefinition,
9522
- // Provides access to the scene in a generic way (other tools might provide a scene in a different way).
9523
- sceneContextServiceDefinition,
9524
- // Helps with managing gizmos and a shared utility layer.
9525
- GizmoServiceDefinition,
9526
- // Scene explorer tab and related services.
9527
- SceneExplorerServiceDefinition,
9528
- NodeExplorerServiceDefinition,
9529
- SkeletonExplorerServiceDefinition,
9530
- MaterialExplorerServiceDefinition,
9531
- TextureExplorerServiceDefinition,
9532
- PostProcessExplorerServiceDefinition,
9533
- RenderingPipelineExplorerServiceDefinition,
9534
- EffectLayerExplorerServiceDefinition,
9535
- ParticleSystemExplorerServiceDefinition,
9536
- SpriteManagerExplorerServiceDefinition,
9537
- AnimationGroupExplorerServiceDefinition,
9538
- GuiExplorerServiceDefinition,
9539
- FrameGraphExplorerServiceDefinition,
9540
- AtmosphereExplorerServiceDefinition,
9541
- // Properties pane tab and related services.
9542
- ScenePropertiesServiceDefinition,
9543
- PropertiesServiceDefinition,
9544
- TexturePropertiesServiceDefinition,
9545
- CommonPropertiesServiceDefinition,
9546
- TransformPropertiesServiceDefinition,
9547
- AnimationPropertiesServiceDefinition,
9548
- NodePropertiesServiceDefinition,
9549
- PhysicsPropertiesServiceDefinition,
9550
- SkeletonPropertiesServiceDefinition,
9551
- MaterialPropertiesServiceDefinition,
9552
- LightPropertiesServiceDefinition,
9553
- SpritePropertiesServiceDefinition,
9554
- ParticleSystemPropertiesServiceDefinition,
9555
- CameraPropertiesServiceDefinition,
9556
- PostProcessPropertiesServiceDefinition,
9557
- RenderingPipelinePropertiesServiceDefinition,
9558
- EffectLayerPropertiesServiceDefinition,
9559
- FrameGraphPropertiesServiceDefinition,
9560
- AnimationGroupPropertiesServiceDefinition,
9561
- MetadataPropertiesServiceDefinition,
9562
- AtmospherePropertiesServiceDefinition,
9563
- // Debug pane tab and related services.
9564
- DebugServiceDefinition,
9565
- // Stats pane tab and related services.
9566
- StatsServiceDefinition,
9567
- // Tools pane tab and related services.
9568
- ToolsServiceDefinition,
9569
- // Settings pane tab and related services.
9570
- SettingsServiceDefinition,
9571
- // Tracks entity selection state (e.g. which Mesh or Material or other entity is currently selected in scene explorer and bound to the properties pane, etc.).
9572
- SelectionServiceDefinition,
9573
- // Gizmos for manipulating objects in the scene.
9574
- GizmoToolbarServiceDefinition,
9575
- // Allows picking objects from the scene to select them.
9576
- PickingServiceDefinition,
9577
- // Adds entry points for user feedback on Inspector v2 (probably eventually will be removed).
9578
- UserFeedbackServiceDefinition,
9579
- // Adds always present "mini stats" (like fps) to the toolbar, etc.
9580
- MiniStatsServiceDefinition,
9581
- // Legacy service to support custom inspectable properties on objects.
9582
- LegacyInspectableObjectPropertiesServiceDefinition,
9583
- // Additional services passed in to the Inspector.
9584
- ...(options.serviceDefinitions ?? []),
9585
- ],
9586
- themeMode: options.themeMode,
9587
- showThemeSelector: options.showThemeSelector,
9588
- extensionFeeds: [DefaultInspectorExtensionFeed, ...(options.extensionFeeds ?? [])],
9589
- layoutMode: options.layoutMode,
9590
- toolbarMode: "compact",
9591
- sidePaneRemapper: options.sidePaneRemapper,
9592
- });
9593
- disposeActions.push(() => modularTool.dispose());
9594
- let disposed = false;
9595
- inspectorToken.dispose = () => {
9596
- if (disposed) {
9492
+ // If we couldn't find a parent element, we can't show the inspector.
9493
+ if (!parentElement) {
9494
+ Logger.Warn("Unable to find a parent element to host the Inspector.");
9597
9495
  return;
9598
9496
  }
9599
- disposeActions.reverse().forEach((dispose) => dispose());
9497
+ // This will keep track of all the cleanup work we need to do when hiding the inspector.
9498
+ const disposeActions = [];
9499
+ // Update the disposeAsync function to walk the dispose actions in reverse order
9500
+ // and call each one.
9501
+ let disposed = false;
9502
+ disposeAsync = async () => {
9503
+ if (disposed) {
9504
+ return;
9505
+ }
9506
+ disposed = true;
9507
+ for (const disposeAction of disposeActions.reverse()) {
9508
+ const result = disposeAction();
9509
+ if (result) {
9510
+ // eslint-disable-next-line no-await-in-loop
9511
+ await result;
9512
+ }
9513
+ }
9514
+ };
9515
+ // If we were responsible for resizing the engine, resize one more after the inspector UI is hidden.
9516
+ disposeActions.push(() => {
9517
+ if (options.autoResizeEngine) {
9518
+ scene.getEngine().resize();
9519
+ }
9520
+ });
9521
+ // Remove all the existing children from the parent element.
9522
+ const canvasContainerDisplay = parentElement.style.display;
9523
+ const canvasContainerChildren = [...parentElement.childNodes];
9524
+ parentElement.replaceChildren();
9525
+ disposeActions.push(async () => {
9526
+ // When the ModularTool token is disposed, it unmounts the react element, which asynchronously
9527
+ // removes all children from the parentElement. We need to wait for that to complete before
9528
+ // re-adding the canvas children back to the parentElement.
9529
+ await new Promise((resolve) => setTimeout(resolve));
9530
+ parentElement.replaceChildren(...canvasContainerChildren);
9531
+ });
9532
+ // This service is responsible for injecting the passed in canvas as the "central content" of the shell UI (the main area between the side panes and toolbars).
9533
+ const canvasInjectorServiceDefinition = {
9534
+ friendlyName: "Canvas Injector",
9535
+ consumes: [ShellServiceIdentity],
9536
+ factory: (shellService) => {
9537
+ const useStyles = makeStyles({
9538
+ canvasContainer: {
9539
+ display: canvasContainerDisplay,
9540
+ width: "100%",
9541
+ height: "100%",
9542
+ },
9543
+ });
9544
+ const registration = shellService.addCentralContent({
9545
+ key: "Canvas Injector",
9546
+ component: () => {
9547
+ const classes = useStyles();
9548
+ const canvasContainerRef = useRef(null);
9549
+ useEffect(() => {
9550
+ canvasContainerRef.current?.replaceChildren(...canvasContainerChildren);
9551
+ }, []);
9552
+ return jsx("div", { ref: canvasContainerRef, className: classes.canvasContainer });
9553
+ },
9554
+ });
9555
+ return {
9556
+ dispose: () => {
9557
+ registration.dispose();
9558
+ },
9559
+ };
9560
+ },
9561
+ };
9562
+ // This service exposes the scene that was passed into Inspector through ISceneContext, which is used by other services that may be used in other contexts outside of Inspector.
9563
+ const sceneContextServiceDefinition = {
9564
+ friendlyName: "Inspector Scene Context",
9565
+ produces: [SceneContextIdentity],
9566
+ factory: () => {
9567
+ return {
9568
+ currentScene: scene,
9569
+ currentSceneObservable: new Observable(),
9570
+ };
9571
+ },
9572
+ };
9600
9573
  if (options.autoResizeEngine) {
9601
- scene.getEngine().resize();
9602
- }
9603
- disposed = true;
9604
- };
9605
- const sceneDisposedObserver = scene.onDisposeObservable.addOnce(() => {
9606
- inspectorToken.dispose();
9607
- });
9608
- disposeActions.push(() => sceneDisposedObserver.remove());
9609
- disposeActions.push(() => {
9610
- InspectorTokens.delete(scene);
9574
+ const observer = scene.onBeforeRenderObservable.add(() => scene.getEngine().resize());
9575
+ disposeActions.push(() => observer.remove());
9576
+ }
9577
+ const modularTool = MakeModularTool({
9578
+ containerElement: parentElement,
9579
+ serviceDefinitions: [
9580
+ // Injects the canvas the scene is rendering to into the central "content" area of the shell UI.
9581
+ canvasInjectorServiceDefinition,
9582
+ // Provides access to the scene in a generic way (other tools might provide a scene in a different way).
9583
+ sceneContextServiceDefinition,
9584
+ // Helps with managing gizmos and a shared utility layer.
9585
+ GizmoServiceDefinition,
9586
+ // Scene explorer tab and related services.
9587
+ SceneExplorerServiceDefinition,
9588
+ NodeExplorerServiceDefinition,
9589
+ SkeletonExplorerServiceDefinition,
9590
+ MaterialExplorerServiceDefinition,
9591
+ TextureExplorerServiceDefinition,
9592
+ PostProcessExplorerServiceDefinition,
9593
+ RenderingPipelineExplorerServiceDefinition,
9594
+ EffectLayerExplorerServiceDefinition,
9595
+ ParticleSystemExplorerServiceDefinition,
9596
+ SpriteManagerExplorerServiceDefinition,
9597
+ AnimationGroupExplorerServiceDefinition,
9598
+ GuiExplorerServiceDefinition,
9599
+ FrameGraphExplorerServiceDefinition,
9600
+ AtmosphereExplorerServiceDefinition,
9601
+ // Properties pane tab and related services.
9602
+ ScenePropertiesServiceDefinition,
9603
+ PropertiesServiceDefinition,
9604
+ TexturePropertiesServiceDefinition,
9605
+ CommonPropertiesServiceDefinition,
9606
+ TransformPropertiesServiceDefinition,
9607
+ AnimationPropertiesServiceDefinition,
9608
+ NodePropertiesServiceDefinition,
9609
+ PhysicsPropertiesServiceDefinition,
9610
+ SkeletonPropertiesServiceDefinition,
9611
+ MaterialPropertiesServiceDefinition,
9612
+ LightPropertiesServiceDefinition,
9613
+ SpritePropertiesServiceDefinition,
9614
+ ParticleSystemPropertiesServiceDefinition,
9615
+ CameraPropertiesServiceDefinition,
9616
+ PostProcessPropertiesServiceDefinition,
9617
+ RenderingPipelinePropertiesServiceDefinition,
9618
+ EffectLayerPropertiesServiceDefinition,
9619
+ FrameGraphPropertiesServiceDefinition,
9620
+ AnimationGroupPropertiesServiceDefinition,
9621
+ MetadataPropertiesServiceDefinition,
9622
+ AtmospherePropertiesServiceDefinition,
9623
+ // Debug pane tab and related services.
9624
+ DebugServiceDefinition,
9625
+ // Stats pane tab and related services.
9626
+ StatsServiceDefinition,
9627
+ // Tools pane tab and related services.
9628
+ ToolsServiceDefinition,
9629
+ // Settings pane tab and related services.
9630
+ SettingsServiceDefinition,
9631
+ // Tracks entity selection state (e.g. which Mesh or Material or other entity is currently selected in scene explorer and bound to the properties pane, etc.).
9632
+ SelectionServiceDefinition,
9633
+ // Gizmos for manipulating objects in the scene.
9634
+ GizmoToolbarServiceDefinition,
9635
+ // Allows picking objects from the scene to select them.
9636
+ PickingServiceDefinition,
9637
+ // Adds entry points for user feedback on Inspector v2 (probably eventually will be removed).
9638
+ UserFeedbackServiceDefinition,
9639
+ // Adds always present "mini stats" (like fps) to the toolbar, etc.
9640
+ MiniStatsServiceDefinition,
9641
+ // Legacy service to support custom inspectable properties on objects.
9642
+ LegacyInspectableObjectPropertiesServiceDefinition,
9643
+ // Additional services passed in to the Inspector.
9644
+ ...(options.serviceDefinitions ?? []),
9645
+ ],
9646
+ themeMode: options.themeMode,
9647
+ showThemeSelector: options.showThemeSelector,
9648
+ extensionFeeds: [DefaultInspectorExtensionFeed, ...(options.extensionFeeds ?? [])],
9649
+ layoutMode: options.layoutMode,
9650
+ toolbarMode: "compact",
9651
+ sidePaneRemapper: options.sidePaneRemapper,
9652
+ });
9653
+ disposeActions.push(() => modularTool.dispose());
9654
+ const sceneDisposedObserver = scene.onDisposeObservable.addOnce(() => {
9655
+ inspectorToken.dispose();
9656
+ });
9657
+ disposeActions.push(() => sceneDisposedObserver.remove());
9658
+ disposeActions.push(() => {
9659
+ InspectorTokens.delete(scene);
9660
+ });
9611
9661
  });
9612
9662
  return inspectorToken;
9613
9663
  }
@@ -9944,6 +9994,10 @@ function ConvertOptions(v1Options) {
9944
9994
  * @deprecated This class only exists for backward compatibility. Use the module-level ShowInspector function instead.
9945
9995
  */
9946
9996
  class Inspector {
9997
+ // @ts-expect-error TS6133: This is private, but used by debugLayer (same as Inspector v1).
9998
+ static get _OpenedPane() {
9999
+ return this._SidePaneOpenCounter?.() ?? 0;
10000
+ }
9947
10001
  static MarkLineContainerTitleForHighlighting(title) {
9948
10002
  this.MarkMultipleLineContainerTitlesForHighlighting([title]);
9949
10003
  }
@@ -9960,7 +10014,7 @@ class Inspector {
9960
10014
  this._PopupToggler?.("right");
9961
10015
  }
9962
10016
  static get IsVisible() {
9963
- return !!this._CurrentInspectorToken;
10017
+ return !!this._CurrentInstance;
9964
10018
  }
9965
10019
  static Show(scene, userOptions) {
9966
10020
  this._Show(scene, userOptions);
@@ -9980,11 +10034,13 @@ class Inspector {
9980
10034
  factory: (shellService) => {
9981
10035
  this._PopupToggler = (side) => {
9982
10036
  const sidePaneContainer = side === "left" ? shellService.leftSidePaneContainer : shellService.rightSidePaneContainer;
9983
- if (sidePaneContainer.isDocked) {
9984
- sidePaneContainer.undock();
9985
- }
9986
- else {
9987
- sidePaneContainer.dock();
10037
+ if (sidePaneContainer) {
10038
+ if (sidePaneContainer.isDocked) {
10039
+ sidePaneContainer.undock();
10040
+ }
10041
+ else {
10042
+ sidePaneContainer.dock();
10043
+ }
9988
10044
  }
9989
10045
  };
9990
10046
  return {
@@ -10047,20 +10103,52 @@ class Inspector {
10047
10103
  },
10048
10104
  };
10049
10105
  serviceDefinitions.push(sectionHighlighterServiceDefinition);
10106
+ const openedPanesServiceDefinition = {
10107
+ friendlyName: "Opened Panes Service (Backward Compatibility)",
10108
+ consumes: [ShellServiceIdentity],
10109
+ factory: (shellService) => {
10110
+ this._SidePaneOpenCounter = () => (shellService.leftSidePaneContainer ? 1 : 0) + (shellService.rightSidePaneContainer ? 1 : 0);
10111
+ return {
10112
+ dispose: () => {
10113
+ this._SidePaneOpenCounter = null;
10114
+ },
10115
+ };
10116
+ },
10117
+ };
10118
+ serviceDefinitions.push(openedPanesServiceDefinition);
10050
10119
  options = {
10051
10120
  ...options,
10052
10121
  serviceDefinitions: [...(options.serviceDefinitions ?? []), ...serviceDefinitions],
10053
10122
  };
10054
- this._CurrentInspectorToken = ShowInspector(scene, options);
10123
+ this._CurrentInstance = {
10124
+ scene,
10125
+ options,
10126
+ disposeToken: ShowInspector(scene, options),
10127
+ };
10055
10128
  }
10056
10129
  static Hide() {
10057
- this._CurrentInspectorToken?.dispose();
10058
- this._CurrentInspectorToken = null;
10130
+ this._CurrentInstance?.disposeToken.dispose();
10131
+ this._CurrentInstance = null;
10132
+ }
10133
+ // @ts-expect-error TS6133: This is private, but used by debugLayer (same as Inspector v1).
10134
+ static _SetNewScene(scene) {
10135
+ if (this._CurrentInstance && this._CurrentInstance.scene !== scene) {
10136
+ // TODO: For now, just hide and re-show the Inspector.
10137
+ // Need to think more about this when we work on multi-scene support in Inspector v2.
10138
+ const options = this._CurrentInstance.options;
10139
+ this.Hide();
10140
+ this._CurrentInstance = {
10141
+ scene,
10142
+ options,
10143
+ disposeToken: ShowInspector(scene, options),
10144
+ };
10145
+ }
10059
10146
  }
10060
10147
  }
10061
- Inspector._CurrentInspectorToken = null;
10148
+ Inspector._CurrentInstance = null;
10062
10149
  Inspector._PopupToggler = null;
10063
10150
  Inspector._SectionHighlighter = null;
10151
+ Inspector._SidePaneOpenCounter = null;
10064
10152
  Inspector.OnSelectionChangeObservable = new Observable();
10065
10153
  Inspector.OnPropertyChangedObservable = new Observable();
10066
10154
 
@@ -10320,4 +10408,4 @@ const TextAreaPropertyLine = (props) => {
10320
10408
  };
10321
10409
 
10322
10410
  export { SettingsContextIdentity as $, useAsyncResource as A, ButtonLine as B, Collapse as C, DebugServiceIdentity as D, ExtensibleAccordion as E, FileUploadLine as F, useCompactMode as G, useSidePaneDockOverrides as H, Inspector as I, useAngleConverters as J, MakeTeachingMoment as K, Link as L, MakeLazyComponent as M, NumberDropdownPropertyLine as N, MakeDialogTeachingMoment as O, PropertiesServiceIdentity as P, InterceptFunction as Q, GetPropertyDescriptor as R, SwitchPropertyLine as S, ToolsServiceIdentity as T, IsPropertyReadonly as U, InterceptProperty as V, ObservableCollection as W, ConstructorFactory as X, SceneContextIdentity as Y, SelectionServiceIdentity as Z, SelectionServiceDefinition as _, SyncedSliderPropertyLine as a, ShowInspector as a0, AccordionSection as a1, Accordion as a2, Button as a3, Checkbox as a4, ColorPickerPopup as a5, InputHexField as a6, InputHsvField as a7, ComboBox as a8, DraggableLine as a9, Color4PropertyLine as aA, HexPropertyLine as aB, TextInputPropertyLine as aC, NumberInputPropertyLine as aD, LinkPropertyLine as aE, PropertyLine as aF, LineContainer as aG, PlaceholderPropertyLine as aH, SpinButtonPropertyLine as aI, StringifiedPropertyLine as aJ, TextAreaPropertyLine as aK, TextPropertyLine as aL, RotationVectorPropertyLine as aM, QuaternionPropertyLine as aN, Vector2PropertyLine as aO, Vector3PropertyLine as aP, Vector4PropertyLine as aQ, Dropdown as aa, NumberDropdown as ab, StringDropdown as ac, FactorGradientComponent as ad, Color3GradientComponent as ae, Color4GradientComponent as af, ColorStepGradientComponent as ag, InfoLabel as ah, List as ai, MessageBar as aj, PositionedPopover as ak, SearchBar as al, SearchBox as am, SpinButton as an, Switch as ao, SyncedSliderInput as ap, Textarea as aq, TextInput as ar, ToggleButton as as, FactorGradientList as at, Color3GradientList as au, Color4GradientList as av, Pane as aw, BooleanBadgePropertyLine as ax, CheckboxPropertyLine as ay, Color3PropertyLine as az, ShellServiceIdentity as b, MakePopoverTeachingMoment as c, TeachingMoment as d, SidePaneContainer as e, SceneExplorerServiceIdentity as f, SettingsServiceIdentity as g, StatsServiceIdentity as h, StringDropdownPropertyLine as i, BoundProperty as j, LinkToEntityPropertyLine as k, BuiltInsExtensionFeed as l, useProperty as m, useVector3Property as n, useColor3Property as o, useColor4Property as p, useQuaternionProperty as q, MakePropertyHook as r, useInterceptObservable as s, useEventfulState as t, useExtensionManager as u, useObservableState as v, useObservableCollection as w, useOrderedObservableCollection as x, usePollingObservable as y, useResource as z };
10323
- //# sourceMappingURL=index-DUdNW7K3.js.map
10411
+ //# sourceMappingURL=index-B1xdfROw.js.map