gdcore-tools 2.0.0-beta5 → 2.0.0-beta6

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.
Files changed (77) hide show
  1. package/dist/Runtime/CustomRuntimeObject.js +1 -1
  2. package/dist/Runtime/CustomRuntimeObject.js.map +2 -2
  3. package/dist/Runtime/CustomRuntimeObjectInstanceContainer.js +1 -1
  4. package/dist/Runtime/CustomRuntimeObjectInstanceContainer.js.map +2 -2
  5. package/dist/Runtime/Extensions/3D/CustomRuntimeObject3D.js +1 -1
  6. package/dist/Runtime/Extensions/3D/CustomRuntimeObject3D.js.map +2 -2
  7. package/dist/Runtime/Extensions/AdMob/admobtools.js +1 -1
  8. package/dist/Runtime/Extensions/AdMob/admobtools.js.map +2 -2
  9. package/dist/Runtime/Extensions/AnchorBehavior/anchorruntimebehavior.js +1 -1
  10. package/dist/Runtime/Extensions/AnchorBehavior/anchorruntimebehavior.js.map +2 -2
  11. package/dist/Runtime/Extensions/Effects/JsExtension.js +2 -2
  12. package/dist/Runtime/Extensions/Multiplayer/JsExtension.js +97 -7
  13. package/dist/Runtime/Extensions/Multiplayer/messageManager.js +1 -1
  14. package/dist/Runtime/Extensions/Multiplayer/messageManager.js.map +2 -2
  15. package/dist/Runtime/Extensions/Multiplayer/multiplayercomponents.js +1 -1
  16. package/dist/Runtime/Extensions/Multiplayer/multiplayercomponents.js.map +2 -2
  17. package/dist/Runtime/Extensions/Multiplayer/multiplayerobjectruntimebehavior.js +1 -1
  18. package/dist/Runtime/Extensions/Multiplayer/multiplayerobjectruntimebehavior.js.map +2 -2
  19. package/dist/Runtime/Extensions/Multiplayer/multiplayertools.js +1 -1
  20. package/dist/Runtime/Extensions/Multiplayer/multiplayertools.js.map +2 -2
  21. package/dist/Runtime/Extensions/PanelSpriteObject/panelspriteruntimeobject-pixi-renderer.js +1 -1
  22. package/dist/Runtime/Extensions/PanelSpriteObject/panelspriteruntimeobject-pixi-renderer.js.map +2 -2
  23. package/dist/Runtime/Extensions/Physics2Behavior/JsExtension.js +62 -27
  24. package/dist/Runtime/Extensions/Physics2Behavior/physics2runtimebehavior.js +1 -1
  25. package/dist/Runtime/Extensions/Physics2Behavior/physics2runtimebehavior.js.map +2 -2
  26. package/dist/Runtime/Extensions/Spine/JsExtension.js +32 -0
  27. package/dist/Runtime/Extensions/Spine/spineruntimeobject-pixi-renderer.js +1 -1
  28. package/dist/Runtime/Extensions/Spine/spineruntimeobject-pixi-renderer.js.map +2 -2
  29. package/dist/Runtime/Extensions/Spine/spineruntimeobject.js +1 -1
  30. package/dist/Runtime/Extensions/Spine/spineruntimeobject.js.map +2 -2
  31. package/dist/Runtime/Extensions/TextInput/JsExtension.js +3 -1
  32. package/dist/Runtime/Extensions/TileMap/JsExtension.js +84 -29
  33. package/dist/Runtime/Extensions/TileMap/collision/TransformedTileMap.js +1 -1
  34. package/dist/Runtime/Extensions/TileMap/collision/TransformedTileMap.js.map +2 -2
  35. package/dist/Runtime/Extensions/TileMap/helper/TileMapHelper.js +1 -1
  36. package/dist/Runtime/Extensions/TileMap/helper/TileMapHelper.js.map +1 -1
  37. package/dist/Runtime/Extensions/TileMap/helper/dts/load/tiled/TiledTileMapLoader.d.ts.map +1 -1
  38. package/dist/Runtime/Extensions/TileMap/helper/dts/model/TileMapModel.d.ts +12 -1
  39. package/dist/Runtime/Extensions/TileMap/helper/dts/model/TileMapModel.d.ts.map +1 -1
  40. package/dist/Runtime/Extensions/TileMap/helper/dts/render/TileMapManager.d.ts.map +1 -1
  41. package/dist/Runtime/Extensions/TileMap/simpletilemapruntimeobject.js +1 -1
  42. package/dist/Runtime/Extensions/TileMap/simpletilemapruntimeobject.js.map +2 -2
  43. package/dist/Runtime/Extensions/TileMap/tilemapruntimeobject-pixi-renderer.js +1 -1
  44. package/dist/Runtime/Extensions/TileMap/tilemapruntimeobject-pixi-renderer.js.map +2 -2
  45. package/dist/Runtime/Extensions/TweenBehavior/JsExtension.js +1 -0
  46. package/dist/Runtime/RuntimeInstanceContainer.js.map +2 -2
  47. package/dist/Runtime/SpriteAnimator.js +1 -1
  48. package/dist/Runtime/SpriteAnimator.js.map +2 -2
  49. package/dist/Runtime/debugger-client/InGameDebugger.js +1 -1
  50. package/dist/Runtime/debugger-client/InGameDebugger.js.map +2 -2
  51. package/dist/Runtime/debugger-client/abstract-debugger-client.js +1 -1
  52. package/dist/Runtime/debugger-client/abstract-debugger-client.js.map +2 -2
  53. package/dist/Runtime/debugger-client/hot-reloader.js +2 -1
  54. package/dist/Runtime/debugger-client/hot-reloader.js.map +2 -2
  55. package/dist/Runtime/debugger-client/minimal-debugger-client.js +2 -0
  56. package/dist/Runtime/debugger-client/minimal-debugger-client.js.map +7 -0
  57. package/dist/Runtime/debugger-client/websocket-debugger-client.js.map +2 -2
  58. package/dist/Runtime/debugger-client/window-message-debugger-client.js.map +2 -2
  59. package/dist/Runtime/pixi-renderers/spriteruntimeobject-pixi-renderer.js +1 -1
  60. package/dist/Runtime/pixi-renderers/spriteruntimeobject-pixi-renderer.js.map +2 -2
  61. package/dist/Runtime/runtimegame.js +1 -1
  62. package/dist/Runtime/runtimegame.js.map +2 -2
  63. package/dist/Runtime/runtimescene.js +1 -1
  64. package/dist/Runtime/runtimescene.js.map +2 -2
  65. package/dist/Runtime/scenestack.js +1 -1
  66. package/dist/Runtime/scenestack.js.map +2 -2
  67. package/dist/Runtime/spriteruntimeobject.js +1 -1
  68. package/dist/Runtime/spriteruntimeobject.js.map +2 -2
  69. package/dist/Runtime/types/project-data.d.ts +31 -8
  70. package/dist/Runtime/variablescontainer.js +1 -1
  71. package/dist/Runtime/variablescontainer.js.map +2 -2
  72. package/dist/lib/libGD.cjs +1 -1
  73. package/dist/lib/libGD.wasm +0 -0
  74. package/gd.d.ts +77 -47
  75. package/package.json +2 -2
  76. package/dist/lib/libGD.d.cts +0 -5
  77. package/dist/loaders.d.cts +0 -2
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../GDevelop/GDJS/Runtime/SpriteAnimator.ts"],
4
- "sourcesContent": ["namespace gdjs {\n /** Represents a point in a coordinate system. */\n export type SpritePoint = {\n /** X position of the point. */\n x: float;\n /** Y position of the point. */\n y: float;\n };\n\n /** Represents a custom point in a frame. */\n export type SpriteCustomPointData = {\n /** Name of the point. */\n name: string;\n /** X position of the point. */\n x: float;\n /** Y position of the point. */\n y: float;\n };\n\n /** Represents the center point in a frame. */\n export type SpriteCenterPointData = {\n /** Name of the point. */\n name: string;\n /** Is the center automatically computed? */\n automatic: boolean;\n /** X position of the point. */\n x: float;\n /** Y position of the point. */\n y: float;\n };\n\n /** Represents a {@link gdjs.SpriteAnimationFrame}. */\n export type SpriteFrameData = {\n /** The resource name of the image used in this frame. */\n image: string;\n /** The points of the frame. */\n points: Array<SpriteCustomPointData>;\n /** The origin point. */\n originPoint: SpriteCustomPointData;\n /** The center of the frame. */\n centerPoint: SpriteCenterPointData;\n /** Is The collision mask custom? */\n hasCustomCollisionMask: boolean;\n /** The collision mask if it is custom. */\n customCollisionMask: Array<Array<SpritePoint>>;\n };\n\n /** Represents the data of a {@link gdjs.SpriteAnimationDirection}. */\n export type SpriteDirectionData = {\n /** Time between each frame, in seconds. */\n timeBetweenFrames: float;\n /** Is the animation looping? */\n looping: boolean;\n /** The list of frames. */\n sprites: Array<SpriteFrameData>;\n };\n\n /** Represents the data of a {@link gdjs.SpriteAnimation}. */\n export type SpriteAnimationData = {\n /** The name of the animation. */\n name: string;\n /** Does the animation use multiple {@link gdjs.SpriteAnimationDirection}? */\n useMultipleDirections: boolean;\n /** The list of {@link SpriteDirectionData} representing {@link gdjs.SpriteAnimationDirection} instances. */\n directions: Array<SpriteDirectionData>;\n };\n\n /** Represents all the information needed to synchronize the animations of an object. */\n export type SpriteAnimatorNetworkSyncData = {\n an: integer;\n di: integer;\n fr: integer;\n et: float;\n ss: float;\n pa: boolean;\n };\n\n /**\n * Abstraction from graphic libraries texture classes.\n */\n export interface AnimationFrameTextureManager<T> {\n getAnimationFrameTexture(imageName: string): T;\n getAnimationFrameWidth(pixiTexture: T);\n getAnimationFrameHeight(pixiTexture: T);\n }\n\n /**\n * A frame used by a SpriteAnimation in a {@link gdjs.SpriteRuntimeObject}.\n *\n * It contains the texture displayed as well as information like the points position\n * or the collision mask.\n */\n export class SpriteAnimationFrame<T> {\n image: string;\n\n //TODO: Rename in imageName, and do not store it in the object?\n texture: T;\n center: SpritePoint = { x: 0, y: 0 };\n origin: SpritePoint = { x: 0, y: 0 };\n hasCustomHitBoxes: boolean = false;\n customHitBoxes: gdjs.Polygon[] = [];\n points: Hashtable<SpritePoint>;\n\n /**\n * @param imageManager The game image manager\n * @param frameData The frame data used to initialize the frame\n */\n constructor(\n frameData: SpriteFrameData,\n textureManager: gdjs.AnimationFrameTextureManager<T>\n ) {\n this.image = frameData ? frameData.image : '';\n this.texture = textureManager.getAnimationFrameTexture(this.image);\n this.points = new Hashtable();\n this.reinitialize(frameData, textureManager);\n }\n\n /**\n * @param frameData The frame data used to initialize the frame\n * @param textureManager The game image manager\n */\n reinitialize(\n frameData: SpriteFrameData,\n textureManager: gdjs.AnimationFrameTextureManager<T>\n ) {\n this.points.clear();\n for (let i = 0, len = frameData.points.length; i < len; ++i) {\n const ptData = frameData.points[i];\n const point = { x: ptData.x, y: ptData.y };\n this.points.put(ptData.name, point);\n }\n const origin = frameData.originPoint;\n this.origin.x = origin.x;\n this.origin.y = origin.y;\n const center = frameData.centerPoint;\n if (center.automatic !== true) {\n this.center.x = center.x;\n this.center.y = center.y;\n } else {\n this.center.x = textureManager.getAnimationFrameWidth(this.texture) / 2;\n this.center.y =\n textureManager.getAnimationFrameHeight(this.texture) / 2;\n }\n\n //Load the custom collision mask, if any:\n if (frameData.hasCustomCollisionMask) {\n this.hasCustomHitBoxes = true;\n let i = 0;\n for (let len = frameData.customCollisionMask.length; i < len; ++i) {\n const polygonData: SpritePoint[] = frameData.customCollisionMask[i];\n\n //Add a polygon, if necessary (Avoid recreating a polygon if it already exists).\n if (i >= this.customHitBoxes.length) {\n this.customHitBoxes.push(new gdjs.Polygon());\n }\n let j = 0;\n for (const len2 = polygonData.length; j < len2; ++j) {\n const pointData: SpritePoint = polygonData[j];\n\n //Add a point, if necessary (Avoid recreating a point if it already exists).\n if (j >= this.customHitBoxes[i].vertices.length) {\n this.customHitBoxes[i].vertices.push([0, 0]);\n }\n this.customHitBoxes[i].vertices[j][0] = pointData.x;\n this.customHitBoxes[i].vertices[j][1] = pointData.y;\n }\n this.customHitBoxes[i].vertices.length = j;\n }\n this.customHitBoxes.length = i;\n } else {\n this.customHitBoxes.length = 0;\n }\n }\n\n /**\n * Get a point of the frame.<br>\n * If the point does not exist, the origin is returned.\n * @param name The point's name\n * @return The requested point. If it doesn't exists returns the origin point.\n */\n getPoint(name: string): SpritePoint {\n if (name === 'Centre' || name === 'Center') {\n return this.center;\n } else {\n if (name === 'Origin') {\n return this.origin;\n }\n }\n return this.points.containsKey(name)\n ? this.points.get(name)\n : this.origin;\n }\n }\n\n /**\n * Represents a direction of an animation of a {@link gdjs.SpriteRuntimeObject}.\n */\n export class SpriteAnimationDirection<T> {\n timeBetweenFrames: float;\n loop: boolean;\n frames: SpriteAnimationFrame<T>[] = [];\n\n /**\n * @param imageManager The game image manager\n * @param directionData The direction data used to initialize the direction\n */\n constructor(\n directionData: SpriteDirectionData,\n textureManager: gdjs.AnimationFrameTextureManager<T>\n ) {\n this.timeBetweenFrames = directionData\n ? directionData.timeBetweenFrames\n : 1.0;\n this.loop = !!directionData.looping;\n this.reinitialize(directionData, textureManager);\n }\n\n /**\n * @param directionData The direction data used to initialize the direction\n * @param textureManager The game image manager\n */\n reinitialize(\n directionData: SpriteDirectionData,\n textureManager: gdjs.AnimationFrameTextureManager<T>\n ) {\n this.timeBetweenFrames = directionData\n ? directionData.timeBetweenFrames\n : 1.0;\n this.loop = !!directionData.looping;\n let i = 0;\n for (const len = directionData.sprites.length; i < len; ++i) {\n const frameData = directionData.sprites[i];\n if (i < this.frames.length) {\n this.frames[i].reinitialize(frameData, textureManager);\n } else {\n this.frames.push(\n new gdjs.SpriteAnimationFrame<T>(frameData, textureManager)\n );\n }\n }\n this.frames.length = i;\n }\n }\n\n /**\n * Represents an animation of a {@link SpriteRuntimeObject}.\n */\n export class SpriteAnimation<T> {\n hasMultipleDirections: boolean;\n name: string;\n directions: gdjs.SpriteAnimationDirection<T>[] = [];\n\n /**\n * @param animData The animation data used to initialize the animation\n * @param textureManager The game image manager\n */\n constructor(\n animData: SpriteAnimationData,\n textureManager: gdjs.AnimationFrameTextureManager<T>\n ) {\n this.hasMultipleDirections = !!animData.useMultipleDirections;\n this.name = animData.name || '';\n this.reinitialize(animData, textureManager);\n }\n\n /**\n * @param animData The animation data used to initialize the animation\n * @param textureManager The game image manager\n */\n reinitialize(\n animData: SpriteAnimationData,\n textureManager: gdjs.AnimationFrameTextureManager<T>\n ) {\n this.hasMultipleDirections = !!animData.useMultipleDirections;\n this.name = animData.name || '';\n let i = 0;\n for (const len = animData.directions.length; i < len; ++i) {\n const directionData = animData.directions[i];\n if (i < this.directions.length) {\n this.directions[i].reinitialize(directionData, textureManager);\n } else {\n this.directions.push(\n new gdjs.SpriteAnimationDirection(directionData, textureManager)\n );\n }\n }\n // Make sure to delete already existing directions which are not used anymore.\n this.directions.length = i;\n }\n }\n\n /**\n * Image-base animation model.\n */\n export class SpriteAnimator<T> implements gdjs.Animatable {\n _animations: gdjs.SpriteAnimation<T>[] = [];\n _textureManager: gdjs.AnimationFrameTextureManager<T>;\n /**\n * Reference to the current SpriteAnimationFrame that is displayed.\n * Can be null, so ensure that this case is handled properly.\n */\n private _animationFrame: gdjs.SpriteAnimationFrame<T> | null = null;\n private _animationFrameDirty: boolean = true;\n\n private _currentAnimation: integer = 0;\n private _currentDirection: integer = 0;\n private _currentFrameIndex: integer = 0;\n /** In seconds */\n private _animationElapsedTime: float = 0;\n private _animationSpeedScale: float = 1;\n private _animationPaused: boolean = false;\n private _onFrameChange: (() => void) | null = null;\n\n /**\n * @param frameData The frame data used to initialize the frame\n * @param textureManager The game image manager\n */\n constructor(\n animations: Array<SpriteAnimationData>,\n textureManager: gdjs.AnimationFrameTextureManager<T>\n ) {\n this._textureManager = textureManager;\n for (let i = 0, len = animations.length; i < len; ++i) {\n this._animations.push(\n new gdjs.SpriteAnimation(animations[i], textureManager)\n );\n }\n }\n\n invalidateFrame() {\n this._animationFrameDirty = true;\n if (this._onFrameChange) {\n this._onFrameChange();\n }\n }\n\n reinitialize(animations: Array<SpriteAnimationData>) {\n this._currentAnimation = 0;\n this._currentDirection = 0;\n this._currentFrameIndex = 0;\n this._animationElapsedTime = 0;\n this._animationSpeedScale = 1;\n this._animationPaused = false;\n\n let i = 0;\n for (const len = animations.length; i < len; ++i) {\n const animData = animations[i];\n if (i < this._animations.length) {\n this._animations[i].reinitialize(animData, this._textureManager);\n } else {\n this._animations.push(\n new gdjs.SpriteAnimation(animData, this._textureManager)\n );\n }\n }\n this._animations.length = i;\n\n // Make sure to delete already existing animations which are not used anymore.\n this._animationFrame = null;\n this.invalidateFrame();\n }\n\n updateFromObjectData(\n oldAnimations: Array<SpriteAnimationData>,\n newAnimations: Array<SpriteAnimationData>\n ): boolean {\n let i = 0;\n for (const len = newAnimations.length; i < len; ++i) {\n const animData = newAnimations[i];\n if (i < this._animations.length) {\n this._animations[i].reinitialize(animData, this._textureManager);\n } else {\n this._animations.push(\n new gdjs.SpriteAnimation(animData, this._textureManager)\n );\n }\n }\n this._animations.length = i;\n\n // Make sure to delete already existing animations which are not used anymore.\n this.invalidateFrame();\n const animationFrame = this.getCurrentFrame();\n if (!animationFrame) {\n this.setAnimationIndex(0);\n }\n return true;\n }\n\n getNetworkSyncData(): SpriteAnimatorNetworkSyncData {\n return {\n an: this._currentAnimation,\n di: this._currentDirection,\n fr: this._currentFrameIndex,\n et: this._animationElapsedTime,\n ss: this._animationSpeedScale,\n pa: this._animationPaused,\n };\n }\n\n updateFromNetworkSyncData(networkSyncData: SpriteAnimatorNetworkSyncData) {\n this._currentAnimation = networkSyncData.an;\n this._currentDirection = networkSyncData.di;\n this._currentFrameIndex = networkSyncData.fr;\n this._animationElapsedTime = networkSyncData.et;\n this._animationSpeedScale = networkSyncData.ss;\n this._animationPaused = networkSyncData.pa;\n this.invalidateFrame();\n }\n\n /**\n * @returns Returns the current frame or null if the current animation doesn't have any frame.\n */\n getCurrentFrame(): gdjs.SpriteAnimationFrame<T> | null {\n if (!this._animationFrameDirty) {\n return this._animationFrame;\n }\n this._animationFrameDirty = false;\n if (\n this._currentAnimation < this._animations.length &&\n this._currentDirection <\n this._animations[this._currentAnimation].directions.length\n ) {\n const direction = this._animations[this._currentAnimation].directions[\n this._currentDirection\n ];\n if (this._currentFrameIndex < direction.frames.length) {\n this._animationFrame = direction.frames[this._currentFrameIndex];\n return this._animationFrame;\n }\n }\n\n //Invalid animation/direction/frame:\n this._animationFrame = null;\n return this._animationFrame;\n }\n\n /**\n * Update the current frame of the object according to the elapsed time on the scene.\n * @param timeDelta in seconds\n */\n step(timeDelta: float): boolean {\n if (\n this._currentAnimation >= this._animations.length ||\n this._currentDirection >=\n this._animations[this._currentAnimation].directions.length\n ) {\n return false;\n }\n const direction = this._animations[this._currentAnimation].directions[\n this._currentDirection\n ];\n const animationDuration = this.getAnimationDuration();\n if (\n !this._animationPaused &&\n (direction.loop || this._animationElapsedTime !== animationDuration) &&\n direction.timeBetweenFrames\n ) {\n const animationElapsedTime =\n this._animationElapsedTime + timeDelta * this._animationSpeedScale;\n return this.setAnimationElapsedTime(\n direction.loop\n ? gdjs.evtTools.common.mod(animationElapsedTime, animationDuration)\n : gdjs.evtTools.common.clamp(\n animationElapsedTime,\n 0,\n animationDuration\n )\n );\n }\n return false;\n }\n\n /**\n * Register a listener to frame changes.\n *\n * It's useful for custom objects as they don't drive this class themselves.\n *\n * @param callback Called each time {@link getCurrentFrame} changes.\n */\n setOnFrameChangeCallback(callback: () => void): void {\n this._onFrameChange = callback;\n }\n\n getAnimationIndex(): integer {\n return this._currentAnimation;\n }\n\n setAnimationIndex(newAnimation: integer): boolean {\n // Truncate the index.\n newAnimation = newAnimation | 0;\n if (\n newAnimation < this._animations.length &&\n this._currentAnimation !== newAnimation &&\n newAnimation >= 0\n ) {\n this._currentAnimation = newAnimation;\n this._currentFrameIndex = 0;\n this._animationElapsedTime = 0;\n this.invalidateFrame();\n return true;\n }\n return false;\n }\n\n getAnimationName(): string {\n if (this._currentAnimation >= this._animations.length) {\n return '';\n }\n return this._animations[this._currentAnimation].name;\n }\n\n setAnimationName(newAnimationName: string): boolean {\n if (!newAnimationName) {\n return false;\n }\n for (let i = 0; i < this._animations.length; ++i) {\n if (this._animations[i].name === newAnimationName) {\n this.setAnimationIndex(i);\n return true;\n }\n }\n return false;\n }\n\n hasAnimationEnded(): boolean {\n if (\n this._currentAnimation >= this._animations.length ||\n this._currentDirection >=\n this._animations[this._currentAnimation].directions.length\n ) {\n return true;\n }\n const direction = this._animations[this._currentAnimation].directions[\n this._currentDirection\n ];\n if (direction.loop) {\n return false;\n }\n return (\n this._currentFrameIndex === direction.frames.length - 1 &&\n this._animationElapsedTime ===\n direction.frames.length * direction.timeBetweenFrames\n );\n }\n\n isAnimationPaused() {\n return this._animationPaused;\n }\n\n pauseAnimation() {\n this._animationPaused = true;\n }\n\n resumeAnimation() {\n this._animationPaused = false;\n }\n\n getAnimationSpeedScale() {\n return this._animationSpeedScale;\n }\n\n setAnimationSpeedScale(ratio: float): void {\n this._animationSpeedScale = ratio;\n }\n\n /**\n * Change the current frame displayed by the animation\n * @param newFrameIndex The index of the frame to be displayed\n */\n setAnimationFrameIndex(newFrameIndex: integer): boolean {\n if (\n this._currentAnimation >= this._animations.length ||\n this._currentDirection >=\n this._animations[this._currentAnimation].directions.length\n ) {\n return false;\n }\n const direction = this._animations[this._currentAnimation].directions[\n this._currentDirection\n ];\n if (\n newFrameIndex >= 0 &&\n newFrameIndex < direction.frames.length &&\n newFrameIndex !== this._currentFrameIndex\n ) {\n this._currentFrameIndex = newFrameIndex;\n this._animationElapsedTime =\n newFrameIndex * direction.timeBetweenFrames;\n this.invalidateFrame();\n return true;\n }\n return false;\n }\n\n /**\n * Get the index of the current frame displayed by the animation\n * @return newFrame The index of the frame being displayed\n */\n getAnimationFrameIndex(): integer {\n return this._currentFrameIndex;\n }\n\n getAnimationElapsedTime(): float {\n return this._animationElapsedTime;\n }\n\n setAnimationElapsedTime(time: float): boolean {\n const direction = this._animations[this._currentAnimation].directions[\n this._currentDirection\n ];\n this._animationElapsedTime = gdjs.evtTools.common.clamp(\n time,\n 0,\n this.getAnimationDuration()\n );\n\n const oldFrame = this._currentFrameIndex;\n this._currentFrameIndex = Math.min(\n Math.floor(this._animationElapsedTime / direction.timeBetweenFrames),\n direction.frames.length - 1\n );\n if (oldFrame !== this._currentFrameIndex) {\n this.invalidateFrame();\n return true;\n }\n return false;\n }\n\n getAnimationDuration(): float {\n const direction = this._animations[this._currentAnimation].directions[\n this._currentDirection\n ];\n return direction.frames.length * direction.timeBetweenFrames;\n }\n\n getAnimationFrameCount(): integer {\n if (this._currentAnimation >= this._animations.length) {\n return 0;\n }\n const currentAnimation = this._animations[this._currentAnimation];\n if (this._currentDirection >= currentAnimation.directions.length) {\n return 0;\n }\n return currentAnimation.directions[this._currentDirection].frames.length;\n }\n\n /**\n * Change the angle (or direction index) of the object\n * @param The new angle (or direction index) to be applied\n * @deprecated\n */\n setDirectionOrAngle(oldValue: float, newValue: float): float | null {\n if (this._currentAnimation >= this._animations.length) {\n return null;\n }\n const anim = this._animations[this._currentAnimation];\n if (!anim.hasMultipleDirections) {\n return oldValue === newValue ? null : newValue;\n } else {\n newValue = newValue | 0;\n if (\n newValue === this._currentDirection ||\n newValue >= anim.directions.length ||\n anim.directions[newValue].frames.length === 0\n ) {\n return null;\n }\n this._currentDirection = newValue;\n this._currentFrameIndex = 0;\n this._animationElapsedTime = 0;\n this.invalidateFrame();\n return 0;\n }\n }\n\n /**\n * @deprecated\n */\n getDirectionOrAngle(angle: float): float {\n if (this._currentAnimation >= this._animations.length) {\n return 0;\n }\n if (!this._animations[this._currentAnimation].hasMultipleDirections) {\n return angle;\n } else {\n return this._currentDirection;\n }\n }\n\n /**\n * @deprecated\n */\n getAngle(angle: float): float {\n if (this._currentAnimation >= this._animations.length) {\n return 0;\n }\n if (!this._animations[this._currentAnimation].hasMultipleDirections) {\n return angle;\n } else {\n return this._currentDirection * 45;\n }\n }\n\n /**\n * @deprecated\n */\n setAngle(oldAngle: float, angle: float): float | null {\n if (this._currentAnimation >= this._animations.length) {\n return null;\n }\n if (!this._animations[this._currentAnimation].hasMultipleDirections) {\n if (oldAngle === angle) {\n return null;\n }\n return angle;\n } else {\n angle = angle % 360;\n if (angle < 0) {\n angle += 360;\n }\n return this.setDirectionOrAngle(oldAngle, Math.round(angle / 45) % 8);\n }\n }\n\n /**\n * @deprecated\n * Return true if animation has ended.\n * Prefer using {@link hasAnimationEnded}. This method returns true as soon as\n * the animation enters the last frame, not at the end of the last frame.\n */\n hasAnimationEndedLegacy(): boolean {\n if (\n this._currentAnimation >= this._animations.length ||\n this._currentDirection >=\n this._animations[this._currentAnimation].directions.length\n ) {\n return true;\n }\n const direction = this._animations[this._currentAnimation].directions[\n this._currentDirection\n ];\n if (direction.loop) {\n return false;\n }\n return this._currentFrameIndex === direction.frames.length - 1;\n }\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["namespace gdjs {\n /** Represents a point in a coordinate system. */\n export type SpritePoint = {\n /** X position of the point. */\n x: float;\n /** Y position of the point. */\n y: float;\n };\n\n /** Represents a custom point in a frame. */\n export type SpriteCustomPointData = {\n /** Name of the point. */\n name: string;\n /** X position of the point. */\n x: float;\n /** Y position of the point. */\n y: float;\n };\n\n /** Represents the center point in a frame. */\n export type SpriteCenterPointData = {\n /** Name of the point. */\n name: string;\n /** Is the center automatically computed? */\n automatic: boolean;\n /** X position of the point. */\n x: float;\n /** Y position of the point. */\n y: float;\n };\n\n /** Represents a {@link gdjs.SpriteAnimationFrame}. */\n export type SpriteFrameData = {\n /** The resource name of the image used in this frame. */\n image: string;\n /** The points of the frame. */\n points: Array<SpriteCustomPointData>;\n /** The origin point. */\n originPoint: SpriteCustomPointData;\n /** The center of the frame. */\n centerPoint: SpriteCenterPointData;\n /** Is The collision mask custom? */\n hasCustomCollisionMask: boolean;\n /** The collision mask if it is custom. */\n customCollisionMask: Array<Array<SpritePoint>>;\n };\n\n /** Represents the data of a {@link gdjs.SpriteAnimationDirection}. */\n export type SpriteDirectionData = {\n /** Time between each frame, in seconds. */\n timeBetweenFrames: float;\n /** Is the animation looping? */\n looping: boolean;\n /** The list of frames. */\n sprites: Array<SpriteFrameData>;\n };\n\n /** Represents the data of a {@link gdjs.SpriteAnimation}. */\n export type SpriteAnimationData = {\n /** The name of the animation. */\n name: string;\n /** Does the animation use multiple {@link gdjs.SpriteAnimationDirection}? */\n useMultipleDirections: boolean;\n /** The list of {@link SpriteDirectionData} representing {@link gdjs.SpriteAnimationDirection} instances. */\n directions: Array<SpriteDirectionData>;\n };\n\n /** Represents all the information needed to synchronize the animations of an object. */\n export type SpriteAnimatorNetworkSyncData = {\n an: integer;\n di: integer;\n fr: integer;\n et: float;\n ss: float;\n pa: boolean;\n };\n\n /**\n * Abstraction from graphic libraries texture classes.\n */\n export interface AnimationFrameTextureManager<T> {\n getAnimationFrameTexture(imageName: string): T;\n getAnimationFrameWidth(pixiTexture: T);\n getAnimationFrameHeight(pixiTexture: T);\n }\n\n /**\n * A frame used by a SpriteAnimation in a {@link gdjs.SpriteRuntimeObject}.\n *\n * It contains the texture displayed as well as information like the points position\n * or the collision mask.\n */\n export class SpriteAnimationFrame<T> {\n image: string;\n\n //TODO: Rename in imageName, and do not store it in the object?\n texture: T;\n center: SpritePoint = { x: 0, y: 0 };\n origin: SpritePoint = { x: 0, y: 0 };\n hasCustomHitBoxes: boolean = false;\n customHitBoxes: gdjs.Polygon[] = [];\n points: Hashtable<SpritePoint>;\n\n /**\n * @param imageManager The game image manager\n * @param frameData The frame data used to initialize the frame\n */\n constructor(\n frameData: SpriteFrameData,\n textureManager: gdjs.AnimationFrameTextureManager<T>\n ) {\n this.image = frameData ? frameData.image : '';\n this.texture = textureManager.getAnimationFrameTexture(this.image);\n this.points = new Hashtable();\n this.reinitialize(frameData, textureManager);\n }\n\n /**\n * @param frameData The frame data used to initialize the frame\n * @param textureManager The game image manager\n */\n reinitialize(\n frameData: SpriteFrameData,\n textureManager: gdjs.AnimationFrameTextureManager<T>\n ) {\n this.image = frameData.image;\n this.texture = textureManager.getAnimationFrameTexture(this.image);\n\n this.points.clear();\n for (let i = 0, len = frameData.points.length; i < len; ++i) {\n const ptData = frameData.points[i];\n const point = { x: ptData.x, y: ptData.y };\n this.points.put(ptData.name, point);\n }\n const origin = frameData.originPoint;\n this.origin.x = origin.x;\n this.origin.y = origin.y;\n const center = frameData.centerPoint;\n if (center.automatic !== true) {\n this.center.x = center.x;\n this.center.y = center.y;\n } else {\n this.center.x = textureManager.getAnimationFrameWidth(this.texture) / 2;\n this.center.y =\n textureManager.getAnimationFrameHeight(this.texture) / 2;\n }\n\n //Load the custom collision mask, if any:\n if (frameData.hasCustomCollisionMask) {\n this.hasCustomHitBoxes = true;\n let i = 0;\n for (let len = frameData.customCollisionMask.length; i < len; ++i) {\n const polygonData: SpritePoint[] = frameData.customCollisionMask[i];\n\n //Add a polygon, if necessary (Avoid recreating a polygon if it already exists).\n if (i >= this.customHitBoxes.length) {\n this.customHitBoxes.push(new gdjs.Polygon());\n }\n let j = 0;\n for (const len2 = polygonData.length; j < len2; ++j) {\n const pointData: SpritePoint = polygonData[j];\n\n //Add a point, if necessary (Avoid recreating a point if it already exists).\n if (j >= this.customHitBoxes[i].vertices.length) {\n this.customHitBoxes[i].vertices.push([0, 0]);\n }\n this.customHitBoxes[i].vertices[j][0] = pointData.x;\n this.customHitBoxes[i].vertices[j][1] = pointData.y;\n }\n this.customHitBoxes[i].vertices.length = j;\n }\n this.customHitBoxes.length = i;\n } else {\n this.customHitBoxes.length = 0;\n }\n }\n\n /**\n * Get a point of the frame.<br>\n * If the point does not exist, the origin is returned.\n * @param name The point's name\n * @return The requested point. If it doesn't exists returns the origin point.\n */\n getPoint(name: string): SpritePoint {\n if (name === 'Centre' || name === 'Center') {\n return this.center;\n } else {\n if (name === 'Origin') {\n return this.origin;\n }\n }\n return this.points.containsKey(name)\n ? this.points.get(name)\n : this.origin;\n }\n }\n\n /**\n * Represents a direction of an animation of a {@link gdjs.SpriteRuntimeObject}.\n */\n export class SpriteAnimationDirection<T> {\n timeBetweenFrames: float;\n loop: boolean;\n frames: SpriteAnimationFrame<T>[] = [];\n\n /**\n * @param imageManager The game image manager\n * @param directionData The direction data used to initialize the direction\n */\n constructor(\n directionData: SpriteDirectionData,\n textureManager: gdjs.AnimationFrameTextureManager<T>\n ) {\n this.timeBetweenFrames = directionData\n ? directionData.timeBetweenFrames\n : 1.0;\n this.loop = !!directionData.looping;\n this.reinitialize(directionData, textureManager);\n }\n\n /**\n * @param directionData The direction data used to initialize the direction\n * @param textureManager The game image manager\n */\n reinitialize(\n directionData: SpriteDirectionData,\n textureManager: gdjs.AnimationFrameTextureManager<T>\n ) {\n this.timeBetweenFrames = directionData\n ? directionData.timeBetweenFrames\n : 1.0;\n this.loop = !!directionData.looping;\n let i = 0;\n for (const len = directionData.sprites.length; i < len; ++i) {\n const frameData = directionData.sprites[i];\n if (i < this.frames.length) {\n this.frames[i].reinitialize(frameData, textureManager);\n } else {\n this.frames.push(\n new gdjs.SpriteAnimationFrame<T>(frameData, textureManager)\n );\n }\n }\n this.frames.length = i;\n }\n }\n\n /**\n * Represents an animation of a {@link SpriteRuntimeObject}.\n */\n export class SpriteAnimation<T> {\n hasMultipleDirections: boolean;\n name: string;\n directions: gdjs.SpriteAnimationDirection<T>[] = [];\n\n /**\n * @param animData The animation data used to initialize the animation\n * @param textureManager The game image manager\n */\n constructor(\n animData: SpriteAnimationData,\n textureManager: gdjs.AnimationFrameTextureManager<T>\n ) {\n this.hasMultipleDirections = !!animData.useMultipleDirections;\n this.name = animData.name || '';\n this.reinitialize(animData, textureManager);\n }\n\n /**\n * @param animData The animation data used to initialize the animation\n * @param textureManager The game image manager\n */\n reinitialize(\n animData: SpriteAnimationData,\n textureManager: gdjs.AnimationFrameTextureManager<T>\n ) {\n this.hasMultipleDirections = !!animData.useMultipleDirections;\n this.name = animData.name || '';\n let i = 0;\n for (const len = animData.directions.length; i < len; ++i) {\n const directionData = animData.directions[i];\n if (i < this.directions.length) {\n this.directions[i].reinitialize(directionData, textureManager);\n } else {\n this.directions.push(\n new gdjs.SpriteAnimationDirection(directionData, textureManager)\n );\n }\n }\n // Make sure to delete already existing directions which are not used anymore.\n this.directions.length = i;\n }\n }\n\n /**\n * Image-base animation model.\n */\n export class SpriteAnimator<T> implements gdjs.Animatable {\n _animations: gdjs.SpriteAnimation<T>[] = [];\n _textureManager: gdjs.AnimationFrameTextureManager<T>;\n /**\n * Reference to the current SpriteAnimationFrame that is displayed.\n * Can be null, so ensure that this case is handled properly.\n */\n private _animationFrame: gdjs.SpriteAnimationFrame<T> | null = null;\n private _animationFrameDirty: boolean = true;\n\n private _currentAnimation: integer = 0;\n private _currentDirection: integer = 0;\n private _currentFrameIndex: integer = 0;\n /** In seconds */\n private _animationElapsedTime: float = 0;\n private _animationSpeedScale: float = 1;\n private _animationPaused: boolean = false;\n private _onFrameChange: (() => void) | null = null;\n\n /**\n * @param frameData The frame data used to initialize the frame\n * @param textureManager The game image manager\n */\n constructor(\n animations: Array<SpriteAnimationData>,\n textureManager: gdjs.AnimationFrameTextureManager<T>\n ) {\n this._textureManager = textureManager;\n for (let i = 0, len = animations.length; i < len; ++i) {\n this._animations.push(\n new gdjs.SpriteAnimation(animations[i], textureManager)\n );\n }\n }\n\n invalidateFrame() {\n this._animationFrameDirty = true;\n if (this._onFrameChange) {\n this._onFrameChange();\n }\n }\n\n reinitialize(animations: Array<SpriteAnimationData>) {\n this._currentAnimation = 0;\n this._currentDirection = 0;\n this._currentFrameIndex = 0;\n this._animationElapsedTime = 0;\n this._animationSpeedScale = 1;\n this._animationPaused = false;\n\n let i = 0;\n for (const len = animations.length; i < len; ++i) {\n const animData = animations[i];\n if (i < this._animations.length) {\n this._animations[i].reinitialize(animData, this._textureManager);\n } else {\n this._animations.push(\n new gdjs.SpriteAnimation(animData, this._textureManager)\n );\n }\n }\n this._animations.length = i;\n\n // Make sure to delete already existing animations which are not used anymore.\n this._animationFrame = null;\n this.invalidateFrame();\n }\n\n updateFromObjectData(\n oldAnimations: Array<SpriteAnimationData>,\n newAnimations: Array<SpriteAnimationData>\n ): boolean {\n let i = 0;\n for (const len = newAnimations.length; i < len; ++i) {\n const animData = newAnimations[i];\n if (i < this._animations.length) {\n this._animations[i].reinitialize(animData, this._textureManager);\n } else {\n this._animations.push(\n new gdjs.SpriteAnimation(animData, this._textureManager)\n );\n }\n }\n this._animations.length = i;\n\n // Make sure to delete already existing animations which are not used anymore.\n this.invalidateFrame();\n const animationFrame = this.getCurrentFrame();\n if (!animationFrame) {\n this.setAnimationIndex(0);\n }\n return true;\n }\n\n getNetworkSyncData(): SpriteAnimatorNetworkSyncData {\n return {\n an: this._currentAnimation,\n di: this._currentDirection,\n fr: this._currentFrameIndex,\n et: this._animationElapsedTime,\n ss: this._animationSpeedScale,\n pa: this._animationPaused,\n };\n }\n\n updateFromNetworkSyncData(networkSyncData: SpriteAnimatorNetworkSyncData) {\n this._currentAnimation = networkSyncData.an;\n this._currentDirection = networkSyncData.di;\n this._currentFrameIndex = networkSyncData.fr;\n this._animationElapsedTime = networkSyncData.et;\n this._animationSpeedScale = networkSyncData.ss;\n this._animationPaused = networkSyncData.pa;\n this.invalidateFrame();\n }\n\n /**\n * @returns Returns the current frame or null if the current animation doesn't have any frame.\n */\n getCurrentFrame(): gdjs.SpriteAnimationFrame<T> | null {\n if (!this._animationFrameDirty) {\n return this._animationFrame;\n }\n this._animationFrameDirty = false;\n if (\n this._currentAnimation < this._animations.length &&\n this._currentDirection <\n this._animations[this._currentAnimation].directions.length\n ) {\n const direction = this._animations[this._currentAnimation].directions[\n this._currentDirection\n ];\n if (this._currentFrameIndex < direction.frames.length) {\n this._animationFrame = direction.frames[this._currentFrameIndex];\n return this._animationFrame;\n }\n }\n\n //Invalid animation/direction/frame:\n this._animationFrame = null;\n return this._animationFrame;\n }\n\n /**\n * Update the current frame of the object according to the elapsed time on the scene.\n * @param timeDelta in seconds\n */\n step(timeDelta: float): boolean {\n if (\n this._currentAnimation >= this._animations.length ||\n this._currentDirection >=\n this._animations[this._currentAnimation].directions.length\n ) {\n return false;\n }\n const direction = this._animations[this._currentAnimation].directions[\n this._currentDirection\n ];\n const animationDuration = this.getAnimationDuration();\n if (\n !this._animationPaused &&\n (direction.loop || this._animationElapsedTime !== animationDuration) &&\n direction.timeBetweenFrames\n ) {\n const animationElapsedTime =\n this._animationElapsedTime + timeDelta * this._animationSpeedScale;\n return this.setAnimationElapsedTime(\n direction.loop\n ? gdjs.evtTools.common.mod(animationElapsedTime, animationDuration)\n : gdjs.evtTools.common.clamp(\n animationElapsedTime,\n 0,\n animationDuration\n )\n );\n }\n return false;\n }\n\n /**\n * Register a listener to frame changes.\n *\n * It's useful for custom objects as they don't drive this class themselves.\n *\n * @param callback Called each time {@link getCurrentFrame} changes.\n */\n setOnFrameChangeCallback(callback: () => void): void {\n this._onFrameChange = callback;\n }\n\n getAnimationIndex(): integer {\n return this._currentAnimation;\n }\n\n setAnimationIndex(newAnimation: integer): boolean {\n // Truncate the index.\n newAnimation = newAnimation | 0;\n if (\n newAnimation < this._animations.length &&\n this._currentAnimation !== newAnimation &&\n newAnimation >= 0\n ) {\n this._currentAnimation = newAnimation;\n this._currentFrameIndex = 0;\n this._animationElapsedTime = 0;\n this.invalidateFrame();\n return true;\n }\n return false;\n }\n\n getAnimationName(): string {\n if (this._currentAnimation >= this._animations.length) {\n return '';\n }\n return this._animations[this._currentAnimation].name;\n }\n\n setAnimationName(newAnimationName: string): boolean {\n if (!newAnimationName) {\n return false;\n }\n for (let i = 0; i < this._animations.length; ++i) {\n if (this._animations[i].name === newAnimationName) {\n this.setAnimationIndex(i);\n return true;\n }\n }\n return false;\n }\n\n hasAnimationEnded(): boolean {\n if (\n this._currentAnimation >= this._animations.length ||\n this._currentDirection >=\n this._animations[this._currentAnimation].directions.length\n ) {\n return true;\n }\n const direction = this._animations[this._currentAnimation].directions[\n this._currentDirection\n ];\n if (direction.loop) {\n return false;\n }\n return (\n this._currentFrameIndex === direction.frames.length - 1 &&\n this._animationElapsedTime ===\n direction.frames.length * direction.timeBetweenFrames\n );\n }\n\n isAnimationPaused() {\n return this._animationPaused;\n }\n\n pauseAnimation() {\n this._animationPaused = true;\n }\n\n resumeAnimation() {\n this._animationPaused = false;\n }\n\n getAnimationSpeedScale() {\n return this._animationSpeedScale;\n }\n\n setAnimationSpeedScale(ratio: float): void {\n this._animationSpeedScale = ratio;\n }\n\n /**\n * Change the current frame displayed by the animation\n * @param newFrameIndex The index of the frame to be displayed\n */\n setAnimationFrameIndex(newFrameIndex: integer): boolean {\n if (\n this._currentAnimation >= this._animations.length ||\n this._currentDirection >=\n this._animations[this._currentAnimation].directions.length\n ) {\n return false;\n }\n const direction = this._animations[this._currentAnimation].directions[\n this._currentDirection\n ];\n if (\n newFrameIndex >= 0 &&\n newFrameIndex < direction.frames.length &&\n newFrameIndex !== this._currentFrameIndex\n ) {\n this._currentFrameIndex = newFrameIndex;\n this._animationElapsedTime =\n newFrameIndex * direction.timeBetweenFrames;\n this.invalidateFrame();\n return true;\n }\n return false;\n }\n\n /**\n * Get the index of the current frame displayed by the animation\n * @return newFrame The index of the frame being displayed\n */\n getAnimationFrameIndex(): integer {\n return this._currentFrameIndex;\n }\n\n getAnimationElapsedTime(): float {\n return this._animationElapsedTime;\n }\n\n setAnimationElapsedTime(time: float): boolean {\n const direction = this._animations[this._currentAnimation].directions[\n this._currentDirection\n ];\n this._animationElapsedTime = gdjs.evtTools.common.clamp(\n time,\n 0,\n this.getAnimationDuration()\n );\n\n const oldFrame = this._currentFrameIndex;\n this._currentFrameIndex = Math.min(\n Math.floor(this._animationElapsedTime / direction.timeBetweenFrames),\n direction.frames.length - 1\n );\n if (oldFrame !== this._currentFrameIndex) {\n this.invalidateFrame();\n return true;\n }\n return false;\n }\n\n getAnimationDuration(): float {\n const direction = this._animations[this._currentAnimation].directions[\n this._currentDirection\n ];\n return direction.frames.length * direction.timeBetweenFrames;\n }\n\n getAnimationFrameCount(): integer {\n if (this._currentAnimation >= this._animations.length) {\n return 0;\n }\n const currentAnimation = this._animations[this._currentAnimation];\n if (this._currentDirection >= currentAnimation.directions.length) {\n return 0;\n }\n return currentAnimation.directions[this._currentDirection].frames.length;\n }\n\n /**\n * Change the angle (or direction index) of the object\n * @param The new angle (or direction index) to be applied\n * @deprecated\n */\n setDirectionOrAngle(oldValue: float, newValue: float): float | null {\n if (this._currentAnimation >= this._animations.length) {\n return null;\n }\n const anim = this._animations[this._currentAnimation];\n if (!anim.hasMultipleDirections) {\n return oldValue === newValue ? null : newValue;\n } else {\n newValue = newValue | 0;\n if (\n newValue === this._currentDirection ||\n newValue >= anim.directions.length ||\n anim.directions[newValue].frames.length === 0\n ) {\n return null;\n }\n this._currentDirection = newValue;\n this._currentFrameIndex = 0;\n this._animationElapsedTime = 0;\n this.invalidateFrame();\n return 0;\n }\n }\n\n /**\n * @deprecated\n */\n getDirectionOrAngle(angle: float): float {\n if (this._currentAnimation >= this._animations.length) {\n return 0;\n }\n if (!this._animations[this._currentAnimation].hasMultipleDirections) {\n return angle;\n } else {\n return this._currentDirection;\n }\n }\n\n /**\n * @deprecated\n */\n getAngle(angle: float): float {\n if (this._currentAnimation >= this._animations.length) {\n return 0;\n }\n if (!this._animations[this._currentAnimation].hasMultipleDirections) {\n return angle;\n } else {\n return this._currentDirection * 45;\n }\n }\n\n /**\n * @deprecated\n */\n setAngle(oldAngle: float, angle: float): float | null {\n if (this._currentAnimation >= this._animations.length) {\n return null;\n }\n if (!this._animations[this._currentAnimation].hasMultipleDirections) {\n if (oldAngle === angle) {\n return null;\n }\n return angle;\n } else {\n angle = angle % 360;\n if (angle < 0) {\n angle += 360;\n }\n return this.setDirectionOrAngle(oldAngle, Math.round(angle / 45) % 8);\n }\n }\n\n /**\n * @deprecated\n * Return true if animation has ended.\n * Prefer using {@link hasAnimationEnded}. This method returns true as soon as\n * the animation enters the last frame, not at the end of the last frame.\n */\n hasAnimationEndedLegacy(): boolean {\n if (\n this._currentAnimation >= this._animations.length ||\n this._currentDirection >=\n this._animations[this._currentAnimation].directions.length\n ) {\n return true;\n }\n const direction = this._animations[this._currentAnimation].directions[\n this._currentDirection\n ];\n if (direction.loop) {\n return false;\n }\n return this._currentFrameIndex === direction.frames.length - 1;\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,2 +1,2 @@
1
- var gdjs;(function(p){function r(t,e,...a){const o=document.createElement(t);return Object.keys(e).forEach(i=>{if(i==="style")for(const[s,c]of Object.entries(e.style))o.style[s]=c;else i==="onClick"?o.addEventListener("click",e[i]):o.setAttribute(i,""+e[i])}),o.append(...a),o}const n={errorContainer:{padding:"15px",backgroundColor:"#a70000cc",borderRadius:"8px",position:"absolute",bottom:"5px",left:"5px",right:"5px",color:"white",display:"flex",flexDirection:"column",pointerEvents:"all"},errorTitle:{fontFamily:"system-ui",fontSize:"20px",marginTop:"5px",marginBottom:"5px",userSelect:"all"},errorMessage:{fontFamily:"system-ui",fontSize:"14px",userSelect:"all"},stacktrace:{fontSize:"14px",fontFamily:"monospace",whiteSpace:"pre",maxHeight:"510px",overflow:"auto",userSelect:"all"},closeButton:{padding:"3px",width:"20px",fontSize:"18px",position:"absolute",right:"5px",top:"5px",color:"white",border:"1px solid white",borderRadius:"6px",backgroundColor:"transparent"}},l=t=>!t||!t.stack?!1:t.stack.includes("GDJSInlineCode");class u{constructor(e){this._uncaughtException=null;this._uncaughtExceptionElement=null;this._runtimeGame=e}setUncaughtException(e){this._uncaughtException&&!!e||(this._uncaughtException=e,this.render())}render(){const e=this._runtimeGame.getRenderer().getDomElementContainer();if(!!e&&(this._uncaughtExceptionElement&&(e.removeChild(this._uncaughtExceptionElement),this._uncaughtExceptionElement=null),this._uncaughtException)){const a=l(this._uncaughtException);this._uncaughtExceptionElement=r("div",{style:n.errorContainer},r("button",{style:n.closeButton,onClick:()=>this.setUncaughtException(null)},"\xD7"),r("h2",{style:n.errorTitle},a?"An error happened in a JavaScript code event.":"A crash or error happened in the game."),r("p",{style:n.errorMessage},(a?'This error comes from a JavaScript code event. Verify your code to ensure no error is happening. You can use the Developer Tools (menu "View" > "Toggle Developer Tools"). Full error is: ':"If you're using JavaScript, verify your code. Otherwise, this might be an issue with GDevelop - consider reporting a bug. Full error is: ")+this._uncaughtException.message),r("pre",{style:n.stacktrace},this._uncaughtException.stack||"(No stracktrace).")),this._uncaughtExceptionElement&&e.appendChild(this._uncaughtExceptionElement)}}}p.InGameDebugger=u})(gdjs||(gdjs={}));
1
+ var gdjs;(function(l){function t(a,e,...i){const n=document.createElement(a);return Object.keys(e).forEach(o=>{if(o==="style")for(const[s,c]of Object.entries(e.style))n.style[s]=c;else o==="onClick"?n.addEventListener("click",e[o]):n.setAttribute(o,""+e[o])}),n.append(...i),n}const r={errorContainer:{padding:"15px",backgroundColor:"#a70000cc",borderRadius:"8px",position:"absolute",bottom:"5px",left:"5px",right:"5px",color:"white",display:"flex",flexDirection:"column",pointerEvents:"all"},errorTitle:{fontFamily:"system-ui",fontSize:"20px",marginTop:"5px",marginBottom:"5px",userSelect:"all"},errorMessage:{fontFamily:"system-ui",fontSize:"14px",userSelect:"all"},stacktrace:{fontSize:"14px",fontFamily:"monospace",whiteSpace:"pre",maxHeight:"510px",overflow:"auto",userSelect:"all"},closeButton:{padding:"3px",width:"20px",fontSize:"18px",position:"absolute",right:"5px",top:"5px",color:"white",border:"1px solid white",borderRadius:"6px",backgroundColor:"transparent"}};class u{constructor(e){this._uncaughtException=null;this._uncaughtExceptionElement=null;this._runtimeGame=e}setUncaughtException(e){this._uncaughtException&&!!e||(this._uncaughtException=e,this.render())}render(){const e=this._runtimeGame.getRenderer().getDomElementContainer();if(!!e&&(this._uncaughtExceptionElement&&(e.removeChild(this._uncaughtExceptionElement),this._uncaughtExceptionElement=null),this._uncaughtException)){const i=l.AbstractDebuggerClient.isErrorComingFromJavaScriptCode(this._uncaughtException);this._uncaughtExceptionElement=t("div",{style:r.errorContainer},t("button",{style:r.closeButton,onClick:()=>this.setUncaughtException(null)},"\xD7"),t("h2",{style:r.errorTitle},i?"An error happened in a JavaScript code event.":"A crash or error happened in the game."),t("p",{style:r.errorMessage},(i?'This error comes from a JavaScript code event. Verify your code to ensure no error is happening. You can use the Developer Tools (menu "View" > "Toggle Developer Tools"). Full error is: ':"If you're using JavaScript, verify your code. Otherwise, this might be an issue with GDevelop - consider reporting a bug. Full error is: ")+this._uncaughtException.message),t("pre",{style:r.stacktrace},this._uncaughtException.stack||"(No stracktrace).")),this._uncaughtExceptionElement&&e.appendChild(this._uncaughtExceptionElement)}}}l.InGameDebugger=u})(gdjs||(gdjs={}));
2
2
  //# sourceMappingURL=InGameDebugger.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../GDevelop/GDJS/Runtime/debugger-client/InGameDebugger.tsx"],
4
- "sourcesContent": ["namespace gdjs {\n /** A minimal utility to define DOM elements. */\n function h<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs: {\n style?: Partial<CSSStyleDeclaration>;\n onClick?: () => void;\n },\n ...nodes: (HTMLElement | string)[]\n ): HTMLElement {\n const node = document.createElement(tag);\n Object.keys(attrs).forEach((key) => {\n if (key === 'style') {\n for (const [styleName, value] of Object.entries(attrs.style!)) {\n node.style[styleName] = value;\n }\n } else if (key === 'onClick') {\n node.addEventListener('click', attrs[key]!);\n } else {\n node.setAttribute(key, '' + attrs[key]);\n }\n });\n\n node.append(...nodes);\n return node;\n }\n\n const styles: {\n errorContainer: Partial<CSSStyleDeclaration>;\n errorTitle: Partial<CSSStyleDeclaration>;\n errorMessage: Partial<CSSStyleDeclaration>;\n stacktrace: Partial<CSSStyleDeclaration>;\n closeButton: Partial<CSSStyleDeclaration>;\n } = {\n errorContainer: {\n padding: '15px',\n backgroundColor: '#a70000cc',\n borderRadius: '8px',\n position: 'absolute',\n bottom: '5px',\n left: '5px',\n right: '5px',\n color: 'white',\n display: 'flex',\n flexDirection: 'column',\n pointerEvents: 'all',\n },\n errorTitle: {\n fontFamily: 'system-ui',\n fontSize: '20px',\n marginTop: '5px',\n marginBottom: '5px',\n userSelect: 'all',\n },\n errorMessage: {\n fontFamily: 'system-ui',\n fontSize: '14px',\n userSelect: 'all',\n },\n stacktrace: {\n fontSize: '14px',\n fontFamily: 'monospace',\n whiteSpace: 'pre',\n maxHeight: '510px',\n overflow: 'auto',\n userSelect: 'all',\n },\n closeButton: {\n padding: '3px',\n width: '20px',\n fontSize: '18px',\n position: 'absolute',\n right: '5px',\n top: '5px',\n color: 'white',\n border: '1px solid white',\n borderRadius: '6px',\n backgroundColor: 'transparent',\n },\n };\n\n const isErrorComingFromJavaScriptCode = (\n exception: Error | null\n ): boolean => {\n if (!exception || !exception.stack) return false;\n\n return exception.stack.includes('GDJSInlineCode');\n };\n\n /**\n * Displays uncaught exceptions on top of the game.\n * Could be reworked in the future to support a minimal debugger inside the game.\n */\n export class InGameDebugger {\n _runtimeGame: RuntimeGame;\n _uncaughtException: Error | null = null;\n _uncaughtExceptionElement: HTMLElement | null = null;\n\n constructor(runtimeGame: RuntimeGame) {\n this._runtimeGame = runtimeGame;\n }\n\n setUncaughtException(exception: Error | null) {\n // Only show the first uncaught exception and ignore anything else.\n if (this._uncaughtException && !!exception) return;\n\n this._uncaughtException = exception;\n this.render();\n }\n\n render() {\n const domElementContainer = this._runtimeGame\n .getRenderer()\n .getDomElementContainer();\n if (!domElementContainer) return;\n\n if (this._uncaughtExceptionElement) {\n domElementContainer.removeChild(this._uncaughtExceptionElement);\n this._uncaughtExceptionElement = null;\n }\n\n if (this._uncaughtException) {\n const errorIsInJs = isErrorComingFromJavaScriptCode(\n this._uncaughtException\n );\n this._uncaughtExceptionElement = (\n <div style={styles.errorContainer}>\n <button\n style={styles.closeButton}\n onClick={() => this.setUncaughtException(null)}\n >\n \u00D7\n </button>\n <h2 style={styles.errorTitle}>\n {errorIsInJs\n ? 'An error happened in a JavaScript code event.'\n : 'A crash or error happened in the game.'}\n </h2>\n <p style={styles.errorMessage}>\n {(errorIsInJs\n ? 'This error comes from a JavaScript code event. Verify your code to ensure no error is happening. You can use the Developer Tools (menu \"View\" > \"Toggle Developer Tools\"). Full error is: '\n : \"If you're using JavaScript, verify your code. Otherwise, this might be an issue with GDevelop - consider reporting a bug. Full error is: \") +\n this._uncaughtException.message}\n </p>\n <pre style={styles.stacktrace}>\n {this._uncaughtException.stack || '(No stracktrace).'}\n </pre>\n </div>\n );\n\n if (this._uncaughtExceptionElement)\n domElementContainer.appendChild(this._uncaughtExceptionElement);\n }\n }\n }\n}\n"],
5
- "mappings": "AAAA,GAAU,MAAV,UAAU,EAAV,CAEE,WACE,EACA,KAIG,EACU,CACb,KAAM,GAAO,SAAS,cAAc,GACpC,cAAO,KAAK,GAAO,QAAQ,AAAC,GAAQ,CAClC,GAAI,IAAQ,QACV,SAAW,CAAC,EAAW,IAAU,QAAO,QAAQ,EAAM,OACpD,EAAK,MAAM,GAAa,MAErB,AAAI,KAAQ,UACjB,EAAK,iBAAiB,QAAS,EAAM,IAErC,EAAK,aAAa,EAAK,GAAK,EAAM,MAItC,EAAK,OAAO,GAAG,GACR,EAGT,KAAM,GAMF,CACF,eAAgB,CACd,QAAS,OACT,gBAAiB,YACjB,aAAc,MACd,SAAU,WACV,OAAQ,MACR,KAAM,MACN,MAAO,MACP,MAAO,QACP,QAAS,OACT,cAAe,SACf,cAAe,OAEjB,WAAY,CACV,WAAY,YACZ,SAAU,OACV,UAAW,MACX,aAAc,MACd,WAAY,OAEd,aAAc,CACZ,WAAY,YACZ,SAAU,OACV,WAAY,OAEd,WAAY,CACV,SAAU,OACV,WAAY,YACZ,WAAY,MACZ,UAAW,QACX,SAAU,OACV,WAAY,OAEd,YAAa,CACX,QAAS,MACT,MAAO,OACP,SAAU,OACV,SAAU,WACV,MAAO,MACP,IAAK,MACL,MAAO,QACP,OAAQ,kBACR,aAAc,MACd,gBAAiB,gBAIf,EAAkC,AACtC,GAEI,CAAC,GAAa,CAAC,EAAU,MAAc,GAEpC,EAAU,MAAM,SAAS,kBAO3B,OAAqB,CAK1B,YAAY,EAA0B,CAHtC,wBAAmC,KACnC,+BAAgD,KAG9C,KAAK,aAAe,EAGtB,qBAAqB,EAAyB,CAE5C,AAAI,KAAK,oBAAsB,CAAC,CAAC,GAEjC,MAAK,mBAAqB,EAC1B,KAAK,UAGP,QAAS,CACP,KAAM,GAAsB,KAAK,aAC9B,cACA,yBACH,GAAI,EAAC,GAED,MAAK,2BACP,GAAoB,YAAY,KAAK,2BACrC,KAAK,0BAA4B,MAG/B,KAAK,oBAAoB,CAC3B,KAAM,GAAc,EAClB,KAAK,oBAEP,KAAK,0BACH,EAAC,MAAD,CAAK,MAAO,EAAO,gBACjB,EAAC,SAAD,CACE,MAAO,EAAO,YACd,QAAS,IAAM,KAAK,qBAAqB,OAC1C,QAGD,EAAC,KAAD,CAAI,MAAO,EAAO,YACf,EACG,gDACA,0CAEN,EAAC,IAAD,CAAG,MAAO,EAAO,cACb,GACE,6LACA,6IACF,KAAK,mBAAmB,SAE5B,EAAC,MAAD,CAAK,MAAO,EAAO,YAChB,KAAK,mBAAmB,OAAS,sBAKpC,KAAK,2BACP,EAAoB,YAAY,KAAK,6BA1DtC,EAAM,mBA7FL",
4
+ "sourcesContent": ["namespace gdjs {\n /** A minimal utility to define DOM elements. */\n function h<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs: {\n style?: Partial<CSSStyleDeclaration>;\n onClick?: () => void;\n },\n ...nodes: (HTMLElement | string)[]\n ): HTMLElement {\n const node = document.createElement(tag);\n Object.keys(attrs).forEach((key) => {\n if (key === 'style') {\n for (const [styleName, value] of Object.entries(attrs.style!)) {\n node.style[styleName] = value;\n }\n } else if (key === 'onClick') {\n node.addEventListener('click', attrs[key]!);\n } else {\n node.setAttribute(key, '' + attrs[key]);\n }\n });\n\n node.append(...nodes);\n return node;\n }\n\n const styles: {\n errorContainer: Partial<CSSStyleDeclaration>;\n errorTitle: Partial<CSSStyleDeclaration>;\n errorMessage: Partial<CSSStyleDeclaration>;\n stacktrace: Partial<CSSStyleDeclaration>;\n closeButton: Partial<CSSStyleDeclaration>;\n } = {\n errorContainer: {\n padding: '15px',\n backgroundColor: '#a70000cc',\n borderRadius: '8px',\n position: 'absolute',\n bottom: '5px',\n left: '5px',\n right: '5px',\n color: 'white',\n display: 'flex',\n flexDirection: 'column',\n pointerEvents: 'all',\n },\n errorTitle: {\n fontFamily: 'system-ui',\n fontSize: '20px',\n marginTop: '5px',\n marginBottom: '5px',\n userSelect: 'all',\n },\n errorMessage: {\n fontFamily: 'system-ui',\n fontSize: '14px',\n userSelect: 'all',\n },\n stacktrace: {\n fontSize: '14px',\n fontFamily: 'monospace',\n whiteSpace: 'pre',\n maxHeight: '510px',\n overflow: 'auto',\n userSelect: 'all',\n },\n closeButton: {\n padding: '3px',\n width: '20px',\n fontSize: '18px',\n position: 'absolute',\n right: '5px',\n top: '5px',\n color: 'white',\n border: '1px solid white',\n borderRadius: '6px',\n backgroundColor: 'transparent',\n },\n };\n\n /**\n * Displays uncaught exceptions on top of the game.\n * Could be reworked in the future to support a minimal debugger inside the game.\n */\n export class InGameDebugger {\n _runtimeGame: RuntimeGame;\n _uncaughtException: Error | null = null;\n _uncaughtExceptionElement: HTMLElement | null = null;\n\n constructor(runtimeGame: RuntimeGame) {\n this._runtimeGame = runtimeGame;\n }\n\n setUncaughtException(exception: Error | null) {\n // Only show the first uncaught exception and ignore anything else.\n if (this._uncaughtException && !!exception) return;\n\n this._uncaughtException = exception;\n this.render();\n }\n\n render() {\n const domElementContainer = this._runtimeGame\n .getRenderer()\n .getDomElementContainer();\n if (!domElementContainer) return;\n\n if (this._uncaughtExceptionElement) {\n domElementContainer.removeChild(this._uncaughtExceptionElement);\n this._uncaughtExceptionElement = null;\n }\n\n if (this._uncaughtException) {\n const errorIsInJs = gdjs.AbstractDebuggerClient.isErrorComingFromJavaScriptCode(\n this._uncaughtException\n );\n this._uncaughtExceptionElement = (\n <div style={styles.errorContainer}>\n <button\n style={styles.closeButton}\n onClick={() => this.setUncaughtException(null)}\n >\n \u00D7\n </button>\n <h2 style={styles.errorTitle}>\n {errorIsInJs\n ? 'An error happened in a JavaScript code event.'\n : 'A crash or error happened in the game.'}\n </h2>\n <p style={styles.errorMessage}>\n {(errorIsInJs\n ? 'This error comes from a JavaScript code event. Verify your code to ensure no error is happening. You can use the Developer Tools (menu \"View\" > \"Toggle Developer Tools\"). Full error is: '\n : \"If you're using JavaScript, verify your code. Otherwise, this might be an issue with GDevelop - consider reporting a bug. Full error is: \") +\n this._uncaughtException.message}\n </p>\n <pre style={styles.stacktrace}>\n {this._uncaughtException.stack || '(No stracktrace).'}\n </pre>\n </div>\n );\n\n if (this._uncaughtExceptionElement)\n domElementContainer.appendChild(this._uncaughtExceptionElement);\n }\n }\n }\n}\n"],
5
+ "mappings": "AAAA,GAAU,MAAV,UAAU,EAAV,CAEE,WACE,EACA,KAIG,EACU,CACb,KAAM,GAAO,SAAS,cAAc,GACpC,cAAO,KAAK,GAAO,QAAQ,AAAC,GAAQ,CAClC,GAAI,IAAQ,QACV,SAAW,CAAC,EAAW,IAAU,QAAO,QAAQ,EAAM,OACpD,EAAK,MAAM,GAAa,MAErB,AAAI,KAAQ,UACjB,EAAK,iBAAiB,QAAS,EAAM,IAErC,EAAK,aAAa,EAAK,GAAK,EAAM,MAItC,EAAK,OAAO,GAAG,GACR,EAGT,KAAM,GAMF,CACF,eAAgB,CACd,QAAS,OACT,gBAAiB,YACjB,aAAc,MACd,SAAU,WACV,OAAQ,MACR,KAAM,MACN,MAAO,MACP,MAAO,QACP,QAAS,OACT,cAAe,SACf,cAAe,OAEjB,WAAY,CACV,WAAY,YACZ,SAAU,OACV,UAAW,MACX,aAAc,MACd,WAAY,OAEd,aAAc,CACZ,WAAY,YACZ,SAAU,OACV,WAAY,OAEd,WAAY,CACV,SAAU,OACV,WAAY,YACZ,WAAY,MACZ,UAAW,QACX,SAAU,OACV,WAAY,OAEd,YAAa,CACX,QAAS,MACT,MAAO,OACP,SAAU,OACV,SAAU,WACV,MAAO,MACP,IAAK,MACL,MAAO,QACP,OAAQ,kBACR,aAAc,MACd,gBAAiB,gBAQd,OAAqB,CAK1B,YAAY,EAA0B,CAHtC,wBAAmC,KACnC,+BAAgD,KAG9C,KAAK,aAAe,EAGtB,qBAAqB,EAAyB,CAE5C,AAAI,KAAK,oBAAsB,CAAC,CAAC,GAEjC,MAAK,mBAAqB,EAC1B,KAAK,UAGP,QAAS,CACP,KAAM,GAAsB,KAAK,aAC9B,cACA,yBACH,GAAI,EAAC,GAED,MAAK,2BACP,GAAoB,YAAY,KAAK,2BACrC,KAAK,0BAA4B,MAG/B,KAAK,oBAAoB,CAC3B,KAAM,GAAc,EAAK,uBAAuB,gCAC9C,KAAK,oBAEP,KAAK,0BACH,EAAC,MAAD,CAAK,MAAO,EAAO,gBACjB,EAAC,SAAD,CACE,MAAO,EAAO,YACd,QAAS,IAAM,KAAK,qBAAqB,OAC1C,QAGD,EAAC,KAAD,CAAI,MAAO,EAAO,YACf,EACG,gDACA,0CAEN,EAAC,IAAD,CAAG,MAAO,EAAO,cACb,GACE,6LACA,6IACF,KAAK,mBAAmB,SAE5B,EAAC,MAAD,CAAK,MAAO,EAAO,YAChB,KAAK,mBAAmB,OAAS,sBAKpC,KAAK,2BACP,EAAoB,YAAY,KAAK,6BA1DtC,EAAM,mBArFL",
6
6
  "names": []
7
7
  }
@@ -1,2 +1,2 @@
1
- var gdjs;(function(c){const a=new c.Logger("Debugger client"),g={log:console.log,info:console.info,debug:console.debug,warn:console.warn,error:console.error},m=(d,e,o)=>{const r=[],n=[];return e==null&&(e=function(i,t){return r[0]===t?"[Circular ~]":"[Circular ~."+n.slice(0,r.indexOf(t)).join(".")+"]"}),function(i,t){if(r.length>0){const s=r.indexOf(this);if(~s?r.splice(s+1):r.push(this),~s?n.splice(s,1/0,i):n.push(i),o!=null&&s>o)return"[Max depth reached]";~r.indexOf(t)&&(t=e.call(this,i,t))}else r.push(t);return d==null?t:d.call(this,i,t)}},l=(d,e,o,r,n)=>JSON.stringify(d,m(e,n,o),r);class p{constructor(e){this._originalConsole=g;this._runtimegame=e,this._hotReloader=new c.HotReloader(e),this._inGameDebugger=new c.InGameDebugger(e);const o=(n,...i)=>{this.log("JavaScript",i.reduce((t,s)=>t+s,""),n,!1)};console.log=(...n)=>{g.log(...n),o("info",...n)},console.debug=(...n)=>{g.debug(...n),o("info",...n)},console.info=(...n)=>{g.info(...n),o("info",...n)},console.warn=(...n)=>{g.warn(...n),o("warning",...n)},console.error=(...n)=>{g.error(...n),o("error",...n)};const r=c.Logger.getLoggerOutput();c.Logger.setLoggerOutput({log:(n,i,t="info",s=!0)=>{r.log(n,i,t,s),this.log(n,i,t,s)}})}handleCommand(e){const o=this,r=this._runtimegame;!e||!e.command||(e.command==="play"?r.pause(!1):e.command==="pause"?(r.pause(!0),o.sendRuntimeGameDump()):e.command==="refresh"?o.sendRuntimeGameDump():e.command==="set"?o.set(e.path,e.newValue):e.command==="call"?o.call(e.path,e.args):e.command==="profiler.start"?(r.startCurrentSceneProfiler(function(n){o.sendProfilerOutput(n.getFramesAverageMeasures(),n.getStats()),o.sendProfilerStopped()}),o.sendProfilerStarted()):e.command==="profiler.stop"?r.stopCurrentSceneProfiler():e.command==="hotReload"?o._hotReloader.hotReload().then(n=>{o.sendHotReloaderLogs(n)}):a.info('Unknown command "'+e.command+'" received by the debugger.'))}onUncaughtException(e){a.error("Uncaught exception: "+e),this._inGameDebugger.setUncaughtException(e)}log(e,o,r,n){this._sendMessage(JSON.stringify({command:"console.log",payload:{message:o,type:r,group:e,internal:n,timestamp:performance.now()}}))}set(e,o){if(!e||!e.length)return a.warn("No path specified, set operation from debugger aborted"),!1;let r=this._runtimegame,n=0;for(;n<e.length-1;){const t=e[n];if(!r||!r[t])return a.error("Incorrect path specified. No "+t+" in ",r),!1;r=r[t],n++}const i=r[e[n]];return typeof i=="number"?o=parseFloat(o):typeof i=="string"&&(o=""+o),a.log("Updating",e,"to",o),r[e[n]]=o,!0}call(e,o){if(!e||!e.length)return a.warn("No path specified, call operation from debugger aborted"),!1;let r=this._runtimegame,n=0;for(;n<e.length-1;){const i=e[n];if(!r||!r[i])return a.error("Incorrect path specified. No "+i+" in ",r),!1;r=r[i],n++}return r[e[n]]?(a.log("Calling",e,"with",o),r[e[n]].apply(r,o),!0):(a.error("Unable to call",e),!1)}sendRuntimeGameDump(){const e=this,o={command:"dump",payload:this._runtimegame},r=Date.now(),n=[e._runtimegame.getGameData()],i=["_debuggerClient","_allInstancesList","_runtimeGame","_runtimeScene","_behaviorsTable","_animations","_animationFrame","linkedObjectsManager","_platformRBush","HSHG","_obstaclesHSHG","owner","_renderer","_gameRenderer","_imageManager","_rendererEffects","baseTexture","_baseTexture","_invalidTexture"],t=l(o,function(f,u){return n.indexOf(u)!==-1||i.indexOf(f)!==-1?"[Removed from the debugger]":u},18),s=Date.now()-r;a.log("RuntimeGame serialization took "+s+"ms"),s>500&&a.warn("Serialization took a long time: please check if there is a need to remove some objects from serialization"),this._sendMessage(t)}sendHotReloaderLogs(e){this._sendMessage(l({command:"hotReloader.logs",payload:e}))}sendProfilerStarted(){this._sendMessage(l({command:"profiler.started",payload:null}))}sendProfilerStopped(){this._sendMessage(l({command:"profiler.stopped",payload:null}))}sendGamePaused(){this._sendMessage(l({command:"game.paused",payload:null}))}sendGameResumed(){this._sendMessage(l({command:"game.resumed",payload:null}))}sendProfilerOutput(e,o){this._sendMessage(l({command:"profiler.output",payload:{framesAverageMeasures:e,stats:o}}))}}c.AbstractDebuggerClient=p})(gdjs||(gdjs={}));
1
+ var gdjs;(function(g){const a=new g.Logger("Debugger client"),d={log:console.log,info:console.info,debug:console.debug,warn:console.warn,error:console.error},f=(c,e,n)=>{const t=[],r=[];return e==null&&(e=function(o,i){return t[0]===i?"[Circular ~]":"[Circular ~."+r.slice(0,t.indexOf(i)).join(".")+"]"}),function(o,i){if(t.length>0){const s=t.indexOf(this);if(~s?t.splice(s+1):t.push(this),~s?r.splice(s,1/0,o):r.push(o),n!=null&&s>n)return"[Max depth reached]";~t.indexOf(i)&&(i=e.call(this,o,i))}else t.push(i);return c==null?i:c.call(this,o,i)}},l=(c,e,n,t,r)=>JSON.stringify(c,f(e,r,n),t),p=(c,e)=>{if(e instanceof Error){const n={};return Object.getOwnPropertyNames(e).forEach(t=>{n[t]=e[t]}),n}return e},h=(c,e)=>{const n=e.getSceneStack().getAllSceneNames(),t=e.getSceneStack().getCurrentScene();return{type:"javascript-uncaught-exception",exception:c,platformInfo:e.getPlatformInfo(),playerId:e.getPlayerId(),sessionId:e.getSessionId(),isPreview:e.isPreview(),gdevelop:{previewContext:e.getAdditionalOptions().previewContext,isNativeMobileApp:e.getAdditionalOptions().nativeMobileApp,versionWithHash:e.getAdditionalOptions().gdevelopVersionWithHash,environment:e.getAdditionalOptions().environment},game:{gameId:g.projectData.properties.projectUuid,name:e.getGameData().properties.name||"",packageName:e.getGameData().properties.packageName||"",version:e.getGameData().properties.version||"",location:window.location.href,projectTemplateSlug:e.getAdditionalOptions().projectTemplateSlug,sourceGameId:e.getAdditionalOptions().sourceGameId},gameState:{sceneNames:n,isWebGLSupported:e.getRenderer().isWebGLSupported(),hasPixiRenderer:!!e.getRenderer().getPIXIRenderer(),hasThreeRenderer:!!e.getRenderer().getThreeRenderer(),resourcesTotalCount:e.getGameData().resources.resources.length,antialiasingMode:e.getAntialiasingMode(),isAntialisingEnabledOnMobile:e.isAntialisingEnabledOnMobile(),scriptFiles:e.getAdditionalOptions().scriptFiles,currentSceneTimeFromStart:t?t.getTimeManager().getTimeFromStart():null,gdjsKeys:Object.keys(g).slice(0,1e3)}}};class u{constructor(e){this._originalConsole=d;this._hasLoggedUncaughtException=!1;this._runtimegame=e,this._hotReloader=new g.HotReloader(e),this._inGameDebugger=new g.InGameDebugger(e);const n=(r,...o)=>{this.log("JavaScript",o.reduce((i,s)=>i+s,""),r,!1)};console.log=(...r)=>{d.log(...r),n("info",...r)},console.debug=(...r)=>{d.debug(...r),n("info",...r)},console.info=(...r)=>{d.info(...r),n("info",...r)},console.warn=(...r)=>{d.warn(...r),n("warning",...r)},console.error=(...r)=>{d.error(...r),n("error",...r)};const t=g.Logger.getLoggerOutput();g.Logger.setLoggerOutput({log:(r,o,i="info",s=!0)=>{t.log(r,o,i,s),this.log(r,o,i,s)}})}handleCommand(e){const n=this,t=this._runtimegame;!e||!e.command||(e.command==="play"?t.pause(!1):e.command==="pause"?(t.pause(!0),n.sendRuntimeGameDump()):e.command==="refresh"?n.sendRuntimeGameDump():e.command==="set"?n.set(e.path,e.newValue):e.command==="call"?n.call(e.path,e.args):e.command==="profiler.start"?(t.startCurrentSceneProfiler(function(r){n.sendProfilerOutput(r.getFramesAverageMeasures(),r.getStats()),n.sendProfilerStopped()}),n.sendProfilerStarted()):e.command==="profiler.stop"?t.stopCurrentSceneProfiler():e.command==="hotReload"?n._hotReloader.hotReload().then(r=>{n.sendHotReloaderLogs(r)}):a.info('Unknown command "'+e.command+'" received by the debugger.'))}static isErrorComingFromJavaScriptCode(e){return!e||!e.stack?!1:e.stack.includes("GDJSInlineCode")}async _reportCrash(e){const n=h(e,this._runtimegame);if(this._sendMessage(l({command:"game.crashed",payload:n},p)),!this._runtimegame.getAdditionalOptions().crashReportUploadLevel||this._runtimegame.getAdditionalOptions().crashReportUploadLevel==="none"||this._runtimegame.getAdditionalOptions().crashReportUploadLevel==="exclude-javascript-code-events"&&u.isErrorComingFromJavaScriptCode(e))return;const r=`${this._runtimegame.isUsingGDevelopDevelopmentEnvironment()?"https://api-dev.gdevelop.io":"https://api.gdevelop.io"}/analytics`;try{await fetch(`${r}/game-crash-report`,{body:l(n,p),method:"POST"})}catch(o){a.error("Error while sending the crash report:",o)}}onUncaughtException(e){a.error("Uncaught exception: "+e),this._inGameDebugger.setUncaughtException(e),this._hasLoggedUncaughtException||(this._hasLoggedUncaughtException=!0,this._reportCrash(e))}log(e,n,t,r){this._sendMessage(JSON.stringify({command:"console.log",payload:{message:n,type:t,group:e,internal:r,timestamp:performance.now()}}))}set(e,n){if(!e||!e.length)return a.warn("No path specified, set operation from debugger aborted"),!1;let t=this._runtimegame,r=0;for(;r<e.length-1;){const i=e[r];if(!t||!t[i])return a.error("Incorrect path specified. No "+i+" in ",t),!1;t=t[i],r++}const o=t[e[r]];return typeof o=="number"?n=parseFloat(n):typeof o=="string"&&(n=""+n),a.log("Updating",e,"to",n),t[e[r]]=n,!0}call(e,n){if(!e||!e.length)return a.warn("No path specified, call operation from debugger aborted"),!1;let t=this._runtimegame,r=0;for(;r<e.length-1;){const o=e[r];if(!t||!t[o])return a.error("Incorrect path specified. No "+o+" in ",t),!1;t=t[o],r++}return t[e[r]]?(a.log("Calling",e,"with",n),t[e[r]].apply(t,n),!0):(a.error("Unable to call",e),!1)}sendRuntimeGameDump(){const e=this,n={command:"dump",payload:this._runtimegame},t=Date.now(),r=[e._runtimegame.getGameData()],o=["_debuggerClient","_allInstancesList","_runtimeGame","_runtimeScene","_behaviorsTable","_animations","_animationFrame","linkedObjectsManager","_platformRBush","HSHG","_obstaclesHSHG","owner","_renderer","_gameRenderer","_imageManager","_rendererEffects","baseTexture","_baseTexture","_invalidTexture"],i=l(n,function(b,m){return r.indexOf(m)!==-1||o.indexOf(b)!==-1?"[Removed from the debugger]":m},18),s=Date.now()-t;a.log("RuntimeGame serialization took "+s+"ms"),s>500&&a.warn("Serialization took a long time: please check if there is a need to remove some objects from serialization"),this._sendMessage(i)}sendHotReloaderLogs(e){this._sendMessage(l({command:"hotReloader.logs",payload:e}))}sendProfilerStarted(){this._sendMessage(l({command:"profiler.started",payload:null}))}sendProfilerStopped(){this._sendMessage(l({command:"profiler.stopped",payload:null}))}sendGamePaused(){this._sendMessage(l({command:"game.paused",payload:null}))}sendGameResumed(){this._sendMessage(l({command:"game.resumed",payload:null}))}sendProfilerOutput(e,n){this._sendMessage(l({command:"profiler.output",payload:{framesAverageMeasures:e,stats:n}}))}}g.AbstractDebuggerClient=u})(gdjs||(gdjs={}));
2
2
  //# sourceMappingURL=abstract-debugger-client.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../GDevelop/GDJS/Runtime/debugger-client/abstract-debugger-client.ts"],
4
- "sourcesContent": ["namespace gdjs {\n const logger = new gdjs.Logger('Debugger client');\n\n const originalConsole = {\n log: console.log,\n info: console.info,\n debug: console.debug,\n warn: console.warn,\n error: console.error,\n };\n\n /**\n * A function used to replace circular references with a new value.\n * @param key - The key corresponding to the value.\n * @param value - The value.\n * @returns The new value.\n */\n type DebuggerClientCycleReplacer = (key: string, value: any) => any;\n\n /**\n * Generates a JSON serializer that prevent circular references and stop if maxDepth is reached.\n * @param [replacer] - A function called for each property on the object or array being stringified, with the property key and its value, and that returns the new value. If not specified, values are not altered.\n * @param [cycleReplacer] - Function used to replace circular references with a new value.\n * @param [maxDepth] - The maximum depth, after which values are replaced by a string (\"[Max depth reached]\"). If not specified, there is no maximum depth.\n */\n const depthLimitedSerializer = (\n replacer?: DebuggerClientCycleReplacer,\n cycleReplacer?: DebuggerClientCycleReplacer,\n maxDepth?: number\n ): DebuggerClientCycleReplacer => {\n const stack: Array<string> = [],\n keys: Array<string> = [];\n if (cycleReplacer === undefined || cycleReplacer === null) {\n cycleReplacer = function (key, value) {\n if (stack[0] === value) {\n return '[Circular ~]';\n }\n return (\n '[Circular ~.' + keys.slice(0, stack.indexOf(value)).join('.') + ']'\n );\n };\n }\n\n return function (key: string, value: any): any {\n if (stack.length > 0) {\n const thisPos = stack.indexOf(this);\n ~thisPos ? stack.splice(thisPos + 1) : stack.push(this);\n ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key);\n if (maxDepth != null && thisPos > maxDepth) {\n return '[Max depth reached]';\n } else {\n if (~stack.indexOf(value)) {\n value = (cycleReplacer as DebuggerClientCycleReplacer).call(\n this,\n key,\n value\n );\n }\n }\n } else {\n stack.push(value);\n }\n return replacer == null ? value : replacer.call(this, key, value);\n };\n };\n\n /**\n * This is an alternative to JSON.stringify that ensure that circular references\n * are replaced by a placeholder.\n *\n * @param obj - The object to serialize.\n * @param [replacer] - A function called for each property on the object or array being stringified, with the property key and its value, and that returns the new value. If not specified, values are not altered.\n * @param [maxDepth] - The maximum depth, after which values are replaced by a string (\"[Max depth reached]\"). If not specified, there is no maximum depth.\n * @param [spaces] - The number of spaces for indentation.\n * @param [cycleReplacer] - Function used to replace circular references with a new value.\n */\n const circularSafeStringify = (\n obj: any,\n replacer?: DebuggerClientCycleReplacer,\n maxDepth?: number,\n spaces?: number,\n cycleReplacer?: DebuggerClientCycleReplacer\n ) => {\n return JSON.stringify(\n obj,\n depthLimitedSerializer(replacer, cycleReplacer, maxDepth),\n spaces\n );\n };\n\n /**\n * The base class describing a debugger client, that can be used to inspect\n * a runtime game (dump its state) or alter it.\n */\n export abstract class AbstractDebuggerClient {\n _runtimegame: gdjs.RuntimeGame;\n _hotReloader: gdjs.HotReloader;\n _originalConsole = originalConsole;\n _inGameDebugger: gdjs.InGameDebugger;\n\n constructor(runtimeGame: RuntimeGame) {\n this._runtimegame = runtimeGame;\n this._hotReloader = new gdjs.HotReloader(runtimeGame);\n this._inGameDebugger = new gdjs.InGameDebugger(runtimeGame);\n\n const redirectJsLog = (\n type: 'info' | 'warning' | 'error',\n ...messages: any[]\n ) => {\n this.log(\n 'JavaScript',\n messages.reduce((accumulator, value) => accumulator + value, ''),\n type,\n false\n );\n };\n\n // Hook the console logging functions to log to the Debugger as well\n console.log = (...messages: any[]) => {\n originalConsole.log(...messages);\n redirectJsLog('info', ...messages);\n };\n\n console.debug = (...messages: any[]) => {\n originalConsole.debug(...messages);\n redirectJsLog('info', ...messages);\n };\n\n console.info = (...messages: any[]) => {\n originalConsole.info(...messages);\n redirectJsLog('info', ...messages);\n };\n\n console.warn = (...messages: any[]) => {\n originalConsole.warn(...messages);\n redirectJsLog('warning', ...messages);\n };\n\n console.error = (...messages: any[]) => {\n originalConsole.error(...messages);\n redirectJsLog('error', ...messages);\n };\n\n // Overwrite the default GDJS log outputs so that they\n // both go to the console (or wherever they were configured to go)\n // and sent to the remote debugger.\n const existingLoggerOutput = gdjs.Logger.getLoggerOutput();\n gdjs.Logger.setLoggerOutput({\n log: (\n group: string,\n message: string,\n type: 'info' | 'warning' | 'error' = 'info',\n internal = true\n ) => {\n existingLoggerOutput.log(group, message, type, internal);\n this.log(group, message, type, internal);\n },\n });\n }\n\n /**\n * Should be called by derived class to handle a command\n * received from the debugger server.\n *\n * @param data An object containing the command to do.\n */\n protected handleCommand(data: any) {\n const that = this;\n const runtimeGame = this._runtimegame;\n if (!data || !data.command) {\n // Not a command that's meant to be handled by the debugger, return silently to\n // avoid polluting the console.\n return;\n }\n\n if (data.command === 'play') {\n runtimeGame.pause(false);\n } else if (data.command === 'pause') {\n runtimeGame.pause(true);\n that.sendRuntimeGameDump();\n } else if (data.command === 'refresh') {\n that.sendRuntimeGameDump();\n } else if (data.command === 'set') {\n that.set(data.path, data.newValue);\n } else if (data.command === 'call') {\n that.call(data.path, data.args);\n } else if (data.command === 'profiler.start') {\n runtimeGame.startCurrentSceneProfiler(function (stoppedProfiler) {\n that.sendProfilerOutput(\n stoppedProfiler.getFramesAverageMeasures(),\n stoppedProfiler.getStats()\n );\n that.sendProfilerStopped();\n });\n that.sendProfilerStarted();\n } else if (data.command === 'profiler.stop') {\n runtimeGame.stopCurrentSceneProfiler();\n } else if (data.command === 'hotReload') {\n that._hotReloader.hotReload().then((logs) => {\n that.sendHotReloaderLogs(logs);\n });\n } else {\n logger.info(\n 'Unknown command \"' + data.command + '\" received by the debugger.'\n );\n }\n }\n\n /**\n * Should be re-implemented by derived class to send a stringified message object\n * to the debugger server.\n * @param message\n */\n protected abstract _sendMessage(message: string): void;\n\n onUncaughtException(exception: Error): void {\n logger.error('Uncaught exception: ' + exception);\n\n this._inGameDebugger.setUncaughtException(exception);\n }\n\n /**\n * Send a message (a log) to debugger server.\n */\n log(\n group: string,\n message: string,\n type: 'info' | 'warning' | 'error',\n internal: boolean\n ) {\n this._sendMessage(\n JSON.stringify({\n command: 'console.log',\n payload: {\n message,\n type,\n group,\n internal,\n timestamp: performance.now(),\n },\n })\n );\n }\n\n /**\n * Update a value, specified by a path starting from the {@link RuntimeGame} instance.\n * @param path - The path to the variable, starting from {@link RuntimeGame}.\n * @param newValue - The new value.\n * @return Was the operation successful?\n */\n set(path: string[], newValue: any): boolean {\n if (!path || !path.length) {\n logger.warn('No path specified, set operation from debugger aborted');\n return false;\n }\n let object = this._runtimegame;\n let currentIndex = 0;\n while (currentIndex < path.length - 1) {\n const key = path[currentIndex];\n if (!object || !object[key]) {\n logger.error('Incorrect path specified. No ' + key + ' in ', object);\n return false;\n }\n object = object[key];\n currentIndex++;\n }\n\n // Ensure the newValue is properly typed to avoid breaking anything in\n // the game engine.\n const currentValue = object[path[currentIndex]];\n if (typeof currentValue === 'number') {\n newValue = parseFloat(newValue);\n } else {\n if (typeof currentValue === 'string') {\n newValue = '' + newValue;\n }\n }\n logger.log('Updating', path, 'to', newValue);\n object[path[currentIndex]] = newValue;\n return true;\n }\n\n /**\n * Call a method, specified by a path starting from the {@link RuntimeGame} instance.\n * @param path - The path to the method, starting from {@link RuntimeGame}.\n * @param args - The arguments to pass the method.\n * @return Was the operation successful?\n */\n call(path: string[], args: any[]): boolean {\n if (!path || !path.length) {\n logger.warn('No path specified, call operation from debugger aborted');\n return false;\n }\n let object = this._runtimegame;\n let currentIndex = 0;\n while (currentIndex < path.length - 1) {\n const key = path[currentIndex];\n if (!object || !object[key]) {\n logger.error('Incorrect path specified. No ' + key + ' in ', object);\n return false;\n }\n object = object[key];\n currentIndex++;\n }\n if (!object[path[currentIndex]]) {\n logger.error('Unable to call', path);\n return false;\n }\n logger.log('Calling', path, 'with', args);\n object[path[currentIndex]].apply(object, args);\n return true;\n }\n\n /**\n * Dump all the relevant data from the {@link RuntimeGame} instance and send it to the server.\n */\n sendRuntimeGameDump(): void {\n const that = this;\n const message = { command: 'dump', payload: this._runtimegame };\n const serializationStartTime = Date.now();\n\n // Stringify the message, excluding some known data that are big and/or not\n // useful for the debugger.\n const excludedValues = [that._runtimegame.getGameData()];\n const excludedKeys = [\n // Exclude reference to the debugger\n '_debuggerClient',\n // Exclude some RuntimeScene fields:\n '_allInstancesList',\n // Exclude circular references to parent runtimeGame or runtimeScene:\n '_runtimeGame',\n '_runtimeScene',\n // Exclude some runtimeObject duplicated data:\n '_behaviorsTable',\n // Exclude some objects data:\n '_animations',\n '_animationFrame',\n // Exclude linked objects to avoid too much repetitions:\n 'linkedObjectsManager',\n // Could be improved by using private fields and excluding these (_)\n // Exclude some behaviors data:\n '_platformRBush',\n // PlatformBehavior\n 'HSHG',\n // Pathfinding\n '_obstaclesHSHG',\n // Pathfinding\n 'owner',\n // Avoid circular reference from behavior to parent runtimeObject\n // Exclude rendering related objects:\n '_renderer',\n '_gameRenderer',\n '_imageManager',\n '_rendererEffects',\n // Exclude PIXI textures:\n 'baseTexture',\n '_baseTexture',\n '_invalidTexture',\n ];\n const stringifiedMessage = circularSafeStringify(\n message,\n function (key, value) {\n if (\n excludedValues.indexOf(value) !== -1 ||\n excludedKeys.indexOf(key) !== -1\n ) {\n return '[Removed from the debugger]';\n }\n return value;\n },\n /* Limit maximum depth to prevent any crashes */\n 18\n );\n const serializationDuration = Date.now() - serializationStartTime;\n logger.log(\n 'RuntimeGame serialization took ' + serializationDuration + 'ms'\n );\n if (serializationDuration > 500) {\n logger.warn(\n 'Serialization took a long time: please check if there is a need to remove some objects from serialization'\n );\n }\n this._sendMessage(stringifiedMessage);\n }\n\n /**\n * Send logs from the hot reloader to the server.\n * @param logs The hot reloader logs.\n */\n sendHotReloaderLogs(logs: HotReloaderLog[]): void {\n this._sendMessage(\n circularSafeStringify({\n command: 'hotReloader.logs',\n payload: logs,\n })\n );\n }\n\n /**\n * Callback called when profiling is starting.\n */\n sendProfilerStarted(): void {\n this._sendMessage(\n circularSafeStringify({\n command: 'profiler.started',\n payload: null,\n })\n );\n }\n\n /**\n * Callback called when profiling is ending.\n */\n sendProfilerStopped(): void {\n this._sendMessage(\n circularSafeStringify({\n command: 'profiler.stopped',\n payload: null,\n })\n );\n }\n\n /**\n * Callback called when the game is paused.\n */\n sendGamePaused(): void {\n this._sendMessage(\n circularSafeStringify({\n command: 'game.paused',\n payload: null,\n })\n );\n }\n\n /**\n * Callback called when the game is resumed.\n */\n sendGameResumed(): void {\n this._sendMessage(\n circularSafeStringify({\n command: 'game.resumed',\n payload: null,\n })\n );\n }\n\n /**\n * Send profiling results.\n * @param framesAverageMeasures The measures made for each frames.\n * @param stats Other measures done during the profiler run.\n */\n sendProfilerOutput(\n framesAverageMeasures: FrameMeasure,\n stats: ProfilerStats\n ): void {\n this._sendMessage(\n circularSafeStringify({\n command: 'profiler.output',\n payload: {\n framesAverageMeasures: framesAverageMeasures,\n stats: stats,\n },\n })\n );\n }\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["namespace gdjs {\n const logger = new gdjs.Logger('Debugger client');\n\n const originalConsole = {\n log: console.log,\n info: console.info,\n debug: console.debug,\n warn: console.warn,\n error: console.error,\n };\n\n /**\n * A function used to replace circular references with a new value.\n * @param key - The key corresponding to the value.\n * @param value - The value.\n * @returns The new value.\n */\n type DebuggerClientCycleReplacer = (key: string, value: any) => any;\n\n /**\n * Generates a JSON serializer that prevent circular references and stop if maxDepth is reached.\n * @param [replacer] - A function called for each property on the object or array being stringified, with the property key and its value, and that returns the new value. If not specified, values are not altered.\n * @param [cycleReplacer] - Function used to replace circular references with a new value.\n * @param [maxDepth] - The maximum depth, after which values are replaced by a string (\"[Max depth reached]\"). If not specified, there is no maximum depth.\n */\n const depthLimitedSerializer = (\n replacer?: DebuggerClientCycleReplacer,\n cycleReplacer?: DebuggerClientCycleReplacer,\n maxDepth?: number\n ): DebuggerClientCycleReplacer => {\n const stack: Array<string> = [],\n keys: Array<string> = [];\n if (cycleReplacer === undefined || cycleReplacer === null) {\n cycleReplacer = function (key, value) {\n if (stack[0] === value) {\n return '[Circular ~]';\n }\n return (\n '[Circular ~.' + keys.slice(0, stack.indexOf(value)).join('.') + ']'\n );\n };\n }\n\n return function (key: string, value: any): any {\n if (stack.length > 0) {\n const thisPos = stack.indexOf(this);\n ~thisPos ? stack.splice(thisPos + 1) : stack.push(this);\n ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key);\n if (maxDepth != null && thisPos > maxDepth) {\n return '[Max depth reached]';\n } else {\n if (~stack.indexOf(value)) {\n value = (cycleReplacer as DebuggerClientCycleReplacer).call(\n this,\n key,\n value\n );\n }\n }\n } else {\n stack.push(value);\n }\n return replacer == null ? value : replacer.call(this, key, value);\n };\n };\n\n /**\n * This is an alternative to JSON.stringify that ensure that circular references\n * are replaced by a placeholder.\n *\n * @param obj - The object to serialize.\n * @param [replacer] - A function called for each property on the object or array being stringified, with the property key and its value, and that returns the new value. If not specified, values are not altered.\n * @param [maxDepth] - The maximum depth, after which values are replaced by a string (\"[Max depth reached]\"). If not specified, there is no maximum depth.\n * @param [spaces] - The number of spaces for indentation.\n * @param [cycleReplacer] - Function used to replace circular references with a new value.\n */\n const circularSafeStringify = (\n obj: any,\n replacer?: DebuggerClientCycleReplacer,\n maxDepth?: number,\n spaces?: number,\n cycleReplacer?: DebuggerClientCycleReplacer\n ) => {\n return JSON.stringify(\n obj,\n depthLimitedSerializer(replacer, cycleReplacer, maxDepth),\n spaces\n );\n };\n\n /** Replacer function for JSON.stringify to convert Error objects into plain objects that can be logged. */\n const errorReplacer = (_, value: any) => {\n if (value instanceof Error) {\n // See https://stackoverflow.com/questions/18391212/is-it-not-possible-to-stringify-an-error-using-json-stringify\n const errorObject = {};\n Object.getOwnPropertyNames(value).forEach((prop) => {\n errorObject[prop] = value[prop];\n });\n\n return errorObject;\n }\n // Return the value unchanged if it's not an Error object.\n return value;\n };\n\n const buildGameCrashReport = (\n exception: Error,\n runtimeGame: gdjs.RuntimeGame\n ) => {\n const sceneNames = runtimeGame.getSceneStack().getAllSceneNames();\n const currentScene = runtimeGame.getSceneStack().getCurrentScene();\n return {\n type: 'javascript-uncaught-exception',\n exception,\n platformInfo: runtimeGame.getPlatformInfo(),\n playerId: runtimeGame.getPlayerId(),\n sessionId: runtimeGame.getSessionId(),\n isPreview: runtimeGame.isPreview(),\n gdevelop: {\n previewContext: runtimeGame.getAdditionalOptions().previewContext,\n isNativeMobileApp: runtimeGame.getAdditionalOptions().nativeMobileApp,\n versionWithHash: runtimeGame.getAdditionalOptions()\n .gdevelopVersionWithHash,\n environment: runtimeGame.getAdditionalOptions().environment,\n },\n game: {\n gameId: gdjs.projectData.properties.projectUuid,\n name: runtimeGame.getGameData().properties.name || '',\n packageName: runtimeGame.getGameData().properties.packageName || '',\n version: runtimeGame.getGameData().properties.version || '',\n location: window.location.href,\n projectTemplateSlug: runtimeGame.getAdditionalOptions()\n .projectTemplateSlug,\n sourceGameId: runtimeGame.getAdditionalOptions().sourceGameId,\n },\n gameState: {\n sceneNames,\n isWebGLSupported: runtimeGame.getRenderer().isWebGLSupported(),\n hasPixiRenderer: !!runtimeGame.getRenderer().getPIXIRenderer(),\n hasThreeRenderer: !!runtimeGame.getRenderer().getThreeRenderer(),\n resourcesTotalCount: runtimeGame.getGameData().resources.resources\n .length,\n antialiasingMode: runtimeGame.getAntialiasingMode(),\n isAntialisingEnabledOnMobile: runtimeGame.isAntialisingEnabledOnMobile(),\n scriptFiles: runtimeGame.getAdditionalOptions().scriptFiles,\n currentSceneTimeFromStart: currentScene\n ? currentScene.getTimeManager().getTimeFromStart()\n : null,\n gdjsKeys: Object.keys(gdjs).slice(0, 1000),\n },\n };\n };\n\n /**\n * The base class describing a debugger client, that can be used to inspect\n * a runtime game (dump its state) or alter it.\n */\n export abstract class AbstractDebuggerClient {\n _runtimegame: gdjs.RuntimeGame;\n _hotReloader: gdjs.HotReloader;\n _originalConsole = originalConsole;\n _inGameDebugger: gdjs.InGameDebugger;\n\n _hasLoggedUncaughtException = false;\n\n constructor(runtimeGame: RuntimeGame) {\n this._runtimegame = runtimeGame;\n this._hotReloader = new gdjs.HotReloader(runtimeGame);\n this._inGameDebugger = new gdjs.InGameDebugger(runtimeGame);\n\n const redirectJsLog = (\n type: 'info' | 'warning' | 'error',\n ...messages: any[]\n ) => {\n this.log(\n 'JavaScript',\n messages.reduce((accumulator, value) => accumulator + value, ''),\n type,\n false\n );\n };\n\n // Hook the console logging functions to log to the Debugger as well\n console.log = (...messages: any[]) => {\n originalConsole.log(...messages);\n redirectJsLog('info', ...messages);\n };\n\n console.debug = (...messages: any[]) => {\n originalConsole.debug(...messages);\n redirectJsLog('info', ...messages);\n };\n\n console.info = (...messages: any[]) => {\n originalConsole.info(...messages);\n redirectJsLog('info', ...messages);\n };\n\n console.warn = (...messages: any[]) => {\n originalConsole.warn(...messages);\n redirectJsLog('warning', ...messages);\n };\n\n console.error = (...messages: any[]) => {\n originalConsole.error(...messages);\n redirectJsLog('error', ...messages);\n };\n\n // Overwrite the default GDJS log outputs so that they\n // both go to the console (or wherever they were configured to go)\n // and sent to the remote debugger.\n const existingLoggerOutput = gdjs.Logger.getLoggerOutput();\n gdjs.Logger.setLoggerOutput({\n log: (\n group: string,\n message: string,\n type: 'info' | 'warning' | 'error' = 'info',\n internal = true\n ) => {\n existingLoggerOutput.log(group, message, type, internal);\n this.log(group, message, type, internal);\n },\n });\n }\n\n /**\n * Should be called by derived class to handle a command\n * received from the debugger server.\n *\n * @param data An object containing the command to do.\n */\n protected handleCommand(data: any) {\n const that = this;\n const runtimeGame = this._runtimegame;\n if (!data || !data.command) {\n // Not a command that's meant to be handled by the debugger, return silently to\n // avoid polluting the console.\n return;\n }\n\n if (data.command === 'play') {\n runtimeGame.pause(false);\n } else if (data.command === 'pause') {\n runtimeGame.pause(true);\n that.sendRuntimeGameDump();\n } else if (data.command === 'refresh') {\n that.sendRuntimeGameDump();\n } else if (data.command === 'set') {\n that.set(data.path, data.newValue);\n } else if (data.command === 'call') {\n that.call(data.path, data.args);\n } else if (data.command === 'profiler.start') {\n runtimeGame.startCurrentSceneProfiler(function (stoppedProfiler) {\n that.sendProfilerOutput(\n stoppedProfiler.getFramesAverageMeasures(),\n stoppedProfiler.getStats()\n );\n that.sendProfilerStopped();\n });\n that.sendProfilerStarted();\n } else if (data.command === 'profiler.stop') {\n runtimeGame.stopCurrentSceneProfiler();\n } else if (data.command === 'hotReload') {\n that._hotReloader.hotReload().then((logs) => {\n that.sendHotReloaderLogs(logs);\n });\n } else {\n logger.info(\n 'Unknown command \"' + data.command + '\" received by the debugger.'\n );\n }\n }\n\n /**\n * Should be re-implemented by derived class to send a stringified message object\n * to the debugger server.\n * @param message\n */\n protected abstract _sendMessage(message: string): void;\n\n static isErrorComingFromJavaScriptCode(exception: Error | null): boolean {\n if (!exception || !exception.stack) return false;\n\n return exception.stack.includes('GDJSInlineCode');\n }\n\n async _reportCrash(exception: Error) {\n const gameCrashReport = buildGameCrashReport(\n exception,\n this._runtimegame\n );\n\n // Let a debugger server know about the crash.\n this._sendMessage(\n circularSafeStringify(\n {\n command: 'game.crashed',\n payload: gameCrashReport,\n },\n errorReplacer\n )\n );\n\n // Send the report to the APIs, if allowed.\n if (\n !this._runtimegame.getAdditionalOptions().crashReportUploadLevel ||\n this._runtimegame.getAdditionalOptions().crashReportUploadLevel ===\n 'none' ||\n (this._runtimegame.getAdditionalOptions().crashReportUploadLevel ===\n 'exclude-javascript-code-events' &&\n AbstractDebuggerClient.isErrorComingFromJavaScriptCode(exception))\n ) {\n return;\n }\n\n const rootApi = this._runtimegame.isUsingGDevelopDevelopmentEnvironment()\n ? 'https://api-dev.gdevelop.io'\n : 'https://api.gdevelop.io';\n const baseUrl = `${rootApi}/analytics`;\n\n try {\n await fetch(`${baseUrl}/game-crash-report`, {\n body: circularSafeStringify(gameCrashReport, errorReplacer),\n method: 'POST',\n });\n } catch (error) {\n logger.error('Error while sending the crash report:', error);\n }\n }\n\n onUncaughtException(exception: Error): void {\n logger.error('Uncaught exception: ' + exception);\n\n this._inGameDebugger.setUncaughtException(exception);\n\n if (!this._hasLoggedUncaughtException) {\n // Only log an uncaught exception once, to avoid spamming the debugger server\n // in case of an exception at each frame.\n this._hasLoggedUncaughtException = true;\n\n this._reportCrash(exception);\n }\n }\n\n /**\n * Send a message (a log) to debugger server.\n */\n log(\n group: string,\n message: string,\n type: 'info' | 'warning' | 'error',\n internal: boolean\n ) {\n this._sendMessage(\n JSON.stringify({\n command: 'console.log',\n payload: {\n message,\n type,\n group,\n internal,\n timestamp: performance.now(),\n },\n })\n );\n }\n\n /**\n * Update a value, specified by a path starting from the {@link RuntimeGame} instance.\n * @param path - The path to the variable, starting from {@link RuntimeGame}.\n * @param newValue - The new value.\n * @return Was the operation successful?\n */\n set(path: string[], newValue: any): boolean {\n if (!path || !path.length) {\n logger.warn('No path specified, set operation from debugger aborted');\n return false;\n }\n let object = this._runtimegame;\n let currentIndex = 0;\n while (currentIndex < path.length - 1) {\n const key = path[currentIndex];\n if (!object || !object[key]) {\n logger.error('Incorrect path specified. No ' + key + ' in ', object);\n return false;\n }\n object = object[key];\n currentIndex++;\n }\n\n // Ensure the newValue is properly typed to avoid breaking anything in\n // the game engine.\n const currentValue = object[path[currentIndex]];\n if (typeof currentValue === 'number') {\n newValue = parseFloat(newValue);\n } else {\n if (typeof currentValue === 'string') {\n newValue = '' + newValue;\n }\n }\n logger.log('Updating', path, 'to', newValue);\n object[path[currentIndex]] = newValue;\n return true;\n }\n\n /**\n * Call a method, specified by a path starting from the {@link RuntimeGame} instance.\n * @param path - The path to the method, starting from {@link RuntimeGame}.\n * @param args - The arguments to pass the method.\n * @return Was the operation successful?\n */\n call(path: string[], args: any[]): boolean {\n if (!path || !path.length) {\n logger.warn('No path specified, call operation from debugger aborted');\n return false;\n }\n let object = this._runtimegame;\n let currentIndex = 0;\n while (currentIndex < path.length - 1) {\n const key = path[currentIndex];\n if (!object || !object[key]) {\n logger.error('Incorrect path specified. No ' + key + ' in ', object);\n return false;\n }\n object = object[key];\n currentIndex++;\n }\n if (!object[path[currentIndex]]) {\n logger.error('Unable to call', path);\n return false;\n }\n logger.log('Calling', path, 'with', args);\n object[path[currentIndex]].apply(object, args);\n return true;\n }\n\n /**\n * Dump all the relevant data from the {@link RuntimeGame} instance and send it to the server.\n */\n sendRuntimeGameDump(): void {\n const that = this;\n const message = { command: 'dump', payload: this._runtimegame };\n const serializationStartTime = Date.now();\n\n // Stringify the message, excluding some known data that are big and/or not\n // useful for the debugger.\n const excludedValues = [that._runtimegame.getGameData()];\n const excludedKeys = [\n // Exclude reference to the debugger\n '_debuggerClient',\n // Exclude some RuntimeScene fields:\n '_allInstancesList',\n // Exclude circular references to parent runtimeGame or runtimeScene:\n '_runtimeGame',\n '_runtimeScene',\n // Exclude some runtimeObject duplicated data:\n '_behaviorsTable',\n // Exclude some objects data:\n '_animations',\n '_animationFrame',\n // Exclude linked objects to avoid too much repetitions:\n 'linkedObjectsManager',\n // Could be improved by using private fields and excluding these (_)\n // Exclude some behaviors data:\n '_platformRBush',\n // PlatformBehavior\n 'HSHG',\n // Pathfinding\n '_obstaclesHSHG',\n // Pathfinding\n 'owner',\n // Avoid circular reference from behavior to parent runtimeObject\n // Exclude rendering related objects:\n '_renderer',\n '_gameRenderer',\n '_imageManager',\n '_rendererEffects',\n // Exclude PIXI textures:\n 'baseTexture',\n '_baseTexture',\n '_invalidTexture',\n ];\n const stringifiedMessage = circularSafeStringify(\n message,\n function (key, value) {\n if (\n excludedValues.indexOf(value) !== -1 ||\n excludedKeys.indexOf(key) !== -1\n ) {\n return '[Removed from the debugger]';\n }\n return value;\n },\n /* Limit maximum depth to prevent any crashes */\n 18\n );\n const serializationDuration = Date.now() - serializationStartTime;\n logger.log(\n 'RuntimeGame serialization took ' + serializationDuration + 'ms'\n );\n if (serializationDuration > 500) {\n logger.warn(\n 'Serialization took a long time: please check if there is a need to remove some objects from serialization'\n );\n }\n this._sendMessage(stringifiedMessage);\n }\n\n /**\n * Send logs from the hot reloader to the server.\n * @param logs The hot reloader logs.\n */\n sendHotReloaderLogs(logs: HotReloaderLog[]): void {\n this._sendMessage(\n circularSafeStringify({\n command: 'hotReloader.logs',\n payload: logs,\n })\n );\n }\n\n /**\n * Callback called when profiling is starting.\n */\n sendProfilerStarted(): void {\n this._sendMessage(\n circularSafeStringify({\n command: 'profiler.started',\n payload: null,\n })\n );\n }\n\n /**\n * Callback called when profiling is ending.\n */\n sendProfilerStopped(): void {\n this._sendMessage(\n circularSafeStringify({\n command: 'profiler.stopped',\n payload: null,\n })\n );\n }\n\n /**\n * Callback called when the game is paused.\n */\n sendGamePaused(): void {\n this._sendMessage(\n circularSafeStringify({\n command: 'game.paused',\n payload: null,\n })\n );\n }\n\n /**\n * Callback called when the game is resumed.\n */\n sendGameResumed(): void {\n this._sendMessage(\n circularSafeStringify({\n command: 'game.resumed',\n payload: null,\n })\n );\n }\n\n /**\n * Send profiling results.\n * @param framesAverageMeasures The measures made for each frames.\n * @param stats Other measures done during the profiler run.\n */\n sendProfilerOutput(\n framesAverageMeasures: FrameMeasure,\n stats: ProfilerStats\n ): void {\n this._sendMessage(\n circularSafeStringify({\n command: 'profiler.output',\n payload: {\n framesAverageMeasures: framesAverageMeasures,\n stats: stats,\n },\n })\n );\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,2 +1,3 @@
1
- var gdjs;(function(d){const u=new d.Logger("Hot reloader");class m{constructor(o){this._reloadedScriptElement={};this._logs=[];this._alreadyLoadedScriptFiles={};this._runtimeGame=o}static groupByPersistentUuid(o){return o.reduce(function(e,r){return r.persistentUuid&&(e[r.persistentUuid]=r),e},{})}_canReloadScriptFile(o){function e(r,t){const i=r.indexOf(t);return i!==-1&&i===r.length-t.length}return!(e(o,".h")||this._alreadyLoadedScriptFiles[o]&&(e(o,"box2d.js")||e(o,"sha256.js")||e(o,"shopify-buy.umd.polyfilled.min.js")||e(o,"pixi-multistyle-text.umd.js")||e(o,"pixi-tilemap.umd.js")||e(o,"bondage.min.js")||e(o,"pixi-particles-pixi-renderer.min.js")||e(o,"pixi-tilemap.umd.js")||e(o,"pixi-tilemap-helper.js")||e(o,"pako/dist/pako.min")))}_reloadScript(o){function e(t,i){const a=t.indexOf(i);return a!==-1&&a===t.length-i.length}if(!this._canReloadScriptFile(o))return this._logs.push({kind:"info",message:"Not reloading "+o+" as it is blocked for hot-reloading."}),Promise.resolve();const r=document.getElementsByTagName("head")[0];return r?new Promise((t,i)=>{const a=this._reloadedScriptElement[o];if(a)r.removeChild(a);else{const n=r.getElementsByTagName("script");for(let h=0;h<n.length;++h){const l=n[h];e(l.src,o)&&r.removeChild(l)}}const s=document.createElement("script");s.src=o+"?timestamp="+Date.now(),s.onload=()=>{t()},s.onerror=n=>{i(n)},r.appendChild(s),this._reloadedScriptElement[o]=s}):Promise.reject(new Error("No head element found, are you in a navigator?"))}hotReload(){u.info("Hot reload started"),this._runtimeGame.pause(!0),this._logs=[];const o=d.projectData,e=d.runtimeGameOptions.scriptFiles;e.forEach(t=>{this._alreadyLoadedScriptFiles[t.path]=!0});const r={};for(let t in d.behaviorsTypes.items)r[t]=d.behaviorsTypes.items[t];return this._reloadScript("data.js").then(()=>{const t=d.projectData,i=d.runtimeGameOptions,a=i.scriptFiles,s=!!i.projectDataOnlyExport;return this.reloadScriptFiles(t,e,a,s).then(()=>{const n=this._computeChangedRuntimeBehaviors(r,d.behaviorsTypes.items);return this._hotReloadRuntimeGame(o,t,n,this._runtimeGame)}).catch(n=>{const h=n.target;h instanceof HTMLScriptElement?this._logs.push({kind:"fatal",message:"Unable to reload script:"+h.src}):this._logs.push({kind:"fatal",message:"Unexpected error happened while hot-reloading:"+n.message})}).then(()=>(u.info("Hot reload finished with logs:",this._logs),this._runtimeGame.pause(!1),this._logs))})}_computeChangedRuntimeBehaviors(o,e){const r=[];for(let t in o){const i=o[t],a=e[t];a?i!==a&&(this._logs.push({kind:"info",message:"Behavior with type "+t+" was changed, and will be re-instantiated in gdjs.RuntimeObjects using it."}),r.push({oldBehaviorConstructor:i,newBehaviorConstructor:a,behaviorTypeName:t})):this._logs.push({kind:"warning",message:"Behavior with type "+t+" was removed from the registered behaviors in gdjs."})}return r}reloadScriptFiles(o,e,r,t){const i=[];t||o.layouts.forEach((a,s)=>{i.push(this._reloadScript("code"+s+".js"))});for(let a=0;a<r.length;++a){const s=r[a],n=e.filter(h=>h.path===s.path)[0];n?s.hash!==n.hash&&(this._logs.push({kind:"info",message:"Reloading "+s.path+" because it was changed."}),i.push(this._reloadScript(s.path))):(this._logs.push({kind:"info",message:"Loading "+s.path+" as it was added to the list of scripts."}),i.push(this._reloadScript(s.path)))}for(let a=0;a<e.length;++a){const s=e[a];!r.filter(h=>h.path===s.path)[0]&&!t&&this._logs.push({kind:"warning",message:"Script file "+s.path+" was removed."})}return Promise.all(i)}async _hotReloadRuntimeGame(o,e,r,t){const i=t.getSceneStack(),a=i.getCurrentScene();if(!a){this._logs.push({kind:"error",message:"Can't hot-reload as no scene are opened."});return}t.setProjectData(e),await t.loadFirstAssetsAndStartBackgroundLoading(a.getName(),()=>{}),this._hotReloadVariablesContainer(o.variables,e.variables,t.getVariables()),i._stack.forEach(s=>{const n=o.layouts.filter(l=>l.name===s.getName())[0],h=e.layouts.filter(l=>l.name===s.getName())[0];n&&h?this._hotReloadRuntimeScene(n,h,r,s):this._logs.push({kind:"error",message:"Scene "+n.name+" was removed. A fresh preview should be launched."})}),e.externalLayouts.forEach(s=>{const n=o.externalLayouts.filter(h=>h.name===s.name)[0];n&&!m.deepEqual(n,s)&&i._stack.forEach(h=>{this._hotReloadRuntimeSceneInstances(n.instances,s.instances,h)})})}_hotReloadVariablesContainer(o,e,r){e.forEach(t=>{const i=t.name,a=o.find(n=>n.name===i),s=r.get(t.name);a?d.Variable.isPrimitive(t.type||"number")&&(a.value!==t.value||!d.Variable.isPrimitive(a.type||"number"))?(r.remove(i),r.add(i,new d.Variable(t))):d.Variable.isPrimitive(t.type||"number")||(t.type==="structure"?this._hotReloadStructureVariable(a.children,t.children,s):(r.remove(i),r.add(i,new d.Variable(t)))):r.add(i,new d.Variable(t))}),o.forEach(t=>{e.find(a=>a.name===t.name)||r.remove(t.name)})}_hotReloadStructureVariable(o,e,r){o?(o.forEach(t=>{const i=e.find(a=>a.name===t.name);i?d.Variable.isPrimitive(i.type||"number")&&(t.value!==i.value||!d.Variable.isPrimitive(t.type||"number"))?r.addChild(i.name,new d.Variable(i)):d.Variable.isPrimitive(i.type||"number")||(i.type==="structure"?this._hotReloadStructureVariable(t.children,i.children,r.getChild(i.name)):r.addChild(i.name,new d.Variable(i))):r.removeChild(t.name)}),e.forEach(t=>{o.find(a=>a.name===t.name)||r.addChild(t.name,new d.Variable(t))})):e.forEach(t=>{r.addChild(t.name,new d.Variable(t))})}_hotReloadRuntimeScene(o,e,r,t){t.setBackgroundColor(e.r,e.v,e.b),o.title!==e.title&&t.getGame().getRenderer().setWindowTitle(e.title),this._hotReloadVariablesContainer(o.variables,e.variables,t.getVariables()),this._hotReloadRuntimeSceneBehaviorsSharedData(o.behaviorsSharedData,e.behaviorsSharedData,t),this._reinstantiateRuntimeSceneRuntimeBehaviors(r,e.objects,t),this._hotReloadRuntimeSceneObjects(o.objects,e.objects,t),this._hotReloadRuntimeSceneInstances(o.instances,e.instances,t),this._hotReloadRuntimeSceneLayers(o.layers,e.layers,t),t.setEventsGeneratedCodeFunction(e)}_hotReloadRuntimeSceneBehaviorsSharedData(o,e,r){o.forEach(t=>{const i=t.name,a=e.filter(s=>s.name===i)[0];a?m.deepEqual(t,a)||r.setInitialSharedDataForBehavior(a.name,a):r.setInitialSharedDataForBehavior(t.name,null)}),e.forEach(t=>{const i=t.name;o.filter(s=>s.name===i)[0]||r.setInitialSharedDataForBehavior(t.name,t)})}_reinstantiateRuntimeSceneRuntimeBehaviors(o,e,r){e.forEach(t=>{const i=t.name,a=t.behaviors,s=r.getObjects(i);o.forEach(n=>{const h=n.behaviorTypeName;a.filter(l=>l.type===h).forEach(l=>{const f=l.name;this._logs.push({kind:"info",message:'Re-instantiating behavior named "'+f+'" for instances of object "'+i+'".'}),s.forEach(c=>{this._reinstantiateRuntimeObjectRuntimeBehavior(l,c)})})})})}_reinstantiateRuntimeObjectRuntimeBehavior(o,e){const r=o.name,t=e.getBehavior(r);if(!t)return;e.removeBehavior(r),e.addNewBehavior(o);const i=e.getBehavior(r);if(!i){this._logs.push({kind:"error",message:"Could not create behavior "+r+" (type: "+o.type+") for object "+e.getName()});return}for(let a in t)if(!!t.hasOwnProperty(a))if(a==="_behaviorData"){i[a]=i[a]||{};for(let s in t[a])i[a][s]=t[a][s]}else i[a]=t[a]}_hotReloadRuntimeSceneObjects(o,e,r){o.forEach(t=>{const i=t.name,a=e.filter(s=>s.name===i)[0];!a||t.type!==a.type?r.unregisterObject(i):r.isObjectRegistered(i)&&this._hotReloadRuntimeSceneObject(t,a,r)}),e.forEach(t=>{const i=t.name,a=o.filter(s=>s.name===i)[0];(!a||a.type!==t.type)&&!r.isObjectRegistered(i)&&r.registerObject(t)})}_hotReloadRuntimeSceneObject(o,e,r){let t=!0;if(!m.deepEqual(o,e)){this._logs.push({kind:"info",message:'Object "'+e.name+'" was modified and is hot-reloaded.'}),r.updateObject(e);const i=r.getObjects(e.name);i.forEach(a=>{t=a.updateFromObjectData(o,e)&&t}),i.forEach(a=>{this._hotReloadVariablesContainer(o.variables,e.variables,a.getVariables())}),this._hotReloadRuntimeObjectsBehaviors(o.behaviors,e.behaviors,i),this._hotReloadRuntimeObjectsEffects(o.effects,e.effects,i)}t||this._logs.push({kind:"error",message:'Object "'+e.name+'" could not be hot-reloaded. A fresh preview should be run.'})}_hotReloadRuntimeObjectsBehaviors(o,e,r){o.forEach(t=>{const i=t.name,a=e.filter(s=>s.name===i)[0];if(!a)r.forEach(s=>{s.hasBehavior(i)&&(s.removeBehavior(i)||this._logs.push({kind:"error",message:"Behavior "+i+" could not be removed from object"+s.getName()}))});else if(!m.deepEqual(t,a)){let s=!0;r.forEach(n=>{const h=n.getBehavior(a.name);h&&(s=this._hotReloadRuntimeBehavior(t,a,h)&&s)}),s||this._logs.push({kind:"error",message:a.name+" behavior could not be hot-reloaded."})}}),e.forEach(t=>{const i=t.name;if(!o.filter(s=>s.name===i)[0]){let s=!0;r.forEach(n=>{s=n.addNewBehavior(t)&&s}),s||this._logs.push({kind:"error",message:t.name+" behavior could not be added during hot-reload."})}})}_hotReloadRuntimeObjectsEffects(o,e,r){o.forEach(t=>{const i=t.name,a=e.filter(s=>s.name===i)[0];if(!a)r.forEach(s=>{s.hasEffect(i)&&(s.removeEffect(i)||this._logs.push({kind:"error",message:"Effect "+i+" could not be removed from object"+s.getName()}))});else if(!m.deepEqual(t,a)){let s=!0;r.forEach(n=>{t.effectType===a.effectType?s=n.updateAllEffectParameters(a)&&s:(n.removeEffect(t.name),n.addEffect(a))}),s||this._logs.push({kind:"error",message:a.name+" effect could not be hot-reloaded."})}}),e.forEach(t=>{const i=t.name;if(!o.filter(s=>s.name===i)[0]){let s=!0;r.forEach(n=>{s=n.addEffect(t)&&s}),s||this._logs.push({kind:"error",message:t.name+" effect could not be added during hot-reload."})}})}_hotReloadRuntimeBehavior(o,e,r){return r.updateFromBehaviorData(o,e)}_hotReloadRuntimeSceneLayers(o,e,r){o.forEach(t=>{const i=t.name,a=e.filter(s=>s.name===i)[0];if(!a)r.removeLayer(i);else if(r.hasLayer(i)){const s=r.getLayer(i);this._hotReloadRuntimeLayer(t,a,s)}}),e.forEach(t=>{const i=t.name;!o.filter(s=>s.name===i)[0]&&!r.hasLayer(i)&&r.addLayer(t)}),e.forEach((t,i)=>{r.setLayerIndex(t.name,i)})}_hotReloadRuntimeLayer(o,e,r){o.visibility!==e.visibility&&r.show(e.visibility),e.isLightingLayer&&((o.ambientLightColorR!==e.ambientLightColorR||o.ambientLightColorG!==e.ambientLightColorG||o.ambientLightColorB!==e.ambientLightColorB)&&r.setClearColor(e.ambientLightColorR,e.ambientLightColorG,e.ambientLightColorB),o.followBaseLayerCamera!==e.followBaseLayerCamera&&r.setFollowBaseLayerCamera(e.followBaseLayerCamera)),o.renderingType!==e.renderingType&&this._logs.push({kind:"error",message:`Could not change the rendering type (2D, 3D...) layer at runtime (for layer "${e.name}").`}),e.isLightingLayer!==o.isLightingLayer&&this._logs.push({kind:"error",message:`Could not add/remove a lighting layer at runtime (for layer "${e.name}").`}),this._hotReloadRuntimeLayerEffects(o.effects,e.effects,r)}_hotReloadRuntimeLayerEffects(o,e,r){o.forEach(t=>{const i=t.name,a=e.filter(s=>s.name===i)[0];a?r.hasEffect(i)&&(t.effectType!==a.effectType?(r.removeEffect(i),r.addEffect(a)):this._hotReloadRuntimeLayerEffect(t,a,r,i)):r.removeEffect(i)}),e.forEach(t=>{const i=t.name;!o.filter(s=>s.name===i)[0]&&!r.hasEffect(i)&&r.addEffect(t)})}_hotReloadRuntimeLayerEffect(o,e,r,t){for(let i in e.booleanParameters){const a=e.booleanParameters[i];a!==o.booleanParameters[i]&&r.setEffectBooleanParameter(t,i,a)}for(let i in e.doubleParameters){const a=e.doubleParameters[i];a!==o.doubleParameters[i]&&r.setEffectDoubleParameter(t,i,a)}for(let i in e.stringParameters){const a=e.stringParameters[i];a!==o.stringParameters[i]&&r.setEffectStringParameter(t,i,a)}}_hotReloadRuntimeSceneInstances(o,e,r){const t=r.getAdhocListOfAllInstances(),i=m.groupByPersistentUuid(o),a=m.groupByPersistentUuid(e),s=m.groupByPersistentUuid(t);for(let n in i){const h=i[n],l=a[n],f=s[n];h&&(!l||h.name!==l.name)?f&&f.deleteFromScene(r):h&&l&&f&&this._hotReloadRuntimeInstance(h,l,f)}for(let n in a){const h=i[n],l=a[n],f=s[n];l&&(!h||h.name!==l.name)&&!f&&r.createObjectsFrom([l],0,0,0,!0)}}_hotReloadRuntimeInstance(o,e,r){let t=!1;o.x!==e.x&&(r.setX(e.x),t=!0),o.y!==e.y&&(r.setY(e.y),t=!0),o.angle!==e.angle&&(r.setAngle(e.angle),t=!0),o.zOrder!==e.zOrder&&(r.setZOrder(e.zOrder),t=!0),o.layer!==e.layer&&(r.setLayer(e.layer),t=!0),d.Base3DHandler&&d.Base3DHandler.is3D(r)&&(o.z!==e.z&&e.z!==void 0&&(r.setZ(e.z),t=!0),o.rotationX!==e.rotationX&&e.rotationX!==void 0&&(r.setRotationX(e.rotationX),t=!0),o.rotationY!==e.rotationY&&e.rotationY!==void 0&&(r.setRotationY(e.rotationY),t=!0));let i=!1;e.customSize?o.customSize?(o.width!==e.width&&(r.setWidth(e.width),t=!0,i=!0),o.height!==e.height&&(r.setHeight(e.height),t=!0,i=!0)):(r.setWidth(e.width),r.setHeight(e.height),t=!0,i=!0):!e.customSize&&o.customSize&&(i=!0),d.Base3DHandler&&d.Base3DHandler.is3D(r)&&(o.depth!==e.depth&&e.depth!==void 0?(r.setDepth(e.depth),t=!0,i=!0):e.depth===void 0&&o.depth!==void 0&&(i=!0)),this._hotReloadVariablesContainer(o.initialVariables,e.initialVariables,r.getVariables());const a=e.numberProperties.some(n=>{const h=n.name,l=n.value,f=o.numberProperties.filter(c=>c.name===h)[0];return!f||f.value!==l}),s=e.stringProperties.some(n=>{const h=n.name,l=n.value,f=o.stringProperties.filter(c=>c.name===h)[0];return!f||f.value!==l});(a||s||i)&&(r.extraInitializationFromInitialInstance(e),t=!0),t&&r.notifyBehaviorsObjectHotReloaded()}static deepEqual(o,e){if(o===e)return!0;if(o&&e&&typeof o=="object"&&typeof e=="object"){if(o.constructor!==e.constructor)return!1;let r,t,i;if(Array.isArray(o)){if(r=o.length,r!=e.length)return!1;for(t=r;t--!=0;)if(!m.deepEqual(o[t],e[t]))return!1;return!0}if(o.valueOf!==Object.prototype.valueOf)return o.valueOf()===e.valueOf();if(o.toString!==Object.prototype.toString)return o.toString()===e.toString();if(i=Object.keys(o),r=i.length,r!==Object.keys(e).length)return!1;for(t=r;t--!=0;)if(!Object.prototype.hasOwnProperty.call(e,i[t]))return!1;for(t=r;t--!=0;){const a=i[t];if(!m.deepEqual(o[a],e[a]))return!1}return!0}return o!==o&&e!==e}}d.HotReloader=m})(gdjs||(gdjs={}));
1
+ var gdjs;(function(d){const y=new d.Logger("Hot reloader");class p{constructor(r){this._reloadedScriptElement={};this._logs=[];this._alreadyLoadedScriptFiles={};this._runtimeGame=r}static groupByPersistentUuid(r){return r.reduce(function(i,a){return a.persistentUuid&&(i[a.persistentUuid]=a),i},{})}static indexByName(r){return r.reduce(function(i,a){return a.name&&i.set(a.name,a),i},new Map)}_canReloadScriptFile(r){function i(a,e){const o=a.indexOf(e);return o!==-1&&o===a.length-e.length}return!(i(r,".h")||this._alreadyLoadedScriptFiles[r]&&(i(r,"box2d.js")||i(r,"sha256.js")||i(r,"shopify-buy.umd.polyfilled.min.js")||i(r,"pixi-multistyle-text.umd.js")||i(r,"pixi-tilemap.umd.js")||i(r,"bondage.min.js")||i(r,"pixi-particles-pixi-renderer.min.js")||i(r,"pixi-tilemap.umd.js")||i(r,"pixi-tilemap-helper.js")||i(r,"pako/dist/pako.min")))}_reloadScript(r){function i(e,o){const t=e.indexOf(o);return t!==-1&&t===e.length-o.length}if(!this._canReloadScriptFile(r))return this._logs.push({kind:"info",message:"Not reloading "+r+" as it is blocked for hot-reloading."}),Promise.resolve();const a=document.getElementsByTagName("head")[0];return a?new Promise((e,o)=>{const t=this._reloadedScriptElement[r];if(t)a.removeChild(t);else{const n=a.getElementsByTagName("script");for(let h=0;h<n.length;++h){const l=n[h];i(l.src,r)&&a.removeChild(l)}}const s=document.createElement("script");s.src=r+"?timestamp="+Date.now(),s.onload=()=>{e()},s.onerror=n=>{o(n)},a.appendChild(s),this._reloadedScriptElement[r]=s}):Promise.reject(new Error("No head element found, are you in a navigator?"))}hotReload(){y.info("Hot reload started"),this._runtimeGame.pause(!0),this._logs=[];const r=d.projectData,i=d.runtimeGameOptions.scriptFiles;i.forEach(e=>{this._alreadyLoadedScriptFiles[e.path]=!0});const a={};for(let e in d.behaviorsTypes.items)a[e]=d.behaviorsTypes.items[e];return this._reloadScript("data.js").then(()=>{const e=d.projectData,o=d.runtimeGameOptions,t=o.scriptFiles,s=!!o.projectDataOnlyExport;return this.reloadScriptFiles(e,i,t,s).then(()=>{const n=this._computeChangedRuntimeBehaviors(a,d.behaviorsTypes.items);return this._hotReloadRuntimeGame(r,e,n,this._runtimeGame)}).catch(n=>{const h=n.target;h instanceof HTMLScriptElement?this._logs.push({kind:"fatal",message:"Unable to reload script: "+h.src}):this._logs.push({kind:"fatal",message:"Unexpected error happened while hot-reloading: "+n.message})}).then(()=>(y.info("Hot reload finished with logs:",this._logs.map(n=>`
2
+ `+n.kind+": "+n.message)),this._runtimeGame.pause(!1),this._logs))})}_computeChangedRuntimeBehaviors(r,i){const a=[];for(let e in r){const o=r[e],t=i[e];t?o!==t&&(this._logs.push({kind:"info",message:"Behavior with type "+e+" was changed, and will be re-instantiated in gdjs.RuntimeObjects using it."}),a.push({oldBehaviorConstructor:o,newBehaviorConstructor:t,behaviorTypeName:e})):this._logs.push({kind:"warning",message:"Behavior with type "+e+" was removed from the registered behaviors in gdjs."})}return a}reloadScriptFiles(r,i,a,e){const o=[];e||r.layouts.forEach((t,s)=>{o.push(this._reloadScript("code"+s+".js"))});for(let t=0;t<a.length;++t){const s=a[t],n=i.filter(h=>h.path===s.path)[0];n?s.hash!==n.hash&&(this._logs.push({kind:"info",message:"Reloading "+s.path+" because it was changed."}),o.push(this._reloadScript(s.path))):(this._logs.push({kind:"info",message:"Loading "+s.path+" as it was added to the list of scripts."}),o.push(this._reloadScript(s.path)))}for(let t=0;t<i.length;++t){const s=i[t];!a.filter(h=>h.path===s.path)[0]&&!e&&this._logs.push({kind:"warning",message:"Script file "+s.path+" was removed."})}return Promise.all(o)}async _hotReloadRuntimeGame(r,i,a,e){const o=e.getSceneStack(),t=o.getCurrentScene();if(!t){this._logs.push({kind:"error",message:"Can't hot-reload as no scene are opened."});return}e.setProjectData(i),await e.loadFirstAssetsAndStartBackgroundLoading(t.getName(),()=>{}),this._hotReloadVariablesContainer(r.variables,i.variables,e.getVariables());for(const h of i.eventsFunctionsExtensions){const l=r.eventsFunctionsExtensions.find(g=>g.name===h.name),c=l?l.globalVariables:[],u=h.globalVariables;if(c.length>0||u.length>0){const g=e.getVariablesForExtension(h.name);g?this._hotReloadVariablesContainer(c,u,g):e._variablesByExtensionName.set(h.name,new d.VariablesContainer(u))}}const s=p.indexByName(r.layouts),n=p.indexByName(i.layouts);o._stack.forEach(h=>{const l=s.get(h.getName()),c=n.get(h.getName());if(l&&c){this._hotReloadRuntimeScene(r,i,l,c,a,h);for(const u of i.eventsFunctionsExtensions){const g=r.eventsFunctionsExtensions.find(f=>f.name===u.name),b=g?g.sceneVariables:[],m=u.sceneVariables;if(b.length>0||m.length>0){const f=h.getVariablesForExtension(u.name);f?this._hotReloadVariablesContainer(b,m,f):h._variablesByExtensionName.set(u.name,new d.VariablesContainer(m))}}}else this._logs.push({kind:"error",message:"Scene "+(l&&l.name)+" was removed. A fresh preview should be launched."})}),i.externalLayouts.forEach(h=>{const l=r.externalLayouts.filter(c=>c.name===h.name)[0];if(l&&!p.deepEqual(l,h)){const c=s.get(l.associatedLayout),u=n.get(h.associatedLayout);o._stack.forEach(g=>{this._hotReloadRuntimeSceneInstances(r,i,a,c?c.objects:[],u?u.objects:[],l.instances,h.instances,g)})}})}_hotReloadVariablesContainer(r,i,a){i.forEach(e=>{const o=e.name,t=r.find(n=>n.name===o),s=a.get(e.name);t?d.Variable.isPrimitive(e.type||"number")&&(t.value!==e.value||!d.Variable.isPrimitive(t.type||"number"))?(a.remove(o),a.add(o,new d.Variable(e))):d.Variable.isPrimitive(e.type||"number")||(e.type==="structure"?this._hotReloadStructureVariable(t.children,e.children,s):(a.remove(o),a.add(o,new d.Variable(e)))):a.add(o,new d.Variable(e))}),r.forEach(e=>{i.find(t=>t.name===e.name)||a.remove(e.name)}),a.rebuildIndexFrom(i)}_hotReloadStructureVariable(r,i,a){r?(r.forEach(e=>{const o=i.find(t=>t.name===e.name);o?d.Variable.isPrimitive(o.type||"number")&&(e.value!==o.value||!d.Variable.isPrimitive(e.type||"number"))?a.addChild(o.name,new d.Variable(o)):d.Variable.isPrimitive(o.type||"number")||(o.type==="structure"?this._hotReloadStructureVariable(e.children,o.children,a.getChild(o.name)):a.addChild(o.name,new d.Variable(o))):a.removeChild(e.name)}),i.forEach(e=>{r.find(t=>t.name===e.name)||a.addChild(e.name,new d.Variable(e))})):i.forEach(e=>{a.addChild(e.name,new d.Variable(e))})}_hotReloadRuntimeScene(r,i,a,e,o,t){t.setBackgroundColor(e.r,e.v,e.b),a.title!==e.title&&t.getGame().getRenderer().setWindowTitle(e.title),this._hotReloadVariablesContainer(a.variables,e.variables,t.getVariables()),this._hotReloadRuntimeSceneBehaviorsSharedData(a.behaviorsSharedData,e.behaviorsSharedData,t),this._hotReloadRuntimeInstanceContainer(r,i,a,e,o,t),t.setEventsGeneratedCodeFunction(e)}static resolveCustomObjectConfigurations(r,i){return i.map(a=>{const[e,o]=a.type.split("::"),t=r.eventsFunctionsExtensions.find(c=>c.name===e);if(!t)return a;const s=t&&t.eventsBasedObjects.find(c=>c.name===o);if(!s)return a;const n=a,h=n.childrenContent?s.objects.map(c=>({...c,...n.childrenContent[c.name]})):s.objects;return{...s,...a,objects:h,childrenContent:h}})}_hotReloadRuntimeInstanceContainer(r,i,a,e,o,t){const s=p.resolveCustomObjectConfigurations(r,a.objects),n=p.resolveCustomObjectConfigurations(i,e.objects);this._reinstantiateRuntimeSceneRuntimeBehaviors(o,n,t),this._hotReloadRuntimeSceneObjects(s,n,t),this._hotReloadRuntimeSceneInstances(r,i,o,s,n,a.instances,e.instances,t),this._hotReloadRuntimeSceneLayers(a.layers,e.layers,t)}_hotReloadRuntimeSceneBehaviorsSharedData(r,i,a){r.forEach(e=>{const o=e.name,t=i.filter(s=>s.name===o)[0];t?p.deepEqual(e,t)||a.setInitialSharedDataForBehavior(t.name,t):a.setInitialSharedDataForBehavior(e.name,null)}),i.forEach(e=>{const o=e.name;r.filter(s=>s.name===o)[0]||a.setInitialSharedDataForBehavior(e.name,e)})}_reinstantiateRuntimeSceneRuntimeBehaviors(r,i,a){i.forEach(e=>{const o=e.name,t=e.behaviors,s=a.getObjects(o);r.forEach(n=>{const h=n.behaviorTypeName;t.filter(l=>l.type===h).forEach(l=>{const c=l.name;this._logs.push({kind:"info",message:'Re-instantiating behavior named "'+c+'" for instances of object "'+o+'".'}),s.forEach(u=>{this._reinstantiateRuntimeObjectRuntimeBehavior(l,u)})})})})}_reinstantiateRuntimeObjectRuntimeBehavior(r,i){const a=r.name,e=i.getBehavior(a);if(!e)return;i.removeBehavior(a),i.addNewBehavior(r);const o=i.getBehavior(a);if(!o){this._logs.push({kind:"error",message:"Could not create behavior "+a+" (type: "+r.type+") for object "+i.getName()});return}for(let t in e)if(!!e.hasOwnProperty(t))if(t==="_behaviorData"){o[t]=o[t]||{};for(let s in e[t])o[t][s]=e[t][s]}else o[t]=e[t]}_hotReloadRuntimeSceneObjects(r,i,a){r.forEach(e=>{const o=e.name,t=i.filter(s=>s.name===o)[0];!t||e.type!==t.type?a.unregisterObject(o):a.isObjectRegistered(o)&&this._hotReloadRuntimeSceneObject(e,t,a)}),i.forEach(e=>{const o=e.name,t=r.filter(s=>s.name===o)[0];(!t||t.type!==e.type)&&!a.isObjectRegistered(o)&&a.registerObject(e)})}_hotReloadRuntimeSceneObject(r,i,a){let e=!0;if(!p.deepEqual(r,i)){this._logs.push({kind:"info",message:'Object "'+i.name+'" was modified and is hot-reloaded.'}),a.updateObject(i);const o=a.getObjects(i.name);o.forEach(t=>{e=t.updateFromObjectData(r,i)&&e}),o.forEach(t=>{this._hotReloadVariablesContainer(r.variables,i.variables,t.getVariables())}),this._hotReloadRuntimeObjectsBehaviors(r.behaviors,i.behaviors,o),this._hotReloadRuntimeObjectsEffects(r.effects,i.effects,o)}e||this._logs.push({kind:"error",message:'Object "'+i.name+'" could not be hot-reloaded. A fresh preview should be run.'})}_hotReloadRuntimeObjectsBehaviors(r,i,a){r.forEach(e=>{const o=e.name,t=i.filter(s=>s.name===o)[0];if(!t)a.forEach(s=>{s.hasBehavior(o)&&(s.removeBehavior(o)||this._logs.push({kind:"error",message:"Behavior "+o+" could not be removed from object"+s.getName()}))});else if(!p.deepEqual(e,t)){let s=!0;a.forEach(n=>{const h=n.getBehavior(t.name);h&&(s=this._hotReloadRuntimeBehavior(e,t,h)&&s)}),s||this._logs.push({kind:"error",message:t.name+" behavior could not be hot-reloaded."})}}),i.forEach(e=>{const o=e.name;if(!r.filter(s=>s.name===o)[0]){let s=!0;a.forEach(n=>{s=n.addNewBehavior(e)&&s}),s||this._logs.push({kind:"error",message:e.name+" behavior could not be added during hot-reload."})}})}_hotReloadRuntimeObjectsEffects(r,i,a){r.forEach(e=>{const o=e.name,t=i.filter(s=>s.name===o)[0];if(!t)a.forEach(s=>{s.hasEffect(o)&&(s.removeEffect(o)||this._logs.push({kind:"error",message:"Effect "+o+" could not be removed from object"+s.getName()}))});else if(!p.deepEqual(e,t)){let s=!0;a.forEach(n=>{e.effectType===t.effectType?s=n.updateAllEffectParameters(t)&&s:(n.removeEffect(e.name),n.addEffect(t))}),s||this._logs.push({kind:"error",message:t.name+" effect could not be hot-reloaded."})}}),i.forEach(e=>{const o=e.name;if(!r.filter(s=>s.name===o)[0]){let s=!0;a.forEach(n=>{s=n.addEffect(e)&&s}),s||this._logs.push({kind:"error",message:e.name+" effect could not be added during hot-reload."})}})}_hotReloadRuntimeBehavior(r,i,a){return a.updateFromBehaviorData(r,i)}_hotReloadRuntimeSceneLayers(r,i,a){r.forEach(e=>{const o=e.name,t=i.filter(s=>s.name===o)[0];if(!t)a.removeLayer(o);else if(a.hasLayer(o)){const s=a.getLayer(o);this._hotReloadRuntimeLayer(e,t,s)}}),i.forEach(e=>{const o=e.name;!r.filter(s=>s.name===o)[0]&&!a.hasLayer(o)&&a.addLayer(e)}),i.forEach((e,o)=>{a.setLayerIndex(e.name,o)})}_hotReloadRuntimeLayer(r,i,a){r.visibility!==i.visibility&&a.show(i.visibility),i.isLightingLayer&&((r.ambientLightColorR!==i.ambientLightColorR||r.ambientLightColorG!==i.ambientLightColorG||r.ambientLightColorB!==i.ambientLightColorB)&&a.setClearColor(i.ambientLightColorR,i.ambientLightColorG,i.ambientLightColorB),r.followBaseLayerCamera!==i.followBaseLayerCamera&&a.setFollowBaseLayerCamera(i.followBaseLayerCamera)),r.renderingType!==i.renderingType&&this._logs.push({kind:"error",message:`Could not change the rendering type (2D, 3D...) layer at runtime (for layer "${i.name}").`}),i.isLightingLayer!==r.isLightingLayer&&this._logs.push({kind:"error",message:`Could not add/remove a lighting layer at runtime (for layer "${i.name}").`}),this._hotReloadRuntimeLayerEffects(r.effects,i.effects,a)}_hotReloadRuntimeLayerEffects(r,i,a){r.forEach(e=>{const o=e.name,t=i.filter(s=>s.name===o)[0];t?a.hasEffect(o)&&(e.effectType!==t.effectType?(a.removeEffect(o),a.addEffect(t)):this._hotReloadRuntimeLayerEffect(e,t,a,o)):a.removeEffect(o)}),i.forEach(e=>{const o=e.name;!r.filter(s=>s.name===o)[0]&&!a.hasEffect(o)&&a.addEffect(e)})}_hotReloadRuntimeLayerEffect(r,i,a,e){for(let o in i.booleanParameters){const t=i.booleanParameters[o];t!==r.booleanParameters[o]&&a.setEffectBooleanParameter(e,o,t)}for(let o in i.doubleParameters){const t=i.doubleParameters[o];t!==r.doubleParameters[o]&&a.setEffectDoubleParameter(e,o,t)}for(let o in i.stringParameters){const t=i.stringParameters[o];t!==r.stringParameters[o]&&a.setEffectStringParameter(e,o,t)}}_hotReloadRuntimeSceneInstances(r,i,a,e,o,t,s,n){const h=n.getAdhocListOfAllInstances(),l=p.groupByPersistentUuid(t),c=p.groupByPersistentUuid(s),u=p.groupByPersistentUuid(h),g=p.indexByName(e),b=p.indexByName(o);for(const m in l){const f=l[m],R=c[m],v=u[m];f&&(!R||f.name!==R.name)&&v&&v.deleteFromScene(n)}for(const m in u){const f=u[m],R=g.get(f.getName()),v=b.get(f.getName());if(!f||!R||!v)continue;const E=l[m],_=c[m];if(E&&_)this._hotReloadRuntimeInstance(r,i,a,R,v,E,_,f);else if(f instanceof d.CustomRuntimeObject){const C=f.getChildrenContainer(),j=R,B=v;this._hotReloadRuntimeInstanceContainer(r,i,j,B,a,C)}}for(const m in c){const f=l[m],R=c[m],v=u[m];R&&(!f||f.name!==R.name)&&!v&&n.createObjectsFrom([R],0,0,0,!0)}}_hotReloadRuntimeInstance(r,i,a,e,o,t,s,n){let h=!1;t.x!==s.x&&(n.setX(s.x),h=!0),t.y!==s.y&&(n.setY(s.y),h=!0),t.angle!==s.angle&&(n.setAngle(s.angle),h=!0),t.zOrder!==s.zOrder&&(n.setZOrder(s.zOrder),h=!0),t.layer!==s.layer&&(n.setLayer(s.layer),h=!0),d.Base3DHandler&&d.Base3DHandler.is3D(n)&&(t.z!==s.z&&s.z!==void 0&&(n.setZ(s.z),h=!0),t.rotationX!==s.rotationX&&s.rotationX!==void 0&&(n.setRotationX(s.rotationX),h=!0),t.rotationY!==s.rotationY&&s.rotationY!==void 0&&(n.setRotationY(s.rotationY),h=!0));let l=!1;if(s.customSize?t.customSize?(t.width!==s.width&&(n.setWidth(s.width),h=!0,l=!0),t.height!==s.height&&(n.setHeight(s.height),h=!0,l=!0)):(n.setWidth(s.width),n.setHeight(s.height),h=!0,l=!0):!s.customSize&&t.customSize&&(l=!0),d.Base3DHandler&&d.Base3DHandler.is3D(n)&&(t.depth!==s.depth&&s.depth!==void 0?(n.setDepth(s.depth),h=!0,l=!0):s.depth===void 0&&t.depth!==void 0&&(l=!0)),n instanceof d.CustomRuntimeObject){const g=n.getChildrenContainer(),b=e,m=o;this._hotReloadRuntimeInstanceContainer(r,i,b,m,a,g)}this._hotReloadVariablesContainer(t.initialVariables,s.initialVariables,n.getVariables());const c=s.numberProperties.some(g=>{const b=g.name,m=g.value,f=t.numberProperties.filter(R=>R.name===b)[0];return!f||f.value!==m}),u=s.stringProperties.some(g=>{const b=g.name,m=g.value,f=t.stringProperties.filter(R=>R.name===b)[0];return!f||f.value!==m});(c||u||l)&&(n.extraInitializationFromInitialInstance(s),h=!0),h&&n.notifyBehaviorsObjectHotReloaded()}static deepEqual(r,i){if(r===i)return!0;if(r&&i&&typeof r=="object"&&typeof i=="object"){if(r.constructor!==i.constructor)return!1;let a,e,o;if(Array.isArray(r)){if(a=r.length,a!=i.length)return!1;for(e=a;e--!=0;)if(!p.deepEqual(r[e],i[e]))return!1;return!0}if(r.valueOf!==Object.prototype.valueOf)return r.valueOf()===i.valueOf();if(r.toString!==Object.prototype.toString)return r.toString()===i.toString();if(o=Object.keys(r),a=o.length,a!==Object.keys(i).length)return!1;for(e=a;e--!=0;)if(!Object.prototype.hasOwnProperty.call(i,o[e]))return!1;for(e=a;e--!=0;){const t=o[e];if(!p.deepEqual(r[t],i[t]))return!1}return!0}return r!==r&&i!==i}}d.HotReloader=p})(gdjs||(gdjs={}));
2
3
  //# sourceMappingURL=hot-reloader.js.map