Skip to content

Commit

Permalink
Added JSON-based procedural code generator to the Playground (#15243)
Browse files Browse the repository at this point in the history
* Added JSON-based procedural code generator to the Playground

* Fixing Linting in PG procedural code generator

* try catch the JSON fetch in case of broken JSON

* Linting Fix - console.error --> console.log

* Linting Fix - drop console
  • Loading branch information
Tricotou committed Jul 9, 2024
1 parent 2f1cf35 commit a00410a
Show file tree
Hide file tree
Showing 8 changed files with 712 additions and 220 deletions.
3 changes: 3 additions & 0 deletions packages/tools/playground/public/imgs/fluentCode.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
94 changes: 94 additions & 0 deletions packages/tools/playground/public/procedural.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
[
{
"label": "Run",
"tooltip": "Run the code generator with these params",
"onClick": "onGenerate"
},
{
"label": "Run Auto",
"tooltip": "Automatic run of the code generator on param change",
"storeKey": "generateAuto",
"defaultValue": true,
"onCheck": "empty",
"keepExpanded": true
},
{
"label": "Debug Layer",
"tooltip": "Open debug layer",
"storeKey": "debugLayer",
"defaultValue": false,
"onCheck": "onUpdateGenerator",
"keepExpanded": true
},
{
"label": "Camera",
"tooltip": "Select a camera type",
"storeKey": "useCamera",
"defaultValue": "Arc Rotate (Rad)",
"subItems": ["Arc Rotate (Rad)", "Arc Rotate (Deg)", "Free", "WebXR"],
"onClick": "onUpdateGenerator",
"keepExpanded": true
},
{
"label": "Light",
"tooltip": "Select a light type",
"storeKey": "useLight",
"defaultValue": "Hemispheric",
"subItems": ["Hemispheric", "Directionnal", "Point", "Spot", "3 Spots"],
"onClick": "onUpdateGenerator",
"keepExpanded": true
},
{
"label": "Shadows",
"tooltip": "Enable shadows",
"storeKey": "useShadows",
"defaultValue": false,
"onCheck": "onUpdateGenerator",
"keepExpanded": true
},
{
"label": "Mesh Builder",
"tooltip": "Build meshes using BABYLON.MeshBuilder",
"storeKeys": ["useGround", "useSphere", "useBox", "useCylinder"],
"defaultValues": [true, true, false, false],
"subItems": ["Ground", "Sphere", "Box", "Cylinder"],
"onCheck": "onUpdateGenerator",
"keepExpanded": true
},
{
"label": "Animations",
"tooltip": "Import animated characters",
"storeKey": "useAnimation",
"defaultValue": "None",
"subItems": ["None", "Dude", "Dummy", "Samba Girl"],
"onClick": "onUpdateGenerator",
"keepExpanded": true
},
{
"label": "Particles",
"tooltip": "Add a simple particle system to the scene",
"storeKey": "useParticles",
"defaultValue": "None",
"subItems": ["None", "Simple", "Color Gradient", "Complex"],
"onClick": "onUpdateGenerator",
"keepExpanded": true
},
{
"label": "Load Snippet",
"tooltip": "Load asset from Snippet Server",
"storeKey": "useSnippet",
"defaultValue": "None",
"subItems": ["None", "Particles", "Node Material", "GUI", "GUI on Mesh"],
"onClick": "onUpdateGenerator",
"keepExpanded": true
},
{
"label": "Import / Export",
"tooltip": "Import or Export assets",
"storeKey": "useImport",
"defaultValue": "None",
"subItems": ["None", "Import Mesh", "Export GLB", "Export GLTF"],
"onClick": "onUpdateGenerator",
"keepExpanded": true
}
]
344 changes: 235 additions & 109 deletions packages/tools/playground/public/templates.json

Large diffs are not rendered by default.

265 changes: 164 additions & 101 deletions packages/tools/playground/src/components/commandBarComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,34 @@ interface ICommandBarComponentProps {

export class CommandBarComponent extends React.Component<ICommandBarComponentProps> {
private _webGPUSupported: boolean = false;
private _procedural: {
label: string;
tooltip: string;
storeKey?: string;
defaultValue?: boolean | string;
subItems?: string[];
onClick?: string;
onCheck?: string;
keepExpanded?: boolean;
}[];

public constructor(props: ICommandBarComponentProps) {
super(props);
// First Fetch JSON data for procedural code
this._procedural = [];
fetch("procedural.json")
.then((response) => response.json())
.then((data) => {
this._procedural = data;
this._load();
})
.catch((err) => {
//console.log("Unable to load procedural.json", err);
this._load();
});
}

private _load() {
this.props.globalState.onLanguageChangedObservable.add(() => {
this.forceUpdate();
});
Expand All @@ -42,6 +67,14 @@ export class CommandBarComponent extends React.Component<ICommandBarComponentPro
this.props.globalState.onNewRequiredObservable.notifyObservers();
}

onUpdateGenerator() {
this.props.globalState.onUpdateGeneratorRequiredObservable.notifyObservers();
}

onGenerate() {
this.props.globalState.onGenerateRequiredObservable.notifyObservers();
}

onClear() {
this.props.globalState.onClearRequiredObservable.notifyObservers();
}
Expand All @@ -63,6 +96,135 @@ export class CommandBarComponent extends React.Component<ICommandBarComponentPro
}

public override render() {
// Main options for the editor itself
const editorOptions = [
{
label: "Theme",
tooltip: "Controls the color scheme of the playground",
storeKey: "theme",
defaultValue: "Light",
subItems: ["Light", "Dark"],
onClick: () => {
this.props.globalState.onThemeChangedObservable.notifyObservers();
},
},
{
label: "Font size",
tooltip: "Change the font size of the code editor",
storeKey: "font-size",
defaultValue: "14",
subItems: ["12", "14", "16", "18", "20", "22", "24", "26", "28", "30"],
onClick: () => {
this.props.globalState.onFontSizeChangedObservable.notifyObservers();
},
},
{
label: "Safe mode",
tooltip: "Asks to confirm if you leave page without saving",
storeKey: "safe-mode",
defaultValue: false,
onCheck: () => {},
},
{
label: "CTRL+S to save",
tooltip: "Saves your playground code online and creates a shareable link",
storeKey: "ctrl-s-to-save",
defaultValue: true,
onCheck: () => {},
},
{
label: "editor",
tooltip: "Show/Hide the Code Editor",
storeKey: "editor",
defaultValue: true,
onCheck: (value: boolean) => {
this.props.globalState.onEditorDisplayChangedObservable.notifyObservers(value);
},
},
{
label: "minimap",
tooltip: "Show/Hide the Code Minimap",
storeKey: "minimap",
defaultValue: true,
onCheck: (value: boolean) => {
this.props.globalState.onMinimapChangedObservable.notifyObservers(value);
},
},
{
label: "fullscreen",
tooltip: "Makes the canvas fullscreen",
onClick: () => {
this.props.globalState.onFullcreenRequiredObservable.notifyObservers();
},
},
{
label: "fullscreen editor",
tooltip: "Makes the code editor fullscreen",
onClick: () => {
this.props.globalState.onEditorFullcreenRequiredObservable.notifyObservers();
},
},
{
label: "format code",
tooltip: "Autoformats code",
onClick: () => {
this.props.globalState.onFormatCodeRequiredObservable.notifyObservers();
},
},
{
label: "metadata",
tooltip: "Edit the playground title, description, and tags",
onClick: () => {
this.props.globalState.onDisplayMetadataObservable.notifyObservers(true);
},
},
{
label: "QR code",
tooltip: "Shows a QR code that points to this playground",
onClick: () => {
this.props.globalState.onQRCodeRequiredObservable.notifyObservers(true);
},
},
{
label: "Load Unity Toolkit",
tooltip: "Loads the Unity Toolkit into the playground",
storeKey: "unity-toolkit",
defaultValue: false,
onCheck: () => {},
},
];

// Procedural Code Generator Options (build from procedural.json)
let proceduralOptions: any[] = [];
proceduralOptions = this._procedural.map((item) => ({
...item,
onClick:
typeof item.onClick === "string"
? {
empty: () => {},
onGenerate: () => {
this.onGenerate();
},
onUpdateGenerator: () => {
this.onUpdateGenerator();
},
}[item.onClick]
: undefined,
onCheck:
typeof item.onCheck === "string"
? {
empty: () => {},
onGenerate: () => {
this.onGenerate();
},
onUpdateGenerator: () => {
this.onUpdateGenerator();
},
}[item.onCheck]
: undefined,
}));

// Engine Version Options
const activeVersion = Utilities.ReadStringFromStore("version", "Latest", true);
const activeEngineVersion = Utilities.ReadStringFromStore("engineVersion", "WebGL2", true);

Expand Down Expand Up @@ -147,108 +309,9 @@ export class CommandBarComponent extends React.Component<ICommandBarComponentPro
onClick={() => this.onDownload()}
/>
<CommandButtonComponent globalState={this.props.globalState} tooltip="Create new" icon="new" isActive={false} onClick={() => this.onNew()} />
<CommandDropdownComponent globalState={this.props.globalState} icon="fluentCode" tooltip="Code Generator" items={proceduralOptions} />
<CommandButtonComponent globalState={this.props.globalState} tooltip="Clear code" icon="clear" isActive={false} onClick={() => this.onClear()} />
<CommandDropdownComponent
globalState={this.props.globalState}
icon="options"
tooltip="Options"
items={[
{
label: "Theme",
tooltip: "Controls the color scheme of the playground",
storeKey: "theme",
defaultValue: "Light",
subItems: ["Light", "Dark"],
onClick: () => {
this.props.globalState.onThemeChangedObservable.notifyObservers();
},
},
{
label: "Font size",
tooltip: "Change the font size of the code editor",
storeKey: "font-size",
defaultValue: "14",
subItems: ["12", "14", "16", "18", "20", "22", "24", "26", "28", "30"],
onClick: () => {
this.props.globalState.onFontSizeChangedObservable.notifyObservers();
},
},
{
label: "Safe mode",
tooltip: "Asks to confirm if you leave page without saving",
storeKey: "safe-mode",
defaultValue: false,
onCheck: () => {},
},
{
label: "CTRL+S to save",
tooltip: "Saves your playground code online and creates a shareable link",
storeKey: "ctrl-s-to-save",
defaultValue: true,
onCheck: () => {},
},
{
label: "editor",
tooltip: "Show/Hide the Code Editor",
storeKey: "editor",
defaultValue: true,
onCheck: (value) => {
this.props.globalState.onEditorDisplayChangedObservable.notifyObservers(value);
},
},
{
label: "minimap",
tooltip: "Show/Hide the Code Minimap",
storeKey: "minimap",
defaultValue: true,
onCheck: (value) => {
this.props.globalState.onMinimapChangedObservable.notifyObservers(value);
},
},
{
label: "fullscreen",
tooltip: "Makes the canvas fullscreen",
onClick: () => {
this.props.globalState.onFullcreenRequiredObservable.notifyObservers();
},
},
{
label: "fullscreen editor",
tooltip: "Makes the code editor fullscreen",
onClick: () => {
this.props.globalState.onEditorFullcreenRequiredObservable.notifyObservers();
},
},
{
label: "format code",
tooltip: "Autoformats code",
onClick: () => {
this.props.globalState.onFormatCodeRequiredObservable.notifyObservers();
},
},
{
label: "metadata",
tooltip: "Edit the playground title, description, and tags",
onClick: () => {
this.props.globalState.onDisplayMetadataObservable.notifyObservers(true);
},
},
{
label: "QR code",
tooltip: "Shows a QR code that points to this playground",
onClick: () => {
this.props.globalState.onQRCodeRequiredObservable.notifyObservers(true);
},
},
{
label: "Load Unity Toolkit",
tooltip: "Loads the Unity Toolkit into the playground",
storeKey: "unity-toolkit",
defaultValue: false,
onCheck: () => {},
},
]}
/>
<CommandDropdownComponent globalState={this.props.globalState} icon="options" tooltip="Options" items={editorOptions} />
</div>
<div className="commands-right">
<CommandDropdownComponent
Expand Down
Loading

0 comments on commit a00410a

Please sign in to comment.