Sfoglia il codice sorgente

Merge pull request #4789 from RaananW/dynamic-imports

Adding Split and moving to dynamic loading of GUI
Raanan Weber 7 anni fa
parent
commit
6fce85b59b

+ 26 - 15
inspector/src/Inspector.ts

@@ -1,11 +1,11 @@
-import { AbstractMesh, Nullable, Scene, Tools } from "babylonjs";
-import * as GUI from "babylonjs-gui";
+import { AbstractMesh, Nullable, Scene, Tools, Observable } from "babylonjs";
 import "../sass/main.scss";
 import { Helpers } from "./helpers/Helpers";
 import { loadGUIProperties } from "./properties_gui";
 import { Scheduler } from "./scheduler/Scheduler";
 import { TabBar } from "./tabs/TabBar";
 
+import * as Split from "Split";
 
 export class Inspector {
 
@@ -32,6 +32,10 @@ export class Inspector {
 
     private _parentElement: Nullable<HTMLElement>;
 
+    public onGUILoaded: Observable<typeof import("babylonjs-gui")>;
+
+    public static GUIObject: typeof import("babylonjs-gui"); // should be typeof "babylonjs-gui";
+
     /** The inspector is created with the given engine.
      * If the parameter 'popup' is false, the inspector is created as a right panel on the main window.
      * If the parameter 'popup' is true, the inspector is created in another popup.
@@ -46,20 +50,27 @@ export class Inspector {
         colorBot?: string
     }) {
 
-        // Load GUI library if not already done
-        if (!GUI) {
-            Tools.LoadScript("https://preview.babylonjs.com/gui/babylon.gui.min.js", () => {
+        this.onGUILoaded = new Observable();
+
+        import("babylonjs-gui").then(GUI => {
+            // Load GUI library if not already done
+            if (!GUI || (<Object>GUI).hasOwnProperty("default")) {
+                Tools.LoadScript("https://preview.babylonjs.com/gui/babylon.gui.min.js", () => {
+                    Inspector.GUIObject = (<any>BABYLON).GUI;
+                    this.onGUILoaded.notifyObservers(Inspector.GUIObject);
+                    //Load properties of GUI objects now as GUI has to be declared before 
+                    loadGUIProperties(Inspector.GUIObject);
+                }, () => {
+                    console.warn('Error : loading "babylon.gui.min.js". Please add script https://preview.babylonjs.com/gui/babylon.min.gui.js to the HTML file.');
+                });
+            }
+            else {
+                Inspector.GUIObject = GUI;
+                this.onGUILoaded.notifyObservers(Inspector.GUIObject);
                 //Load properties of GUI objects now as GUI has to be declared before 
-                loadGUIProperties();
-            }, () => {
-                console.warn('Error : loading "babylon.gui.min.js". Please add script https://preview.babylonjs.com/gui/babylon.min.gui.js to the HTML file.');
-            });
-        }
-        else {
-            //Load properties of GUI objects now as GUI has to be declared before 
-            loadGUIProperties();
-        }
-
+                loadGUIProperties(Inspector.GUIObject);
+            }
+        })
         //get Tabbar initialTab
         this._initialTab = initialTab;
 

+ 3 - 4
inspector/src/adapters/GUIAdapter.ts

@@ -4,14 +4,13 @@ import { Helpers } from "../helpers/Helpers";
 import { AbstractTreeTool } from "../treetools/AbstractTreeTool";
 import { Checkbox, IToolVisible } from "../treetools/Checkbox";
 import { Adapter } from "./Adapter";
-import { Control } from "babylonjs-gui";
 
 
 export class GUIAdapter
     extends Adapter
     implements IToolVisible {
 
-    constructor(obj: Control) {
+    constructor(obj: import("babylonjs-gui").Control) {
         super(obj);
     }
 
@@ -41,10 +40,10 @@ export class GUIAdapter
     }
 
     public setVisible(b: boolean) {
-        (this._obj as Control).isVisible = b;
+        (this._obj).isVisible = b;
     }
 
     public isVisible(): boolean {
-        return (this._obj as Control).isVisible;
+        return (this._obj).isVisible;
     }
 }

+ 117 - 108
inspector/src/properties_gui.ts

@@ -1,116 +1,125 @@
-import * as GUI from "babylonjs-gui";
+
 import { PROPERTIES } from "./properties";
 
+export type GUITyping = typeof import("babylonjs-gui");
+
+export let guiLoaded: boolean = false;
 /**
   * Function that add gui objects properties to the variable PROPERTIES
   */
-export function loadGUIProperties() {
-    let PROPERTIES_GUI = {
-        'ValueAndUnit': {
-            type: GUI.ValueAndUnit,
-            properties: ['_value', 'unit'],
-            format: (valueAndUnit: GUI.ValueAndUnit) => { return valueAndUnit }
-        },
-        'Control': {
-            type: GUI.Control,
-            properties: [
-                '_alpha',
-                '_fontFamily',
-                '_color',
-                '_scaleX',
-                '_scaleY',
-                '_rotation',
-                '_currentMeasure',
-                '_width',
-                '_height',
-                '_left',
-                '_top',
-                '_linkedMesh',
-                'isHitTestVisible',
-                'isPointerBlocker',
-            ],
-            format: (control: GUI.Control) => { return control.name }
-        },
-        'Button': {
-            type: GUI.Button,
-            properties: new Array(),
-            format: (button: GUI.Button) => { return button.name }
-        },
-        'ColorPicker': {
-            type: GUI.ColorPicker,
-            properties: ['_value'],
-            format: (colorPicker: GUI.ColorPicker) => { return colorPicker.name }
-        },
-        'Checkbox': {
-            type: GUI.Checkbox,
-            properties: ['_isChecked', '_background'],
-            format: (checkbox: GUI.Checkbox) => { return checkbox.name }
-        },
-        'Ellipse': {
-            type: GUI.Ellipse,
-            properties: ['_thickness'],
-            format: (ellipse: GUI.Ellipse) => { return ellipse.name }
-        },
-        'Image': {
-            type: GUI.Image,
-            properties: [
-                '_imageWidth',
-                '_imageHeight',
-                '_loaded',
-                '_source',
-            ],
-            format: (image: GUI.Image) => { return image.name }
-        },
-        'Line': {
-            type: GUI.Line,
-            properties: ['_lineWidth',
-                '_background',
-                '_x1',
-                '_y1',
-                '_x2',
-                '_y2',
-            ],
-            format: (line: GUI.Line) => { return line.name }
-        },
-        'RadioButton': {
-            type: GUI.RadioButton,
-            properties: ['_isChecked', '_background'],
-            format: (radioButton: GUI.RadioButton) => { return radioButton.name }
-        },
-        'Rectangle': {
-            type: GUI.Rectangle,
-            properties: ['_thickness', '_cornerRadius'],
-            format: (rectangle: GUI.Rectangle) => { return rectangle.name }
-        },
-        'Slider': {
-            type: GUI.Slider,
-            properties: [
-                '_minimum',
-                '_maximum',
-                '_value',
-                '_background',
-                '_borderColor',
-            ],
-            format: (slider: GUI.Slider) => { return slider.name }
-        },
-        'StackPanel': {
-            type: GUI.StackPanel,
-            properties: ['_isVertical'],
-            format: (stackPanel: GUI.StackPanel) => { return stackPanel.name }
-        },
-        'TextBlock': {
-            type: GUI.TextBlock,
-            properties: ['_text', '_textWrapping'],
-            format: (textBlock: GUI.TextBlock) => { return textBlock.name }
-        },
-        'Container': {
-            type: GUI.Container,
-            properties: ['_background'],
-            format: (container: GUI.Container) => { return container.name }
-        },
-    }
+export function loadGUIProperties(GUI: GUITyping) {
+
+    guiLoaded = !!GUI;
+
+    if (guiLoaded) {
+
+        let PROPERTIES_GUI = {
+            'ValueAndUnit': {
+                type: GUI.ValueAndUnit,
+                properties: ['_value', 'unit'],
+                format: (valueAndUnit: import("babylonjs-gui").ValueAndUnit) => { return valueAndUnit }
+            },
+            'Control': {
+                type: GUI.Control,
+                properties: [
+                    '_alpha',
+                    '_fontFamily',
+                    '_color',
+                    '_scaleX',
+                    '_scaleY',
+                    '_rotation',
+                    '_currentMeasure',
+                    '_width',
+                    '_height',
+                    '_left',
+                    '_top',
+                    '_linkedMesh',
+                    'isHitTestVisible',
+                    'isPointerBlocker',
+                ],
+                format: (control: import("babylonjs-gui").Control) => { return control.name }
+            },
+            'Button': {
+                type: GUI.Button,
+                properties: new Array(),
+                format: (button: import("babylonjs-gui").Button) => { return button.name }
+            },
+            'ColorPicker': {
+                type: GUI.ColorPicker,
+                properties: ['_value'],
+                format: (colorPicker: import("babylonjs-gui").ColorPicker) => { return colorPicker.name }
+            },
+            'Checkbox': {
+                type: GUI.Checkbox,
+                properties: ['_isChecked', '_background'],
+                format: (checkbox: import("babylonjs-gui").Checkbox) => { return checkbox.name }
+            },
+            'Ellipse': {
+                type: GUI.Ellipse,
+                properties: ['_thickness'],
+                format: (ellipse: import("babylonjs-gui").Ellipse) => { return ellipse.name }
+            },
+            'Image': {
+                type: GUI.Image,
+                properties: [
+                    '_imageWidth',
+                    '_imageHeight',
+                    '_loaded',
+                    '_source',
+                ],
+                format: (image: import("babylonjs-gui").Image) => { return image.name }
+            },
+            'Line': {
+                type: GUI.Line,
+                properties: ['_lineWidth',
+                    '_background',
+                    '_x1',
+                    '_y1',
+                    '_x2',
+                    '_y2',
+                ],
+                format: (line: import("babylonjs-gui").Line) => { return line.name }
+            },
+            'RadioButton': {
+                type: GUI.RadioButton,
+                properties: ['_isChecked', '_background'],
+                format: (radioButton: import("babylonjs-gui").RadioButton) => { return radioButton.name }
+            },
+            'Rectangle': {
+                type: GUI.Rectangle,
+                properties: ['_thickness', '_cornerRadius'],
+                format: (rectangle: import("babylonjs-gui").Rectangle) => { return rectangle.name }
+            },
+            'Slider': {
+                type: GUI.Slider,
+                properties: [
+                    '_minimum',
+                    '_maximum',
+                    '_value',
+                    '_background',
+                    '_borderColor',
+                ],
+                format: (slider: import("babylonjs-gui").Slider) => { return slider.name }
+            },
+            'StackPanel': {
+                type: GUI.StackPanel,
+                properties: ['_isVertical'],
+                format: (stackPanel: import("babylonjs-gui").StackPanel) => { return stackPanel.name }
+            },
+            'TextBlock': {
+                type: GUI.TextBlock,
+                properties: ['_text', '_textWrapping'],
+                format: (textBlock: import("babylonjs-gui").TextBlock) => { return textBlock.name }
+            },
+            'Container': {
+                type: GUI.Container,
+                properties: ['_background'],
+                format: (container: import("babylonjs-gui").Container) => { return container.name }
+            },
+        }
 
-    for (let prop in PROPERTIES_GUI) {
-        (<any>PROPERTIES)[prop] = (<any>PROPERTIES_GUI)[prop];
+        for (let prop in PROPERTIES_GUI) {
+            (<any>PROPERTIES)[prop] = (<any>PROPERTIES_GUI)[prop];
+        }
     }
 } 

+ 2 - 0
inspector/src/tabs/ConsoleTab.ts

@@ -4,6 +4,8 @@ import { Inspector } from "../Inspector";
 import { Tab } from "./Tab";
 import { TabBar } from "./TabBar";
 
+import * as Split from "Split";
+
 /** 
  * The console tab will have two features : 
  * - hook all console.log call and display them in this panel (and in the browser console as well)

+ 2 - 0
inspector/src/tabs/GLTFTab.ts

@@ -9,6 +9,8 @@ import { Inspector } from "../Inspector";
 import { Tab } from "./Tab";
 import { TabBar } from "./TabBar";
 
+import * as Split from "Split";
+
 interface ILoaderDefaults {
     [extensionName: string]: {
         [key: string]: any

+ 7 - 6
inspector/src/tabs/GUITab.ts

@@ -1,4 +1,3 @@
-import { AdvancedDynamicTexture, Container, Control } from "babylonjs-gui";
 import { GUIAdapter } from "../adapters/GUIAdapter";
 import { Inspector } from "../Inspector";
 import { TreeItem } from "../tree/TreeItem";
@@ -13,11 +12,13 @@ export class GUITab extends PropertyTab {
 
     /* Overrides super */
     protected _getTree(): Array<TreeItem> {
-        let arr = [];
+        let arr: Array<TreeItem> = [];
+
+        if (!Inspector.GUIObject) return arr;
 
         // Recursive method building the tree panel
-        let createNode = (obj: Control) => {
-            let descendants = (obj as Container).children;
+        let createNode = (obj: import("babylonjs-gui").Control) => {
+            let descendants = (obj as import("babylonjs-gui").Container).children;
 
             if (descendants && descendants.length > 0) {
                 let node = new TreeItem(this, new GUIAdapter(obj));
@@ -36,8 +37,8 @@ export class GUITab extends PropertyTab {
         let instances = this._inspector.scene;
         for (let tex of instances.textures) {
             //only get GUI's textures
-            if (tex instanceof AdvancedDynamicTexture) {
-                let node = createNode(tex._rootContainer);
+            if (tex instanceof Inspector.GUIObject.AdvancedDynamicTexture) {
+                let node = createNode((<import("babylonjs-gui").AdvancedDynamicTexture>tex)._rootContainer);
                 arr.push(node);
             }
         }

+ 2 - 0
inspector/src/tabs/PropertyTab.ts

@@ -7,6 +7,8 @@ import { TreeItem } from "../tree/TreeItem";
 import { Tab } from "./Tab";
 import { TabBar } from "./TabBar";
 
+import * as Split from "Split";
+
 /**
  * A Property tab can creates two panels: 
  * a tree panel and a detail panel, 

+ 2 - 0
inspector/src/tabs/SceneTab.ts

@@ -7,6 +7,8 @@ import { Inspector } from "../Inspector";
 import { Tab } from "./Tab";
 import { TabBar } from "./TabBar";
 
+import * as Split from "Split";
+
 export class SceneTab extends Tab {
 
     private _inspector: Inspector;

+ 1 - 2
inspector/src/tabs/TabBar.ts

@@ -1,5 +1,4 @@
 import { AbstractMesh, Nullable } from "babylonjs";
-import * as GUI from "babylonjs-gui";
 import { BasicElement } from "../gui/BasicElement";
 import { Helpers } from "../helpers/Helpers";
 import { Inspector } from "../Inspector";
@@ -56,7 +55,7 @@ export class TabBar extends BasicElement {
         if (GLTFTab.IsSupported) {
             this._tabs.push(new GLTFTab(this, this._inspector));
         }
-        if (GUI) {
+        if (Inspector.GUIObject) {
             this._tabs.push(new GUITab(this, this._inspector));
         }
         this._tabs.push(new PhysicsTab(this, this._inspector));

+ 1 - 0
inspector/src/tabs/TextureTab.ts

@@ -6,6 +6,7 @@ import { TreeItem } from "../tree/TreeItem";
 import { Tab } from "./Tab";
 import { TabBar } from "./TabBar";
 
+import * as Split from "Split";
 
 export class TextureTab extends Tab {
 

+ 24 - 26
inspector/src/tools/LabelTool.ts

@@ -1,18 +1,16 @@
 import { AbstractMesh, Nullable, Scene } from "babylonjs";
-import * as GUI from "babylonjs-gui";
 import { Helpers } from "../helpers/Helpers";
 import { Inspector } from "../Inspector";
 import { AbstractTool } from "./AbstractTool";
-
+import { guiLoaded } from "../properties_gui";
 
 export class LabelTool extends AbstractTool {
 
     /** True if label are displayed, false otherwise */
     private _isDisplayed: boolean = false;
-    private _advancedTexture: Nullable<GUI.AdvancedDynamicTexture> = null;
+    private _advancedTexture: Nullable<any/*AdvancedDynamicTexture*/> = null;
     private _labelInitialized: boolean = false;
     private _scene: Nullable<Scene> = null;
-    private _guiLoaded: boolean = false;
 
     constructor(parent: HTMLElement, inspector: Inspector) {
         super('fa', 'fa-tags', parent, inspector, 'Display mesh names on the canvas');
@@ -28,48 +26,45 @@ export class LabelTool extends AbstractTool {
     }
 
     private _checkGUILoaded(): boolean {
-        if (this._guiLoaded === true) {
-            return true;
-        }
-        if (GUI) {
-            this._guiLoaded = true;
-        }
-        return this._guiLoaded;
+        return guiLoaded;
     }
 
     private _initializeLabels() {
-        // Check if the label are already initialized and quit if it's the case
-        if (this._labelInitialized || !this._scene) {
-            return;
-        }
 
         // Can't initialize them if the GUI lib is not loaded yet
         if (!this._checkGUILoaded()) {
             return;
         }
 
+
+        // Check if the label are already initialized and quit if it's the case
+        if (this._labelInitialized || !this._scene) {
+            return false;
+        }
         // Create the canvas that will be used to display the labels
-        this._advancedTexture = GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");
+        this._advancedTexture = Inspector.GUIObject.AdvancedDynamicTexture.CreateFullscreenUI("UI");
 
         // Create label for all the Meshes, Lights and Cameras
         // Those that will be created/removed after this method is called will be taken care by the event handlers added below
 
         for (let m of this._scene.meshes) {
-            this._createLabel(m);
+            this._createLabel(m, Inspector.GUIObject);
         }
 
-        this._scene.onNewMeshAddedObservable.add((m, s) => {
-            this._createLabel(m);
+        this._scene.onNewMeshAddedObservable.add((m) => {
+            this._createLabel(m, Inspector.GUIObject);
         });
 
-        this._scene.onMeshRemovedObservable.add((m, s) => {
+        this._scene.onMeshRemovedObservable.add((m) => {
             this._removeLabel(m);
         });
 
         this._labelInitialized = true;
+
+        return true;
     }
 
-    private _createLabel(mesh: AbstractMesh) {
+    private _createLabel(mesh: AbstractMesh, GUI: typeof import("babylonjs-gui")) {
         // Don't create label for "system nodes" (starting and ending with ###)
         let name = mesh.name;
 
@@ -78,14 +73,14 @@ export class LabelTool extends AbstractTool {
         }
 
         if (mesh && this._advancedTexture) {
-            let rect1 = new GUI.Rectangle();
+            let rect1: import("babylonjs-gui").Rectangle = new GUI.Rectangle();
             rect1.width = 4 + 10 * name.length + "px";
             rect1.height = "22px";
             rect1.background = "rgba(0,0,0,0.6)";
             rect1.color = "black";
             this._advancedTexture.addControl(rect1);
 
-            let label = new GUI.TextBlock();
+            let label: import("babylonjs-gui").TextBlock = new GUI.TextBlock();
             label.text = name;
             label.fontSize = 12;
             rect1.addControl(label);
@@ -110,7 +105,7 @@ export class LabelTool extends AbstractTool {
     // Action : Display/hide mesh names on the canvas
     public action() {
         // Don't toggle if the script is not loaded
-        if (!this._checkGUILoaded() || !this._advancedTexture) {
+        if (!this._checkGUILoaded()) {
             return;
         }
 
@@ -120,12 +115,15 @@ export class LabelTool extends AbstractTool {
         // Check if we have to display the labels
         if (this._isDisplayed) {
             this._initializeLabels();
-            this._advancedTexture._rootContainer.isVisible = true;
+            if (this._advancedTexture)
+                this._advancedTexture._rootContainer.isVisible = true;
+
         }
 
         // Or to hide them
         else {
-            this._advancedTexture._rootContainer.isVisible = false;
+            if (this._advancedTexture)
+                this._advancedTexture._rootContainer.isVisible = false;
         }
     }
 }

+ 1 - 1
inspector/tsconfig.json

@@ -1,7 +1,7 @@
 {
     "compilerOptions": {
         "experimentalDecorators": true,
-        "module": "commonjs",
+        "module": "esnext",
         "target": "es5",
         "noImplicitAny": true,
         "noImplicitReturns": true,