From cedc6ea3e927afe48a1941223e559a31453d7819 Mon Sep 17 00:00:00 2001 From: Florian Rival Date: Fri, 27 Dec 2024 22:40:04 +0100 Subject: [PATCH 01/12] WIP --- Core/GDCore/Project/PropertyDescriptor.cpp | 4 +- .../abstract-debugger-client.ts | 11 +++ newIDE/app/src/Debugger/index.js | 26 +++---- .../app/src/EmbeddedGame/EmbeddedGameFrame.js | 70 +++++++++++++++++++ .../BrowserS3PreviewLauncher/index.js | 5 ++ .../LocalPreviewLauncher/index.js | 4 ++ .../MainFrame/EditorTabs/EditorTabsHandler.js | 5 ++ newIDE/app/src/MainFrame/TabsTitlebar.js | 7 +- newIDE/app/src/MainFrame/index.js | 14 +++- .../CollisionMasksEditor/index.js | 2 +- .../SpriteEditor/PointsEditor/index.js | 2 +- .../src/SceneEditor/EditorsDisplay.flow.js | 1 + .../SceneEditor/MosaicEditorsDisplay/index.js | 4 +- newIDE/app/src/SceneEditor/index.js | 8 +++ newIDE/app/src/UI/ClosableTabs.js | 2 + newIDE/app/src/UI/EditorMosaic/index.js | 11 ++- newIDE/app/src/UI/Theme/Global/Mosaic.css | 15 +++- newIDE/app/src/UI/Toolbar.js | 1 + 18 files changed, 170 insertions(+), 22 deletions(-) create mode 100644 newIDE/app/src/EmbeddedGame/EmbeddedGameFrame.js diff --git a/Core/GDCore/Project/PropertyDescriptor.cpp b/Core/GDCore/Project/PropertyDescriptor.cpp index 4b5b7254d8f7..bc35302f056f 100644 --- a/Core/GDCore/Project/PropertyDescriptor.cpp +++ b/Core/GDCore/Project/PropertyDescriptor.cpp @@ -51,7 +51,9 @@ void PropertyDescriptor::UnserializeFrom(const SerializerElement& element) { currentValue = element.GetChild("value").GetStringValue(); type = element.GetChild("type").GetStringValue(); if (type == "Number") { - gd::String unitName = element.GetChild("unit").GetStringValue(); + gd::String unitName = element.HasChild("unit") + ? element.GetChild("unit").GetStringValue() + : ""; measurementUnit = gd::MeasurementUnit::HasDefaultMeasurementUnitNamed(unitName) ? measurementUnit = diff --git a/GDJS/Runtime/debugger-client/abstract-debugger-client.ts b/GDJS/Runtime/debugger-client/abstract-debugger-client.ts index 51622df0d707..bddb6fc0db58 100644 --- a/GDJS/Runtime/debugger-client/abstract-debugger-client.ts +++ b/GDJS/Runtime/debugger-client/abstract-debugger-client.ts @@ -264,6 +264,8 @@ namespace gdjs { that._hotReloader.hotReload().then((logs) => { that.sendHotReloaderLogs(logs); }); + } else if (data.command === 'updateInstances') { + // TODO: do an update/partial hot reload of the instances } else { logger.info( 'Unknown command "' + data.command + '" received by the debugger.' @@ -567,6 +569,15 @@ namespace gdjs { ); } + sendInstancesUpdated(runtimeObjects: gdjs.RuntimeObject[]): void { + this._sendMessage( + circularSafeStringify({ + command: 'instances.updated', + payload: 'TODO', + }) + ); + } + /** * Send profiling results. * @param framesAverageMeasures The measures made for each frames. diff --git a/newIDE/app/src/Debugger/index.js b/newIDE/app/src/Debugger/index.js index 9d2c66405c11..c11ce6aa6ebb 100644 --- a/newIDE/app/src/Debugger/index.js +++ b/newIDE/app/src/Debugger/index.js @@ -276,24 +276,26 @@ export default class Debugger extends React.Component { const { previewDebuggerServer } = this.props; previewDebuggerServer.sendMessage(id, { command: 'play' }); - this.setState( - state => ({ - gameIsPaused: { ...state.gameIsPaused, [id]: false }, - }), - () => this.updateToolbar() - ); + // TODO: state should be set by the game (game.paused, game.resumed) + // this.setState( + // state => ({ + // gameIsPaused: { ...state.gameIsPaused, [id]: false }, + // }), + // () => this.updateToolbar() + // ); }; _pause = (id: DebuggerId) => { const { previewDebuggerServer } = this.props; previewDebuggerServer.sendMessage(id, { command: 'pause' }); - this.setState( - state => ({ - gameIsPaused: { ...state.gameIsPaused, [id]: true }, - }), - () => this.updateToolbar() - ); + // TODO: state should be set by the game (game.paused, game.resumed) + // this.setState( + // state => ({ + // gameIsPaused: { ...state.gameIsPaused, [id]: true }, + // }), + // () => this.updateToolbar() + // ); }; _refresh = (id: DebuggerId) => { diff --git a/newIDE/app/src/EmbeddedGame/EmbeddedGameFrame.js b/newIDE/app/src/EmbeddedGame/EmbeddedGameFrame.js new file mode 100644 index 000000000000..3c7e605d4b0f --- /dev/null +++ b/newIDE/app/src/EmbeddedGame/EmbeddedGameFrame.js @@ -0,0 +1,70 @@ +// @flow +import * as React from 'react'; + +type SwitchToPreviewOptions = {| + previewIndexHtmlLocation: string, +|}; + +type SwitchToSceneEditionOptions = {| + sceneName: string, +|}; + +let onSwitchToPreview: null | (SwitchToPreviewOptions => void) = null; +let onSwitchToSceneEdition: null | (SwitchToSceneEditionOptions => void) = null; + +export const switchToPreview = ({ + previewIndexHtmlLocation, +}: SwitchToPreviewOptions) => { + if (!onSwitchToPreview) throw new Error('No EmbeddedGameFrame registered.'); + onSwitchToPreview({ previewIndexHtmlLocation }); +}; + +export const switchToSceneEdition = ({ + sceneName, +}: SwitchToSceneEditionOptions) => { + if (!onSwitchToSceneEdition) throw new Error('No EmbeddedGameFrame registered.'); + onSwitchToSceneEdition({ sceneName }); +}; + +export const EmbeddedGameFrame = () => { + const [ + previewIndexHtmlLocation, + setPreviewIndexHtmlLocation, + ] = React.useState(''); + const iframeRef = React.useRef(null); + // TODO: display a loader when the preview is being loaded. + + React.useEffect(() => { + // TODO: use a real context for this? + onSwitchToPreview = (options: SwitchToPreviewOptions) => { + setPreviewIndexHtmlLocation(options.previewIndexHtmlLocation); + if (iframeRef.current) { + iframeRef.current.contentWindow.focus(); + } + }; + onSwitchToSceneEdition = (options: SwitchToSceneEditionOptions) => { + console.log("TODO: switch to scene edition", options); + }; + }, []); + + return ( +
+
+