gdcore-tools 2.0.0-beta5 → 2.0.0-beta7

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 (170) hide show
  1. package/dist/Runtime/Cordova/config.xml +4 -0
  2. package/dist/Runtime/Cordova/package.json +12 -20
  3. package/dist/Runtime/CustomRuntimeObject.js +1 -1
  4. package/dist/Runtime/CustomRuntimeObject.js.map +2 -2
  5. package/dist/Runtime/CustomRuntimeObjectInstanceContainer.js +1 -1
  6. package/dist/Runtime/CustomRuntimeObjectInstanceContainer.js.map +2 -2
  7. package/dist/Runtime/Extensions/3D/A_RuntimeObject3D.js +1 -1
  8. package/dist/Runtime/Extensions/3D/A_RuntimeObject3D.js.map +2 -2
  9. package/dist/Runtime/Extensions/3D/AmbientLight.js +1 -1
  10. package/dist/Runtime/Extensions/3D/AmbientLight.js.map +2 -2
  11. package/dist/Runtime/Extensions/3D/CustomRuntimeObject3D.js +1 -1
  12. package/dist/Runtime/Extensions/3D/CustomRuntimeObject3D.js.map +2 -2
  13. package/dist/Runtime/Extensions/3D/DirectionalLight.js +1 -1
  14. package/dist/Runtime/Extensions/3D/DirectionalLight.js.map +2 -2
  15. package/dist/Runtime/Extensions/3D/ExponentialFog.js +1 -1
  16. package/dist/Runtime/Extensions/3D/ExponentialFog.js.map +2 -2
  17. package/dist/Runtime/Extensions/3D/HemisphereLight.js +1 -1
  18. package/dist/Runtime/Extensions/3D/HemisphereLight.js.map +2 -2
  19. package/dist/Runtime/Extensions/3D/JsExtension.js +419 -228
  20. package/dist/Runtime/Extensions/3D/LinearFog.js +1 -1
  21. package/dist/Runtime/Extensions/3D/LinearFog.js.map +2 -2
  22. package/dist/Runtime/Extensions/3D/Model3DRuntimeObject.js +1 -1
  23. package/dist/Runtime/Extensions/3D/Model3DRuntimeObject.js.map +2 -2
  24. package/dist/Runtime/Extensions/AdMob/admobtools.js +1 -1
  25. package/dist/Runtime/Extensions/AdMob/admobtools.js.map +2 -2
  26. package/dist/Runtime/Extensions/AdvancedWindow/electron-advancedwindowtools.js +1 -1
  27. package/dist/Runtime/Extensions/AdvancedWindow/electron-advancedwindowtools.js.map +2 -2
  28. package/dist/Runtime/Extensions/AnchorBehavior/anchorruntimebehavior.js +1 -1
  29. package/dist/Runtime/Extensions/AnchorBehavior/anchorruntimebehavior.js.map +2 -2
  30. package/dist/Runtime/Extensions/BBText/JsExtension.js +45 -42
  31. package/dist/Runtime/Extensions/BBText/bbtextruntimeobject.js +1 -1
  32. package/dist/Runtime/Extensions/BBText/bbtextruntimeobject.js.map +2 -2
  33. package/dist/Runtime/Extensions/BitmapText/JsExtension.js +40 -49
  34. package/dist/Runtime/Extensions/BitmapText/bitmaptextruntimeobject.js +1 -1
  35. package/dist/Runtime/Extensions/BitmapText/bitmaptextruntimeobject.js.map +2 -2
  36. package/dist/Runtime/Extensions/Effects/JsExtension.js +2 -2
  37. package/dist/Runtime/Extensions/Effects/bevel-pixi-filter.js +1 -1
  38. package/dist/Runtime/Extensions/Effects/bevel-pixi-filter.js.map +2 -2
  39. package/dist/Runtime/Extensions/Effects/color-replace-pixi-filter.js +1 -1
  40. package/dist/Runtime/Extensions/Effects/color-replace-pixi-filter.js.map +2 -2
  41. package/dist/Runtime/Extensions/Effects/drop-shadow-pixi-filter.js +1 -1
  42. package/dist/Runtime/Extensions/Effects/drop-shadow-pixi-filter.js.map +2 -2
  43. package/dist/Runtime/Extensions/Effects/glow-pixi-filter.js +1 -1
  44. package/dist/Runtime/Extensions/Effects/glow-pixi-filter.js.map +2 -2
  45. package/dist/Runtime/Extensions/Effects/outline-pixi-filter.js +1 -1
  46. package/dist/Runtime/Extensions/Effects/outline-pixi-filter.js.map +2 -2
  47. package/dist/Runtime/Extensions/ExampleJsExtension/JsExtension.js +18 -21
  48. package/dist/Runtime/Extensions/Firebase/B_firebasetools/C_firebasetools.js +1 -1
  49. package/dist/Runtime/Extensions/Firebase/B_firebasetools/C_firebasetools.js.map +2 -2
  50. package/dist/Runtime/Extensions/JsExtensionTypes.d.ts +8 -2
  51. package/dist/Runtime/Extensions/Leaderboards/leaderboardstools.js +1 -1
  52. package/dist/Runtime/Extensions/Leaderboards/leaderboardstools.js.map +2 -2
  53. package/dist/Runtime/Extensions/Lighting/JsExtension.js +50 -38
  54. package/dist/Runtime/Extensions/Lighting/lightruntimeobject-pixi-renderer.js +1 -1
  55. package/dist/Runtime/Extensions/Lighting/lightruntimeobject-pixi-renderer.js.map +2 -2
  56. package/dist/Runtime/Extensions/Multiplayer/JsExtension.js +112 -7
  57. package/dist/Runtime/Extensions/Multiplayer/messageManager.js +1 -1
  58. package/dist/Runtime/Extensions/Multiplayer/messageManager.js.map +2 -2
  59. package/dist/Runtime/Extensions/Multiplayer/multiplayercomponents.js +1 -1
  60. package/dist/Runtime/Extensions/Multiplayer/multiplayercomponents.js.map +2 -2
  61. package/dist/Runtime/Extensions/Multiplayer/multiplayerobjectruntimebehavior.js +1 -1
  62. package/dist/Runtime/Extensions/Multiplayer/multiplayerobjectruntimebehavior.js.map +2 -2
  63. package/dist/Runtime/Extensions/Multiplayer/multiplayertools.js +1 -1
  64. package/dist/Runtime/Extensions/Multiplayer/multiplayertools.js.map +2 -2
  65. package/dist/Runtime/Extensions/PanelSpriteObject/panelspriteruntimeobject-pixi-renderer.js +1 -1
  66. package/dist/Runtime/Extensions/PanelSpriteObject/panelspriteruntimeobject-pixi-renderer.js.map +2 -2
  67. package/dist/Runtime/Extensions/PanelSpriteObject/panelspriteruntimeobject.js +1 -1
  68. package/dist/Runtime/Extensions/PanelSpriteObject/panelspriteruntimeobject.js.map +2 -2
  69. package/dist/Runtime/Extensions/ParticleSystem/particleemitterobject-pixi-renderer.js +1 -1
  70. package/dist/Runtime/Extensions/ParticleSystem/particleemitterobject-pixi-renderer.js.map +2 -2
  71. package/dist/Runtime/Extensions/ParticleSystem/particleemitterobject.js +1 -1
  72. package/dist/Runtime/Extensions/ParticleSystem/particleemitterobject.js.map +2 -2
  73. package/dist/Runtime/Extensions/Physics2Behavior/JsExtension.js +127 -40
  74. package/dist/Runtime/Extensions/Physics2Behavior/physics2runtimebehavior.js +1 -1
  75. package/dist/Runtime/Extensions/Physics2Behavior/physics2runtimebehavior.js.map +2 -2
  76. package/dist/Runtime/Extensions/PlayerAuthentication/playerauthenticationtools.js +1 -1
  77. package/dist/Runtime/Extensions/PlayerAuthentication/playerauthenticationtools.js.map +2 -2
  78. package/dist/Runtime/Extensions/PrimitiveDrawing/shapepainterruntimeobject.js +1 -1
  79. package/dist/Runtime/Extensions/PrimitiveDrawing/shapepainterruntimeobject.js.map +2 -2
  80. package/dist/Runtime/Extensions/Spine/JsExtension.js +77 -36
  81. package/dist/Runtime/Extensions/Spine/spineruntimeobject-pixi-renderer.js +1 -1
  82. package/dist/Runtime/Extensions/Spine/spineruntimeobject-pixi-renderer.js.map +2 -2
  83. package/dist/Runtime/Extensions/Spine/spineruntimeobject.js +1 -1
  84. package/dist/Runtime/Extensions/Spine/spineruntimeobject.js.map +2 -2
  85. package/dist/Runtime/Extensions/TextInput/JsExtension.js +55 -56
  86. package/dist/Runtime/Extensions/TextInput/textinputruntimeobject-pixi-renderer.js +1 -1
  87. package/dist/Runtime/Extensions/TextInput/textinputruntimeobject-pixi-renderer.js.map +2 -2
  88. package/dist/Runtime/Extensions/TextInput/textinputruntimeobject.js +1 -1
  89. package/dist/Runtime/Extensions/TextInput/textinputruntimeobject.js.map +2 -2
  90. package/dist/Runtime/Extensions/TextObject/textruntimeobject-pixi-renderer.js +1 -1
  91. package/dist/Runtime/Extensions/TextObject/textruntimeobject-pixi-renderer.js.map +2 -2
  92. package/dist/Runtime/Extensions/TextObject/textruntimeobject.js +1 -1
  93. package/dist/Runtime/Extensions/TextObject/textruntimeobject.js.map +2 -2
  94. package/dist/Runtime/Extensions/TileMap/JsExtension.js +511 -287
  95. package/dist/Runtime/Extensions/TileMap/TileMapRuntimeManager.js +1 -1
  96. package/dist/Runtime/Extensions/TileMap/TileMapRuntimeManager.js.map +2 -2
  97. package/dist/Runtime/Extensions/TileMap/collision/TransformedTileMap.js +1 -1
  98. package/dist/Runtime/Extensions/TileMap/collision/TransformedTileMap.js.map +2 -2
  99. package/dist/Runtime/Extensions/TileMap/helper/TileMapHelper.js +1 -1
  100. package/dist/Runtime/Extensions/TileMap/helper/TileMapHelper.js.map +1 -1
  101. package/dist/Runtime/Extensions/TileMap/helper/dts/load/tiled/TiledTileMapLoader.d.ts.map +1 -1
  102. package/dist/Runtime/Extensions/TileMap/helper/dts/model/TileMapModel.d.ts +12 -1
  103. package/dist/Runtime/Extensions/TileMap/helper/dts/model/TileMapModel.d.ts.map +1 -1
  104. package/dist/Runtime/Extensions/TileMap/helper/dts/render/TileMapManager.d.ts.map +1 -1
  105. package/dist/Runtime/Extensions/TileMap/helper/dts/render/TileMapPixiHelper.d.ts +1 -0
  106. package/dist/Runtime/Extensions/TileMap/helper/dts/render/TileMapPixiHelper.d.ts.map +1 -1
  107. package/dist/Runtime/Extensions/TileMap/simpletilemapruntimeobject.js +1 -1
  108. package/dist/Runtime/Extensions/TileMap/simpletilemapruntimeobject.js.map +2 -2
  109. package/dist/Runtime/Extensions/TileMap/tilemapcollisionmaskruntimeobject.js +1 -1
  110. package/dist/Runtime/Extensions/TileMap/tilemapcollisionmaskruntimeobject.js.map +2 -2
  111. package/dist/Runtime/Extensions/TileMap/tilemapruntimeobject-pixi-renderer.js +1 -1
  112. package/dist/Runtime/Extensions/TileMap/tilemapruntimeobject-pixi-renderer.js.map +2 -2
  113. package/dist/Runtime/Extensions/TileMap/tilemapruntimeobject.js +1 -1
  114. package/dist/Runtime/Extensions/TileMap/tilemapruntimeobject.js.map +2 -2
  115. package/dist/Runtime/Extensions/TiledSpriteObject/tiledspriteruntimeobject.js +1 -1
  116. package/dist/Runtime/Extensions/TiledSpriteObject/tiledspriteruntimeobject.js.map +2 -2
  117. package/dist/Runtime/Extensions/TweenBehavior/JsExtension.js +1 -0
  118. package/dist/Runtime/Extensions/Video/JsExtension.js +35 -44
  119. package/dist/Runtime/Extensions/Video/videoruntimeobject.js +1 -1
  120. package/dist/Runtime/Extensions/Video/videoruntimeobject.js.map +2 -2
  121. package/dist/Runtime/ResourceLoader.js +1 -1
  122. package/dist/Runtime/ResourceLoader.js.map +2 -2
  123. package/dist/Runtime/RuntimeInstanceContainer.js.map +2 -2
  124. package/dist/Runtime/SpriteAnimator.js +1 -1
  125. package/dist/Runtime/SpriteAnimator.js.map +2 -2
  126. package/dist/Runtime/debugger-client/InGameDebugger.js +1 -1
  127. package/dist/Runtime/debugger-client/InGameDebugger.js.map +2 -2
  128. package/dist/Runtime/debugger-client/abstract-debugger-client.js +1 -1
  129. package/dist/Runtime/debugger-client/abstract-debugger-client.js.map +2 -2
  130. package/dist/Runtime/debugger-client/hot-reloader.js +2 -1
  131. package/dist/Runtime/debugger-client/hot-reloader.js.map +2 -2
  132. package/dist/Runtime/debugger-client/minimal-debugger-client.js +2 -0
  133. package/dist/Runtime/debugger-client/minimal-debugger-client.js.map +7 -0
  134. package/dist/Runtime/debugger-client/websocket-debugger-client.js.map +2 -2
  135. package/dist/Runtime/debugger-client/window-message-debugger-client.js.map +2 -2
  136. package/dist/Runtime/events-tools/inputtools.js +1 -1
  137. package/dist/Runtime/events-tools/inputtools.js.map +2 -2
  138. package/dist/Runtime/events-tools/objecttools.js +1 -1
  139. package/dist/Runtime/events-tools/objecttools.js.map +2 -2
  140. package/dist/Runtime/gd.js +1 -1
  141. package/dist/Runtime/gd.js.map +2 -2
  142. package/dist/Runtime/howler-sound-manager/howler-sound-manager.js +1 -1
  143. package/dist/Runtime/howler-sound-manager/howler-sound-manager.js.map +2 -2
  144. package/dist/Runtime/inputmanager.js +1 -1
  145. package/dist/Runtime/inputmanager.js.map +2 -2
  146. package/dist/Runtime/pixi-renderers/CustomRuntimeObject2DPixiRenderer.js +1 -1
  147. package/dist/Runtime/pixi-renderers/CustomRuntimeObject2DPixiRenderer.js.map +2 -2
  148. package/dist/Runtime/pixi-renderers/pixi-filters-tools.js +1 -1
  149. package/dist/Runtime/pixi-renderers/pixi-filters-tools.js.map +2 -2
  150. package/dist/Runtime/pixi-renderers/runtimegame-pixi-renderer.js +1 -1
  151. package/dist/Runtime/pixi-renderers/runtimegame-pixi-renderer.js.map +2 -2
  152. package/dist/Runtime/pixi-renderers/spriteruntimeobject-pixi-renderer.js +1 -1
  153. package/dist/Runtime/pixi-renderers/spriteruntimeobject-pixi-renderer.js.map +2 -2
  154. package/dist/Runtime/runtimegame.js +1 -1
  155. package/dist/Runtime/runtimegame.js.map +2 -2
  156. package/dist/Runtime/runtimeobject.js +1 -1
  157. package/dist/Runtime/runtimeobject.js.map +2 -2
  158. package/dist/Runtime/runtimescene.js +1 -1
  159. package/dist/Runtime/runtimescene.js.map +2 -2
  160. package/dist/Runtime/scenestack.js +1 -1
  161. package/dist/Runtime/scenestack.js.map +2 -2
  162. package/dist/Runtime/spriteruntimeobject.js +1 -1
  163. package/dist/Runtime/spriteruntimeobject.js.map +2 -2
  164. package/dist/Runtime/types/project-data.d.ts +36 -8
  165. package/dist/Runtime/variablescontainer.js +1 -1
  166. package/dist/Runtime/variablescontainer.js.map +2 -2
  167. package/dist/lib/libGD.cjs +1 -1
  168. package/dist/lib/libGD.wasm +0 -0
  169. package/gd.d.ts +149 -75
  170. package/package.json +3 -3
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../GDevelop/GDJS/Runtime/ResourceLoader.ts"],
4
- "sourcesContent": ["/*\n * GDevelop JS Platform\n * Copyright 2013-2023 Florian Rival (Florian.Rival@gmail.com). All rights reserved.\n * This project is released under the MIT License.\n */\nnamespace gdjs {\n const logger = new gdjs.Logger('ResourceLoader');\n\n const addSearchParameterToUrl = (\n url: string,\n urlEncodedParameterName: string,\n urlEncodedValue: string\n ) => {\n if (url.startsWith('data:') || url.startsWith('blob:')) {\n // blob/data protocol does not support search parameters, which are useless anyway.\n return url;\n }\n\n const separator = url.indexOf('?') === -1 ? '?' : '&';\n return url + separator + urlEncodedParameterName + '=' + urlEncodedValue;\n };\n\n const checkIfIsGDevelopCloudBucketUrl = (url: string): boolean => {\n return (\n url.startsWith('https://project-resources.gdevelop.io/') ||\n url.startsWith('https://project-resources-dev.gdevelop.io/')\n );\n };\n\n const maxForegroundConcurrency = 20;\n const maxBackgroundConcurrency = 5;\n const maxAttempt = 3;\n\n /**\n * A task of pre-loading resources used by a scene.\n *\n * A Promise can't be used instead of this class because a Promise will start\n * as soon as possible. It would flood the server with downloading requests\n * and make impossible to finely tune in which order scenes are actually\n * downloaded.\n */\n class SceneLoadingTask {\n sceneName: string;\n private onProgressCallbacks: Array<(count: number, total: number) => void>;\n private onFinishCallbacks: Array<() => void>;\n private isFinished = false;\n\n constructor(sceneName: string) {\n this.sceneName = sceneName;\n this.onProgressCallbacks = new Array<\n (count: number, total: number) => void\n >();\n this.onFinishCallbacks = new Array<() => void>();\n }\n\n registerCallback(\n onFinish: () => void,\n onProgress?: (count: number, total: number) => void\n ) {\n if (this.isFinished) {\n onFinish();\n return;\n }\n this.onFinishCallbacks.push(onFinish);\n if (onProgress) {\n this.onProgressCallbacks.push(onProgress);\n }\n }\n\n onProgress(count: number, total: number) {\n for (const onProgress of this.onProgressCallbacks) {\n onProgress(count, total);\n }\n }\n\n onFinish() {\n this.isFinished = true;\n for (const onFinish of this.onFinishCallbacks) {\n onFinish();\n }\n }\n }\n\n /**\n * Pre-load resources of any kind needed for a game or a scene.\n */\n export class ResourceLoader {\n _runtimeGame: RuntimeGame;\n /**\n * All the resource of a game by resource name.\n */\n private _resources: Map<string, ResourceData>;\n /**\n * Resources needed for any scene. Typically, they are resources from\n * global objects.\n */\n private _globalResources: Array<string>;\n /**\n * Resources by scene names.\n */\n private _sceneResources: Map<string, Array<string>>;\n /**\n * Keep track of which scene whose resources has already be pre-loaded.\n */\n private _sceneNamesToLoad: Set<string>;\n /**\n * Keep track of which scene whose resources has already be loaded.\n */\n private _sceneNamesToMakeReady: Set<string>;\n /**\n * A queue of scenes whose resources are still to be pre-loaded.\n */\n private _sceneToLoadQueue: Array<SceneLoadingTask> = new Array<\n SceneLoadingTask\n >();\n /**\n * The resource managers that actually download and remember downloaded\n * content.\n */\n _resourceManagersMap: Map<ResourceKind, ResourceManager>;\n private _imageManager: ImageManager;\n private _soundManager: SoundManager;\n private _fontManager: FontManager;\n private _jsonManager: JsonManager;\n private _model3DManager: Model3DManager;\n private _bitmapFontManager: BitmapFontManager;\n private _spineAtlasManager: SpineAtlasManager | null = null;\n private _spineManager: SpineManager | null = null;\n\n /**\n * Only used by events.\n */\n private currentLoadingSceneName: string = '';\n /**\n * Only used by events.\n */\n private currentSceneLoadingProgress: float = 0;\n /**\n * It's set to `true` during intermediary loading screen to use a greater\n * concurrency as the game is paused and doesn't need bandwidth (for video\n * or music streaming or online multiplayer).\n */\n private _isLoadingInForeground = true;\n\n /**\n * @param runtimeGame The game.\n * @param resourceDataArray The resources data of the game.\n * @param globalResources The resources needed for any layer.\n * @param layoutDataArray The resources used by each layer.\n */\n constructor(\n runtimeGame: RuntimeGame,\n resourceDataArray: ResourceData[],\n globalResources: Array<string>,\n layoutDataArray: Array<LayoutData>\n ) {\n this._runtimeGame = runtimeGame;\n this._resources = new Map<string, ResourceData>();\n this._globalResources = globalResources;\n\n // These 3 attributes are filled by `setResources`.\n this._sceneResources = new Map<string, Array<string>>();\n this._sceneNamesToLoad = new Set<string>();\n this._sceneNamesToMakeReady = new Set<string>();\n this.setResources(resourceDataArray, globalResources, layoutDataArray);\n\n this._imageManager = new gdjs.ImageManager(this);\n this._soundManager = new gdjs.SoundManager(this);\n this._fontManager = new gdjs.FontManager(this);\n this._jsonManager = new gdjs.JsonManager(this);\n this._bitmapFontManager = new gdjs.BitmapFontManager(\n this,\n this._imageManager\n );\n this._model3DManager = new gdjs.Model3DManager(this);\n\n // add spine related managers only if spine extension is used\n if (gdjs.SpineAtlasManager && gdjs.SpineManager) {\n this._spineAtlasManager = new gdjs.SpineAtlasManager(\n this,\n this._imageManager\n );\n this._spineManager = new gdjs.SpineManager(\n this,\n this._spineAtlasManager\n );\n }\n\n const resourceManagers: Array<ResourceManager> = [\n this._imageManager,\n this._soundManager,\n this._fontManager,\n this._jsonManager,\n this._bitmapFontManager,\n this._model3DManager,\n ];\n\n if (this._spineAtlasManager)\n resourceManagers.push(this._spineAtlasManager);\n if (this._spineManager) resourceManagers.push(this._spineManager);\n\n this._resourceManagersMap = new Map<ResourceKind, ResourceManager>();\n for (const resourceManager of resourceManagers) {\n for (const resourceKind of resourceManager.getResourceKinds()) {\n this._resourceManagersMap.set(resourceKind, resourceManager);\n }\n }\n }\n\n /**\n * @returns the runtime game instance.\n */\n getRuntimeGame(): RuntimeGame {\n return this._runtimeGame;\n }\n\n /**\n * Update the resources data of the game. Useful for hot-reloading, should\n * not be used otherwise.\n */\n setResources(\n resourceDataArray: ResourceData[],\n globalResources: Array<string>,\n layoutDataArray: Array<LayoutData>\n ): void {\n this._globalResources = globalResources;\n\n this._sceneResources.clear();\n this._sceneNamesToLoad.clear();\n this._sceneNamesToMakeReady.clear();\n for (const layoutData of layoutDataArray) {\n this._sceneResources.set(\n layoutData.name,\n layoutData.usedResources.map((resource) => resource.name)\n );\n this._sceneNamesToLoad.add(layoutData.name);\n this._sceneNamesToMakeReady.add(layoutData.name);\n }\n // TODO Clearing the queue doesn't abort the running task, but it should\n // not matter as resource loading is really fast in preview mode.\n this._sceneToLoadQueue.length = 0;\n for (let index = layoutDataArray.length - 1; index >= 0; index--) {\n const layoutData = layoutDataArray[index];\n this._sceneToLoadQueue.push(new SceneLoadingTask(layoutData.name));\n }\n\n this._resources.clear();\n for (const resourceData of resourceDataArray) {\n this._resources.set(resourceData.name, resourceData);\n }\n }\n\n async loadAllResources(\n onProgress: (loadingCount: integer, totalCount: integer) => void\n ): Promise<void> {\n let loadedCount = 0;\n await processAndRetryIfNeededWithPromisePool(\n [...this._resources.values()],\n maxForegroundConcurrency,\n maxAttempt,\n async (resource) => {\n await this._loadResource(resource);\n await this._processResource(resource);\n loadedCount++;\n onProgress(loadedCount, this._resources.size);\n }\n );\n this._sceneNamesToLoad.clear();\n this._sceneNamesToMakeReady.clear();\n }\n\n /**\n * Load the resources that are needed to launch the first scene.\n */\n async loadGlobalAndFirstSceneResources(\n firstSceneName: string,\n onProgress: (count: number, total: number) => void\n ): Promise<void> {\n const sceneResources = this._sceneResources.get(firstSceneName);\n if (!sceneResources) {\n logger.warn(\n 'Can\\'t load resource for unknown scene: \"' + firstSceneName + '\".'\n );\n return;\n }\n let loadedCount = 0;\n const resources = [...this._globalResources, ...sceneResources.values()];\n await processAndRetryIfNeededWithPromisePool(\n resources,\n maxForegroundConcurrency,\n maxAttempt,\n async (resourceName) => {\n const resource = this._resources.get(resourceName);\n if (!resource) {\n logger.warn('Unable to find resource \"' + resourceName + '\".');\n return;\n }\n await this._loadResource(resource);\n await this._processResource(resource);\n loadedCount++;\n onProgress(loadedCount, resources.length);\n }\n );\n this._setSceneAssetsLoaded(firstSceneName);\n this._setSceneAssetsReady(firstSceneName);\n }\n\n /**\n * Load each scene in order.\n *\n * This is done in background to try to avoid loading screens when changing\n * scenes.\n */\n async loadAllSceneInBackground(): Promise<void> {\n while (this._sceneToLoadQueue.length > 0) {\n const task = this._sceneToLoadQueue[this._sceneToLoadQueue.length - 1];\n if (task === undefined) {\n continue;\n }\n this.currentLoadingSceneName = task.sceneName;\n if (!this.areSceneAssetsLoaded(task.sceneName)) {\n await this._doLoadSceneResources(\n task.sceneName,\n async (count, total) => task.onProgress(count, total)\n );\n // A scene may have been moved last while awaiting resources to be\n // downloaded (see _prioritizeScene).\n this._sceneToLoadQueue.splice(\n this._sceneToLoadQueue.findIndex((element) => element === task),\n 1\n );\n task.onFinish();\n } else {\n this._sceneToLoadQueue.pop();\n }\n }\n this.currentLoadingSceneName = '';\n }\n\n private async _doLoadSceneResources(\n sceneName: string,\n onProgress?: (count: number, total: number) => Promise<void>\n ): Promise<void> {\n const sceneResources = this._sceneResources.get(sceneName);\n if (!sceneResources) {\n logger.warn(\n 'Can\\'t load resource for unknown scene: \"' + sceneName + '\".'\n );\n return;\n }\n let loadedCount = 0;\n await processAndRetryIfNeededWithPromisePool(\n [...sceneResources.values()],\n this._isLoadingInForeground\n ? maxForegroundConcurrency\n : maxBackgroundConcurrency,\n maxAttempt,\n async (resourceName) => {\n const resource = this._resources.get(resourceName);\n if (!resource) {\n logger.warn('Unable to find resource \"' + resourceName + '\".');\n return;\n }\n await this._loadResource(resource);\n loadedCount++;\n this.currentSceneLoadingProgress = loadedCount / this._resources.size;\n onProgress && (await onProgress(loadedCount, this._resources.size));\n }\n );\n this._setSceneAssetsLoaded(sceneName);\n }\n\n private async _loadResource(resource: ResourceData): Promise<void> {\n const resourceManager = this._resourceManagersMap.get(resource.kind);\n if (!resourceManager) {\n logger.warn(\n 'Unknown resource kind: \"' +\n resource.kind +\n '\" for: \"' +\n resource.name +\n '\".'\n );\n return;\n }\n await resourceManager.loadResource(resource.name);\n }\n\n /**\n * Load and process a scene that is needed right away.\n *\n * The renderer will show a loading screen while its done.\n */\n async loadAndProcessSceneResources(\n sceneName: string,\n onProgress?: (count: number, total: number) => Promise<void>\n ): Promise<void> {\n if (this.areSceneAssetsReady(sceneName)) {\n return;\n }\n await this.loadSceneResources(sceneName, onProgress);\n\n const sceneResources = this._sceneResources.get(sceneName);\n if (!sceneResources) {\n logger.warn(\n 'Can\\'t load resource for unknown scene: \"' + sceneName + '\".'\n );\n return;\n }\n\n let parsedCount = 0;\n for (const resourceName of sceneResources) {\n const resource = this._resources.get(resourceName);\n if (!resource) {\n logger.warn('Unable to find resource \"' + resourceName + '\".');\n continue;\n }\n await this._processResource(resource);\n parsedCount++;\n onProgress && (await onProgress(parsedCount, sceneResources.length));\n }\n this._setSceneAssetsReady(sceneName);\n }\n\n /**\n * Load a scene resources without parsing them.\n *\n * When another scene resources are loading in background, it waits for\n * all its resources to be loaded before loading resources of the given\n * scene.\n */\n async loadSceneResources(\n sceneName: string,\n onProgress?: (count: number, total: number) => void\n ): Promise<void> {\n this._isLoadingInForeground = true;\n const task = this._prioritizeScene(sceneName);\n return new Promise<void>((resolve, reject) => {\n if (!task) {\n this._isLoadingInForeground = false;\n resolve();\n return;\n }\n task.registerCallback(() => {\n this._isLoadingInForeground = false;\n resolve();\n }, onProgress);\n });\n }\n\n /**\n * Put a given scene at the end of the queue.\n *\n * When the scene that is currently loading in background is done,\n * this scene will be the next to be loaded.\n */\n private _prioritizeScene(sceneName: string): SceneLoadingTask | null {\n const taskIndex = this._sceneToLoadQueue.findIndex(\n (task) => task.sceneName === sceneName\n );\n if (taskIndex < 0) {\n // The scene is already loaded.\n return null;\n }\n const task = this._sceneToLoadQueue[taskIndex];\n this._sceneToLoadQueue.splice(taskIndex, 1);\n this._sceneToLoadQueue.push(task);\n return task;\n }\n\n private async _processResource(resource: ResourceData): Promise<void> {\n const resourceManager = this._resourceManagersMap.get(resource.kind);\n if (!resourceManager) {\n logger.warn(\n 'Unknown resource kind: \"' +\n resource.kind +\n '\" for: \"' +\n resource.name +\n '\".'\n );\n return;\n }\n await resourceManager.processResource(resource.name);\n }\n\n getSceneLoadingProgress(sceneName: string): float {\n return sceneName === this.currentLoadingSceneName\n ? this.currentSceneLoadingProgress\n : this.areSceneAssetsLoaded(sceneName)\n ? 1\n : 0;\n }\n\n /**\n * @returns true when all the resources of the given scene are loaded\n * (but maybe not parsed).\n */\n areSceneAssetsLoaded(sceneName: string): boolean {\n return !this._sceneNamesToLoad.has(sceneName);\n }\n\n /**\n * @returns true when all the resources of the given scene are loaded and\n * parsed.\n */\n areSceneAssetsReady(sceneName: string): boolean {\n return !this._sceneNamesToMakeReady.has(sceneName);\n }\n\n private _setSceneAssetsLoaded(sceneName: string): void {\n this._sceneNamesToLoad.delete(sceneName);\n }\n\n private _setSceneAssetsReady(sceneName: string): void {\n this._sceneNamesToMakeReady.delete(sceneName);\n }\n\n getResource(resourceName: string): ResourceData | null {\n return this._resources.get(resourceName) || null;\n }\n\n // Helper methods used when resources are loaded from an URL.\n\n /**\n * Complete the given URL with any specific parameter required to access\n * the resource (this can be for example a token needed to access the resource).\n */\n getFullUrl(url: string) {\n const { gdevelopResourceToken } = this._runtimeGame._options;\n if (!gdevelopResourceToken) return url;\n\n if (!checkIfIsGDevelopCloudBucketUrl(url)) return url;\n\n return addSearchParameterToUrl(\n url,\n 'gd_resource_token',\n encodeURIComponent(gdevelopResourceToken)\n );\n }\n\n /**\n * Return true if the specified URL must be loaded with cookies (\"credentials\")\n * sent to grant access to them.\n */\n checkIfCredentialsRequired(url: string) {\n if (this._runtimeGame._options.gdevelopResourceToken) return false;\n\n // Any resource stored on the GDevelop Cloud buckets needs the \"credentials\" of the user,\n // i.e: its gdevelop.io cookie, to be passed.\n // Note that this is only useful during previews.\n if (checkIfIsGDevelopCloudBucketUrl(url)) return true;\n\n // For other resources, use the default way of loading resources (\"anonymous\" or \"same-site\").\n return false;\n }\n\n /**\n * Get the gdjs.SoundManager of the RuntimeGame.\n * @return The sound manager.\n */\n getSoundManager(): gdjs.HowlerSoundManager {\n return this._soundManager;\n }\n\n /**\n * Get the gdjs.ImageManager of the RuntimeGame.\n * @return The image manager.\n */\n getImageManager(): gdjs.PixiImageManager {\n return this._imageManager;\n }\n\n /**\n * Get the gdjs.FontManager of the RuntimeGame.\n * @return The font manager.\n */\n getFontManager(): gdjs.FontFaceObserverFontManager {\n return this._fontManager;\n }\n\n /**\n * Get the gdjs.BitmapFontManager of the RuntimeGame.\n * @return The bitmap font manager.\n */\n getBitmapFontManager(): gdjs.BitmapFontManager {\n return this._bitmapFontManager;\n }\n\n /**\n * Get the JSON manager of the game, used to load JSON from game\n * resources.\n * @return The json manager for the game\n */\n getJsonManager(): gdjs.JsonManager {\n return this._jsonManager;\n }\n\n /**\n * Get the 3D model manager of the game, used to load 3D model from game\n * resources.\n * @return The 3D model manager for the game\n */\n getModel3DManager(): gdjs.Model3DManager {\n return this._model3DManager;\n }\n\n /**\n * Get the Spine manager of the game, used to load and construct spine skeletons from game\n * resources.\n * @return The Spine manager for the game\n */\n getSpineManager(): gdjs.SpineManager | null {\n return this._spineManager;\n }\n\n /**\n * Get the Spine Atlas manager of the game, used to load atlases from game\n * resources.\n * @return The Spine Atlas manager for the game\n */\n getSpineAtlasManager(): gdjs.SpineAtlasManager | null {\n return this._spineAtlasManager;\n }\n }\n\n type PromiseError<T> = { item: T; error: Error };\n\n type PromisePoolOutput<T, U> = {\n results: Array<U>;\n errors: Array<PromiseError<T>>;\n };\n\n const processWithPromisePool = <T, U>(\n items: Array<T>,\n maxConcurrency: number,\n asyncFunction: (item: T) => Promise<U>\n ): Promise<PromisePoolOutput<T, U>> => {\n const results: Array<U> = [];\n const errors: Array<PromiseError<T>> = [];\n let activePromises = 0;\n let index = 0;\n\n return new Promise((resolve, reject) => {\n const executeNext = () => {\n if (items.length === 0) {\n resolve({ results, errors });\n return;\n }\n while (activePromises < maxConcurrency && index < items.length) {\n const item = items[index++];\n activePromises++;\n\n asyncFunction(item)\n .then((result) => results.push(result))\n .catch((error) => errors.push({ item, error }))\n .finally(() => {\n activePromises--;\n if (index === items.length && activePromises === 0) {\n resolve({ results, errors });\n } else {\n executeNext();\n }\n });\n }\n };\n\n executeNext();\n });\n };\n\n const processAndRetryIfNeededWithPromisePool = async <T, U>(\n items: Array<T>,\n maxConcurrency: number,\n maxAttempt: number,\n asyncFunction: (item: T) => Promise<U>\n ): Promise<PromisePoolOutput<T, U>> => {\n const output = await processWithPromisePool<T, U>(\n items,\n maxConcurrency,\n asyncFunction\n );\n if (output.errors.length !== 0) {\n logger.warn(\"Some assets couldn't be downloaded. Trying again now.\");\n }\n for (\n let attempt = 1;\n attempt < maxAttempt && output.errors.length !== 0;\n attempt++\n ) {\n const retryOutput = await processWithPromisePool<T, U>(\n items,\n maxConcurrency,\n asyncFunction\n );\n output.results.push.apply(output.results, retryOutput.results);\n output.errors = retryOutput.errors;\n }\n return output;\n };\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/*\n * GDevelop JS Platform\n * Copyright 2013-2023 Florian Rival (Florian.Rival@gmail.com). All rights reserved.\n * This project is released under the MIT License.\n */\nnamespace gdjs {\n const logger = new gdjs.Logger('ResourceLoader');\n\n const addSearchParameterToUrl = (\n url: string,\n urlEncodedParameterName: string,\n urlEncodedValue: string\n ) => {\n if (url.startsWith('data:') || url.startsWith('blob:')) {\n // blob/data protocol does not support search parameters, which are useless anyway.\n return url;\n }\n\n const separator = url.indexOf('?') === -1 ? '?' : '&';\n return url + separator + urlEncodedParameterName + '=' + urlEncodedValue;\n };\n\n const checkIfIsGDevelopCloudBucketUrl = (url: string): boolean => {\n return (\n url.startsWith('https://project-resources.gdevelop.io/') ||\n url.startsWith('https://project-resources-dev.gdevelop.io/')\n );\n };\n\n const maxForegroundConcurrency = 20;\n const maxBackgroundConcurrency = 5;\n const maxAttempt = 3;\n\n /**\n * A task of pre-loading resources used by a scene.\n *\n * A Promise can't be used instead of this class because a Promise will start\n * as soon as possible. It would flood the server with downloading requests\n * and make impossible to finely tune in which order scenes are actually\n * downloaded.\n */\n class SceneLoadingTask {\n sceneName: string;\n private onProgressCallbacks: Array<(count: number, total: number) => void>;\n private onFinishCallbacks: Array<() => void>;\n private isFinished = false;\n\n constructor(sceneName: string) {\n this.sceneName = sceneName;\n this.onProgressCallbacks = new Array<\n (count: number, total: number) => void\n >();\n this.onFinishCallbacks = new Array<() => void>();\n }\n\n registerCallback(\n onFinish: () => void,\n onProgress?: (count: number, total: number) => void\n ) {\n if (this.isFinished) {\n onFinish();\n return;\n }\n this.onFinishCallbacks.push(onFinish);\n if (onProgress) {\n this.onProgressCallbacks.push(onProgress);\n }\n }\n\n onProgress(count: number, total: number) {\n for (const onProgress of this.onProgressCallbacks) {\n onProgress(count, total);\n }\n }\n\n onFinish() {\n this.isFinished = true;\n for (const onFinish of this.onFinishCallbacks) {\n onFinish();\n }\n }\n }\n\n /**\n * Pre-load resources of any kind needed for a game or a scene.\n */\n export class ResourceLoader {\n _runtimeGame: RuntimeGame;\n /**\n * All the resource of a game by resource name.\n */\n private _resources: Map<string, ResourceData>;\n /**\n * Resources needed for any scene. Typically, they are resources from\n * global objects.\n */\n private _globalResources: Array<string>;\n /**\n * Resources by scene names.\n */\n private _sceneResources: Map<string, Array<string>>;\n /**\n * Keep track of which scene whose resources has already be pre-loaded.\n */\n private _sceneNamesToLoad: Set<string>;\n /**\n * Keep track of which scene whose resources has already be loaded.\n */\n private _sceneNamesToMakeReady: Set<string>;\n /**\n * A queue of scenes whose resources are still to be pre-loaded.\n */\n private _sceneToLoadQueue: Array<SceneLoadingTask> = new Array<\n SceneLoadingTask\n >();\n /**\n * The resource managers that actually download and remember downloaded\n * content.\n */\n _resourceManagersMap: Map<ResourceKind, ResourceManager>;\n private _imageManager: ImageManager;\n private _soundManager: SoundManager;\n private _fontManager: FontManager;\n private _jsonManager: JsonManager;\n private _model3DManager: Model3DManager;\n private _bitmapFontManager: BitmapFontManager;\n private _spineAtlasManager: SpineAtlasManager | null = null;\n private _spineManager: SpineManager | null = null;\n\n /**\n * Only used by events.\n */\n private currentLoadingSceneName: string = '';\n /**\n * Only used by events.\n */\n private currentSceneLoadingProgress: float = 0;\n /**\n * It's set to `true` during intermediary loading screen to use a greater\n * concurrency as the game is paused and doesn't need bandwidth (for video\n * or music streaming or online multiplayer).\n */\n private _isLoadingInForeground = true;\n\n /**\n * @param runtimeGame The game.\n * @param resourceDataArray The resources data of the game.\n * @param globalResources The resources needed for any layer.\n * @param layoutDataArray The resources used by each layer.\n */\n constructor(\n runtimeGame: RuntimeGame,\n resourceDataArray: ResourceData[],\n globalResources: Array<string>,\n layoutDataArray: Array<LayoutData>\n ) {\n this._runtimeGame = runtimeGame;\n this._resources = new Map<string, ResourceData>();\n this._globalResources = globalResources;\n\n // These 3 attributes are filled by `setResources`.\n this._sceneResources = new Map<string, Array<string>>();\n this._sceneNamesToLoad = new Set<string>();\n this._sceneNamesToMakeReady = new Set<string>();\n this.setResources(resourceDataArray, globalResources, layoutDataArray);\n\n this._imageManager = new gdjs.ImageManager(this);\n this._soundManager = new gdjs.SoundManager(this);\n this._fontManager = new gdjs.FontManager(this);\n this._jsonManager = new gdjs.JsonManager(this);\n this._bitmapFontManager = new gdjs.BitmapFontManager(\n this,\n this._imageManager\n );\n this._model3DManager = new gdjs.Model3DManager(this);\n\n // add spine related managers only if spine extension is used\n if (gdjs.SpineAtlasManager && gdjs.SpineManager) {\n this._spineAtlasManager = new gdjs.SpineAtlasManager(\n this,\n this._imageManager\n );\n this._spineManager = new gdjs.SpineManager(\n this,\n this._spineAtlasManager\n );\n }\n\n const resourceManagers: Array<ResourceManager> = [\n this._imageManager,\n this._soundManager,\n this._fontManager,\n this._jsonManager,\n this._bitmapFontManager,\n this._model3DManager,\n ];\n\n if (this._spineAtlasManager)\n resourceManagers.push(this._spineAtlasManager);\n if (this._spineManager) resourceManagers.push(this._spineManager);\n\n this._resourceManagersMap = new Map<ResourceKind, ResourceManager>();\n for (const resourceManager of resourceManagers) {\n for (const resourceKind of resourceManager.getResourceKinds()) {\n this._resourceManagersMap.set(resourceKind, resourceManager);\n }\n }\n }\n\n /**\n * @returns the runtime game instance.\n */\n getRuntimeGame(): RuntimeGame {\n return this._runtimeGame;\n }\n\n /**\n * Update the resources data of the game. Useful for hot-reloading, should\n * not be used otherwise.\n */\n setResources(\n resourceDataArray: ResourceData[],\n globalResources: Array<string>,\n layoutDataArray: Array<LayoutData>\n ): void {\n this._globalResources = globalResources;\n\n this._sceneResources.clear();\n this._sceneNamesToLoad.clear();\n this._sceneNamesToMakeReady.clear();\n for (const layoutData of layoutDataArray) {\n this._sceneResources.set(\n layoutData.name,\n layoutData.usedResources.map((resource) => resource.name)\n );\n this._sceneNamesToLoad.add(layoutData.name);\n this._sceneNamesToMakeReady.add(layoutData.name);\n }\n // TODO Clearing the queue doesn't abort the running task, but it should\n // not matter as resource loading is really fast in preview mode.\n this._sceneToLoadQueue.length = 0;\n for (let index = layoutDataArray.length - 1; index >= 0; index--) {\n const layoutData = layoutDataArray[index];\n this._sceneToLoadQueue.push(new SceneLoadingTask(layoutData.name));\n }\n\n this._resources.clear();\n for (const resourceData of resourceDataArray) {\n if (!resourceData.file) {\n // Empty string or missing `file` field: not a valid resource, let's entirely ignore it.\n // Otherwise, this can confuse some loaders that will consider an empty string different\n // than a file that happen not to fail to load.\n continue;\n }\n\n this._resources.set(resourceData.name, resourceData);\n }\n }\n\n async loadAllResources(\n onProgress: (loadingCount: integer, totalCount: integer) => void\n ): Promise<void> {\n let loadedCount = 0;\n await processAndRetryIfNeededWithPromisePool(\n [...this._resources.values()],\n maxForegroundConcurrency,\n maxAttempt,\n async (resource) => {\n await this._loadResource(resource);\n await this._processResource(resource);\n loadedCount++;\n onProgress(loadedCount, this._resources.size);\n }\n );\n this._sceneNamesToLoad.clear();\n this._sceneNamesToMakeReady.clear();\n }\n\n /**\n * Load the resources that are needed to launch the first scene.\n */\n async loadGlobalAndFirstSceneResources(\n firstSceneName: string,\n onProgress: (count: number, total: number) => void\n ): Promise<void> {\n const sceneResources = this._sceneResources.get(firstSceneName);\n if (!sceneResources) {\n logger.warn(\n 'Can\\'t load resource for unknown scene: \"' + firstSceneName + '\".'\n );\n return;\n }\n let loadedCount = 0;\n const resources = [...this._globalResources, ...sceneResources.values()];\n await processAndRetryIfNeededWithPromisePool(\n resources,\n maxForegroundConcurrency,\n maxAttempt,\n async (resourceName) => {\n const resource = this._resources.get(resourceName);\n if (!resource) {\n logger.warn('Unable to find resource \"' + resourceName + '\".');\n return;\n }\n await this._loadResource(resource);\n await this._processResource(resource);\n loadedCount++;\n onProgress(loadedCount, resources.length);\n }\n );\n this._setSceneAssetsLoaded(firstSceneName);\n this._setSceneAssetsReady(firstSceneName);\n }\n\n /**\n * Load each scene in order.\n *\n * This is done in background to try to avoid loading screens when changing\n * scenes.\n */\n async loadAllSceneInBackground(): Promise<void> {\n while (this._sceneToLoadQueue.length > 0) {\n const task = this._sceneToLoadQueue[this._sceneToLoadQueue.length - 1];\n if (task === undefined) {\n continue;\n }\n this.currentLoadingSceneName = task.sceneName;\n if (!this.areSceneAssetsLoaded(task.sceneName)) {\n await this._doLoadSceneResources(\n task.sceneName,\n async (count, total) => task.onProgress(count, total)\n );\n // A scene may have been moved last while awaiting resources to be\n // downloaded (see _prioritizeScene).\n this._sceneToLoadQueue.splice(\n this._sceneToLoadQueue.findIndex((element) => element === task),\n 1\n );\n task.onFinish();\n } else {\n this._sceneToLoadQueue.pop();\n }\n }\n this.currentLoadingSceneName = '';\n }\n\n private async _doLoadSceneResources(\n sceneName: string,\n onProgress?: (count: number, total: number) => Promise<void>\n ): Promise<void> {\n const sceneResources = this._sceneResources.get(sceneName);\n if (!sceneResources) {\n logger.warn(\n 'Can\\'t load resource for unknown scene: \"' + sceneName + '\".'\n );\n return;\n }\n let loadedCount = 0;\n await processAndRetryIfNeededWithPromisePool(\n [...sceneResources.values()],\n this._isLoadingInForeground\n ? maxForegroundConcurrency\n : maxBackgroundConcurrency,\n maxAttempt,\n async (resourceName) => {\n const resource = this._resources.get(resourceName);\n if (!resource) {\n logger.warn('Unable to find resource \"' + resourceName + '\".');\n return;\n }\n await this._loadResource(resource);\n loadedCount++;\n this.currentSceneLoadingProgress = loadedCount / this._resources.size;\n onProgress && (await onProgress(loadedCount, this._resources.size));\n }\n );\n this._setSceneAssetsLoaded(sceneName);\n }\n\n private async _loadResource(resource: ResourceData): Promise<void> {\n const resourceManager = this._resourceManagersMap.get(resource.kind);\n if (!resourceManager) {\n logger.warn(\n 'Unknown resource kind: \"' +\n resource.kind +\n '\" for: \"' +\n resource.name +\n '\".'\n );\n return;\n }\n await resourceManager.loadResource(resource.name);\n }\n\n /**\n * Load and process a scene that is needed right away.\n *\n * The renderer will show a loading screen while its done.\n */\n async loadAndProcessSceneResources(\n sceneName: string,\n onProgress?: (count: number, total: number) => Promise<void>\n ): Promise<void> {\n if (this.areSceneAssetsReady(sceneName)) {\n return;\n }\n await this.loadSceneResources(sceneName, onProgress);\n\n const sceneResources = this._sceneResources.get(sceneName);\n if (!sceneResources) {\n logger.warn(\n 'Can\\'t load resource for unknown scene: \"' + sceneName + '\".'\n );\n return;\n }\n\n let parsedCount = 0;\n for (const resourceName of sceneResources) {\n const resource = this._resources.get(resourceName);\n if (!resource) {\n logger.warn('Unable to find resource \"' + resourceName + '\".');\n continue;\n }\n await this._processResource(resource);\n parsedCount++;\n onProgress && (await onProgress(parsedCount, sceneResources.length));\n }\n this._setSceneAssetsReady(sceneName);\n }\n\n /**\n * Load a scene resources without parsing them.\n *\n * When another scene resources are loading in background, it waits for\n * all its resources to be loaded before loading resources of the given\n * scene.\n */\n async loadSceneResources(\n sceneName: string,\n onProgress?: (count: number, total: number) => void\n ): Promise<void> {\n this._isLoadingInForeground = true;\n const task = this._prioritizeScene(sceneName);\n return new Promise<void>((resolve, reject) => {\n if (!task) {\n this._isLoadingInForeground = false;\n resolve();\n return;\n }\n task.registerCallback(() => {\n this._isLoadingInForeground = false;\n resolve();\n }, onProgress);\n });\n }\n\n /**\n * Put a given scene at the end of the queue.\n *\n * When the scene that is currently loading in background is done,\n * this scene will be the next to be loaded.\n */\n private _prioritizeScene(sceneName: string): SceneLoadingTask | null {\n const taskIndex = this._sceneToLoadQueue.findIndex(\n (task) => task.sceneName === sceneName\n );\n if (taskIndex < 0) {\n // The scene is already loaded.\n return null;\n }\n const task = this._sceneToLoadQueue[taskIndex];\n this._sceneToLoadQueue.splice(taskIndex, 1);\n this._sceneToLoadQueue.push(task);\n return task;\n }\n\n private async _processResource(resource: ResourceData): Promise<void> {\n const resourceManager = this._resourceManagersMap.get(resource.kind);\n if (!resourceManager) {\n logger.warn(\n 'Unknown resource kind: \"' +\n resource.kind +\n '\" for: \"' +\n resource.name +\n '\".'\n );\n return;\n }\n await resourceManager.processResource(resource.name);\n }\n\n getSceneLoadingProgress(sceneName: string): float {\n return sceneName === this.currentLoadingSceneName\n ? this.currentSceneLoadingProgress\n : this.areSceneAssetsLoaded(sceneName)\n ? 1\n : 0;\n }\n\n /**\n * @returns true when all the resources of the given scene are loaded\n * (but maybe not parsed).\n */\n areSceneAssetsLoaded(sceneName: string): boolean {\n return !this._sceneNamesToLoad.has(sceneName);\n }\n\n /**\n * @returns true when all the resources of the given scene are loaded and\n * parsed.\n */\n areSceneAssetsReady(sceneName: string): boolean {\n return !this._sceneNamesToMakeReady.has(sceneName);\n }\n\n private _setSceneAssetsLoaded(sceneName: string): void {\n this._sceneNamesToLoad.delete(sceneName);\n }\n\n private _setSceneAssetsReady(sceneName: string): void {\n this._sceneNamesToMakeReady.delete(sceneName);\n }\n\n getResource(resourceName: string): ResourceData | null {\n return this._resources.get(resourceName) || null;\n }\n\n // Helper methods used when resources are loaded from an URL.\n\n /**\n * Complete the given URL with any specific parameter required to access\n * the resource (this can be for example a token needed to access the resource).\n */\n getFullUrl(url: string) {\n const { gdevelopResourceToken } = this._runtimeGame._options;\n if (!gdevelopResourceToken) return url;\n\n if (!checkIfIsGDevelopCloudBucketUrl(url)) return url;\n\n return addSearchParameterToUrl(\n url,\n 'gd_resource_token',\n encodeURIComponent(gdevelopResourceToken)\n );\n }\n\n /**\n * Return true if the specified URL must be loaded with cookies (\"credentials\")\n * sent to grant access to them.\n */\n checkIfCredentialsRequired(url: string) {\n if (this._runtimeGame._options.gdevelopResourceToken) return false;\n\n // Any resource stored on the GDevelop Cloud buckets needs the \"credentials\" of the user,\n // i.e: its gdevelop.io cookie, to be passed.\n // Note that this is only useful during previews.\n if (checkIfIsGDevelopCloudBucketUrl(url)) return true;\n\n // For other resources, use the default way of loading resources (\"anonymous\" or \"same-site\").\n return false;\n }\n\n /**\n * Get the gdjs.SoundManager of the RuntimeGame.\n * @return The sound manager.\n */\n getSoundManager(): gdjs.HowlerSoundManager {\n return this._soundManager;\n }\n\n /**\n * Get the gdjs.ImageManager of the RuntimeGame.\n * @return The image manager.\n */\n getImageManager(): gdjs.PixiImageManager {\n return this._imageManager;\n }\n\n /**\n * Get the gdjs.FontManager of the RuntimeGame.\n * @return The font manager.\n */\n getFontManager(): gdjs.FontFaceObserverFontManager {\n return this._fontManager;\n }\n\n /**\n * Get the gdjs.BitmapFontManager of the RuntimeGame.\n * @return The bitmap font manager.\n */\n getBitmapFontManager(): gdjs.BitmapFontManager {\n return this._bitmapFontManager;\n }\n\n /**\n * Get the JSON manager of the game, used to load JSON from game\n * resources.\n * @return The json manager for the game\n */\n getJsonManager(): gdjs.JsonManager {\n return this._jsonManager;\n }\n\n /**\n * Get the 3D model manager of the game, used to load 3D model from game\n * resources.\n * @return The 3D model manager for the game\n */\n getModel3DManager(): gdjs.Model3DManager {\n return this._model3DManager;\n }\n\n /**\n * Get the Spine manager of the game, used to load and construct spine skeletons from game\n * resources.\n * @return The Spine manager for the game\n */\n getSpineManager(): gdjs.SpineManager | null {\n return this._spineManager;\n }\n\n /**\n * Get the Spine Atlas manager of the game, used to load atlases from game\n * resources.\n * @return The Spine Atlas manager for the game\n */\n getSpineAtlasManager(): gdjs.SpineAtlasManager | null {\n return this._spineAtlasManager;\n }\n }\n\n type PromiseError<T> = { item: T; error: Error };\n\n type PromisePoolOutput<T, U> = {\n results: Array<U>;\n errors: Array<PromiseError<T>>;\n };\n\n const processWithPromisePool = <T, U>(\n items: Array<T>,\n maxConcurrency: number,\n asyncFunction: (item: T) => Promise<U>\n ): Promise<PromisePoolOutput<T, U>> => {\n const results: Array<U> = [];\n const errors: Array<PromiseError<T>> = [];\n let activePromises = 0;\n let index = 0;\n\n return new Promise((resolve, reject) => {\n const executeNext = () => {\n if (items.length === 0) {\n resolve({ results, errors });\n return;\n }\n while (activePromises < maxConcurrency && index < items.length) {\n const item = items[index++];\n activePromises++;\n\n asyncFunction(item)\n .then((result) => results.push(result))\n .catch((error) => errors.push({ item, error }))\n .finally(() => {\n activePromises--;\n if (index === items.length && activePromises === 0) {\n resolve({ results, errors });\n } else {\n executeNext();\n }\n });\n }\n };\n\n executeNext();\n });\n };\n\n const processAndRetryIfNeededWithPromisePool = async <T, U>(\n items: Array<T>,\n maxConcurrency: number,\n maxAttempt: number,\n asyncFunction: (item: T) => Promise<U>\n ): Promise<PromisePoolOutput<T, U>> => {\n const output = await processWithPromisePool<T, U>(\n items,\n maxConcurrency,\n asyncFunction\n );\n if (output.errors.length !== 0) {\n logger.warn(\"Some assets couldn't be downloaded. Trying again now.\");\n }\n for (\n let attempt = 1;\n attempt < maxAttempt && output.errors.length !== 0;\n attempt++\n ) {\n const retryOutput = await processWithPromisePool<T, U>(\n items,\n maxConcurrency,\n asyncFunction\n );\n output.results.push.apply(output.results, retryOutput.results);\n output.errors = retryOutput.errors;\n }\n return output;\n };\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../GDevelop/GDJS/Runtime/RuntimeInstanceContainer.ts"],
4
- "sourcesContent": ["/*\n * GDevelop JS Platform\n * Copyright 2013-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.\n * This project is released under the MIT License.\n */\nnamespace gdjs {\n const logger = new gdjs.Logger('RuntimeInstanceContainer');\n\n /**\n * A container of object instances rendered on screen.\n */\n export abstract class RuntimeInstanceContainer {\n _initialBehaviorSharedData: Hashtable<BehaviorSharedData | null>;\n\n /** Contains the instances living on the container */\n _instances: Hashtable<RuntimeObject[]>;\n\n /**\n * An array used to create a list of all instance when necessary.\n * @see gdjs.RuntimeInstanceContainer#_constructListOfAllInstances}\n */\n private _allInstancesList: gdjs.RuntimeObject[] = [];\n _allInstancesListIsUpToDate = true;\n\n /** Used to recycle destroyed instance instead of creating new ones. */\n _instancesCache: Hashtable<RuntimeObject[]>;\n\n /** The instances removed from the container and waiting to be sent to the cache. */\n _instancesRemoved: gdjs.RuntimeObject[] = [];\n\n /** Contains the objects data stored in the project */\n _objects: Hashtable<ObjectData>;\n _objectsCtor: Hashtable<typeof RuntimeObject>;\n\n _layers: Hashtable<RuntimeLayer>;\n _orderedLayers: RuntimeLayer[]; // TODO: should this be a single structure with _layers, to enforce its usage?\n _layersCameraCoordinates: Record<string, [float, float, float, float]> = {};\n\n // Options for the debug draw:\n _debugDrawEnabled: boolean = false;\n _debugDrawShowHiddenInstances: boolean = false;\n _debugDrawShowPointsNames: boolean = false;\n _debugDrawShowCustomPoints: boolean = false;\n\n constructor() {\n this._initialBehaviorSharedData = new Hashtable();\n this._instances = new Hashtable();\n this._instancesCache = new Hashtable();\n this._objects = new Hashtable();\n this._objectsCtor = new Hashtable();\n this._layers = new Hashtable();\n this._orderedLayers = [];\n }\n\n /**\n * Return the time elapsed since the last frame,\n * in milliseconds, for objects on the layer.\n */\n abstract getElapsedTime(): float;\n\n /**\n * Get the renderer associated to the container.\n */\n abstract getRenderer(): gdjs.RuntimeInstanceContainerRenderer;\n\n /**\n * Get the renderer for visual debugging associated to the container.\n */\n abstract getDebuggerRenderer(): gdjs.DebuggerRenderer;\n\n /**\n * Get the {@link gdjs.RuntimeGame} associated to this.\n */\n abstract getGame(): gdjs.RuntimeGame;\n\n /**\n * Get the {@link gdjs.RuntimeScene} associated to this.\n */\n abstract getScene(): gdjs.RuntimeScene;\n\n /**\n * Convert a point from the canvas coordinates (for example,\n * the mouse position) to the container coordinates.\n *\n * @param x The x position, in container coordinates.\n * @param y The y position, in container coordinates.\n * @param result The point instance that is used to return the result.\n */\n abstract convertCoords(x: float, y: float, result?: FloatPoint): FloatPoint;\n\n /**\n * Convert a point from the container coordinates (for example,\n * an object position) to the canvas coordinates.\n *\n * @param sceneX The x position, in container coordinates.\n * @param sceneY The y position, in container coordinates.\n * @param result The point instance that is used to return the result.\n */\n abstract convertInverseCoords(\n sceneX: float,\n sceneY: float,\n result: FloatPoint\n ): FloatPoint;\n\n /**\n * @return the width of:\n * - the game resolution for a {@link gdjs.RuntimeScene}\n * - the default dimensions (the AABB of all its children) for a\n * {@link gdjs.CustomRuntimeObject}.\n */\n abstract getViewportWidth(): float;\n\n /**\n * @return the height of:\n * - the game resolution for a {@link gdjs.RuntimeScene}\n * - the default dimensions (the AABB of all its children) for a\n * {@link gdjs.CustomRuntimeObject}.\n */\n abstract getViewportHeight(): float;\n\n /**\n * @return the center X of:\n * - the game resolution for a {@link gdjs.RuntimeScene}\n * - the default dimensions (the AABB of all its children) for a\n * {@link gdjs.CustomRuntimeObject}.\n */\n abstract getViewportOriginX(): float;\n\n /**\n * @return the center Y of:\n * - the game resolution for a {@link gdjs.RuntimeScene}\n * - the default dimensions (the AABB of all its children) for a\n * {@link gdjs.CustomRuntimeObject}.\n */\n abstract getViewportOriginY(): float;\n\n /**\n * Triggered when the AABB of a child of the container could have changed.\n */\n abstract onChildrenLocationChanged(): void;\n\n /**\n * Activate or deactivate the debug visualization for collisions and points.\n */\n enableDebugDraw(\n enableDebugDraw: boolean,\n showHiddenInstances: boolean,\n showPointsNames: boolean,\n showCustomPoints: boolean\n ): void {\n if (this._debugDrawEnabled && !enableDebugDraw) {\n this.getDebuggerRenderer().clearDebugDraw();\n }\n\n this._debugDrawEnabled = enableDebugDraw;\n this._debugDrawShowHiddenInstances = showHiddenInstances;\n this._debugDrawShowPointsNames = showPointsNames;\n this._debugDrawShowCustomPoints = showCustomPoints;\n }\n\n /**\n * Check if an object is registered, meaning that instances of it can be\n * created and lives in the container.\n * @see gdjs.RuntimeInstanceContainer#registerObject\n */\n isObjectRegistered(objectName: string): boolean {\n return (\n this._objects.containsKey(objectName) &&\n this._instances.containsKey(objectName) &&\n this._objectsCtor.containsKey(objectName)\n );\n }\n\n /**\n * Register a {@link gdjs.RuntimeObject} so that instances of it can be\n * used in the container.\n * @param objectData The data for the object to register.\n */\n registerObject(objectData: ObjectData) {\n this._objects.put(objectData.name, objectData);\n this._instances.put(objectData.name, []);\n\n // Cache the constructor\n const Ctor = gdjs.getObjectConstructor(objectData.type);\n this._objectsCtor.put(objectData.name, Ctor);\n\n // Also prepare a cache for recycled instances, if the object supports it.\n if (Ctor.supportsReinitialization) {\n this._instancesCache.put(objectData.name, []);\n }\n }\n\n /**\n * Update the data of a {@link gdjs.RuntimeObject} so that instances use\n * this when constructed.\n * @param objectData The data for the object to register.\n */\n updateObject(objectData: ObjectData): void {\n if (!this.isObjectRegistered(objectData.name)) {\n logger.warn(\n 'Tried to call updateObject for an object that was not registered (' +\n objectData.name +\n '). Call registerObject first.'\n );\n }\n this._objects.put(objectData.name, objectData);\n }\n\n // Don't erase instances, nor instances cache, or objectsCtor cache.\n /**\n * Unregister a {@link gdjs.RuntimeObject}. Instances will be destroyed.\n * @param objectName The name of the object to unregister.\n */\n unregisterObject(objectName: string) {\n const instances = this._instances.get(objectName);\n if (instances) {\n // This is sub-optimal: markObjectForDeletion will search the instance to\n // remove in instances, so cost is O(n^2), n being the number of instances.\n // As we're unregistering an object which only happen during a hot-reloading,\n // this is fine.\n const instancesToRemove = instances.slice();\n for (let i = 0; i < instancesToRemove.length; i++) {\n this.markObjectForDeletion(instancesToRemove[i]);\n }\n this._cacheOrClearRemovedInstances();\n }\n this._objects.remove(objectName);\n this._instances.remove(objectName);\n this._instancesCache.remove(objectName);\n this._objectsCtor.remove(objectName);\n }\n\n /**\n * Create objects from initial instances data (for example, the initial instances\n * of the scene or the instances of an external layout).\n *\n * @param data The instances data\n * @param xPos The offset on X axis\n * @param yPos The offset on Y axis\n * @param zPos The offset on Z axis\n * @param trackByPersistentUuid If true, objects are tracked by setting their `persistentUuid`\n * to the same as the associated instance. Useful for hot-reloading when instances are changed.\n */\n createObjectsFrom(\n data: InstanceData[],\n xPos: float,\n yPos: float,\n zPos: float,\n trackByPersistentUuid: boolean\n ): void {\n let zOffset: number;\n let shouldTrackByPersistentUuid: boolean;\n\n if (arguments.length === 5) {\n zOffset = zPos;\n shouldTrackByPersistentUuid = trackByPersistentUuid;\n } else {\n /**\n * Support for the previous signature (before 3D was introduced):\n * createObjectsFrom(data, xPos, yPos, trackByPersistentUuid)\n */\n zOffset = 0;\n shouldTrackByPersistentUuid = arguments[3];\n }\n\n for (let i = 0, len = data.length; i < len; ++i) {\n const instanceData = data[i];\n const objectName = instanceData.name;\n const newObject = this.createObject(objectName);\n if (newObject !== null) {\n if (shouldTrackByPersistentUuid) {\n // Give the object the same persistentUuid as the instance, so that\n // it can be hot-reloaded.\n newObject.persistentUuid = instanceData.persistentUuid || null;\n }\n newObject.setPosition(instanceData.x + xPos, instanceData.y + yPos);\n newObject.setAngle(instanceData.angle);\n if (gdjs.Base3DHandler && gdjs.Base3DHandler.is3D(newObject)) {\n if (instanceData.z !== undefined)\n newObject.setZ(instanceData.z + zOffset);\n if (instanceData.rotationX !== undefined)\n newObject.setRotationX(instanceData.rotationX);\n if (instanceData.rotationY !== undefined)\n newObject.setRotationY(instanceData.rotationY);\n }\n\n newObject.setZOrder(instanceData.zOrder);\n newObject.setLayer(instanceData.layer);\n newObject\n .getVariables()\n .initFrom(instanceData.initialVariables, true);\n newObject.extraInitializationFromInitialInstance(instanceData);\n }\n }\n }\n\n /**\n * Get the data representing the initial shared data of the scene for the specified behavior.\n * @param name The name of the behavior\n * @returns The shared data for the behavior, if any.\n */\n getInitialSharedDataForBehavior(name: string): BehaviorSharedData | null {\n return this._initialBehaviorSharedData.get(name);\n }\n\n /**\n * Set the data representing the initial shared data of the scene for the specified behavior.\n * @param name The name of the behavior\n * @param sharedData The shared data for the behavior, or null to remove it.\n */\n setInitialSharedDataForBehavior(\n name: string,\n sharedData: BehaviorSharedData | null\n ): void {\n this._initialBehaviorSharedData.put(name, sharedData);\n }\n\n /**\n * Set the default Z order for each layer, which is the highest Z order found on each layer.\n * Useful as it ensures that instances created from events are, by default, shown in front\n * of other instances.\n */\n _setLayerDefaultZOrders() {\n if (\n this.getGame().getGameData().properties.useDeprecatedZeroAsDefaultZOrder\n ) {\n // Deprecated option to still support games that were made considered 0 as the\n // default Z order for all layers.\n return;\n }\n const layerHighestZOrders: Record<string, number> = {};\n const allInstances = this.getAdhocListOfAllInstances();\n for (let i = 0, len = allInstances.length; i < len; ++i) {\n const object = allInstances[i];\n let layerName = object.getLayer();\n const zOrder = object.getZOrder();\n if (\n layerHighestZOrders[layerName] === undefined ||\n layerHighestZOrders[layerName] < zOrder\n ) {\n layerHighestZOrders[layerName] = zOrder;\n }\n }\n for (let layerName in layerHighestZOrders) {\n this.getLayer(layerName).setDefaultZOrder(\n layerHighestZOrders[layerName] + 1\n );\n }\n }\n\n _updateLayersCameraCoordinates(scale: float) {\n this._layersCameraCoordinates = this._layersCameraCoordinates || {};\n for (const name in this._layers.items) {\n if (this._layers.items.hasOwnProperty(name)) {\n const theLayer = this._layers.items[name];\n this._layersCameraCoordinates[name] = this._layersCameraCoordinates[\n name\n ] || [0, 0, 0, 0];\n this._layersCameraCoordinates[name][0] =\n theLayer.getCameraX() - (theLayer.getCameraWidth() / 2) * scale;\n this._layersCameraCoordinates[name][1] =\n theLayer.getCameraY() - (theLayer.getCameraHeight() / 2) * scale;\n this._layersCameraCoordinates[name][2] =\n theLayer.getCameraX() + (theLayer.getCameraWidth() / 2) * scale;\n this._layersCameraCoordinates[name][3] =\n theLayer.getCameraY() + (theLayer.getCameraHeight() / 2) * scale;\n }\n }\n }\n\n /**\n * Called to update effects of layers before rendering.\n */\n _updateLayersPreRender() {\n for (const layer of this._orderedLayers) {\n layer.updatePreRender(this);\n }\n }\n\n /**\n * Called to update visibility of the renderers of objects\n * rendered on the scene (\"culling\"), update effects (of visible objects)\n * and give a last chance for objects to update before rendering.\n *\n * Visibility is set to false if object is hidden, or if\n * object is too far from the camera of its layer (\"culling\").\n */\n _updateObjectsPreRender() {\n const allInstancesList = this.getAdhocListOfAllInstances();\n // TODO (3D) culling - add support for 3D object culling?\n for (let i = 0, len = allInstancesList.length; i < len; ++i) {\n const object = allInstancesList[i];\n const rendererObject = object.getRendererObject();\n if (rendererObject) {\n rendererObject.visible = !object.isHidden();\n\n // Update effects, only for visible objects.\n if (rendererObject.visible) {\n this.getGame()\n .getEffectsManager()\n .updatePreRender(object.getRendererEffects(), object);\n }\n }\n\n // Perform pre-render update.\n object.updatePreRender(this);\n }\n return;\n }\n\n /**\n * Empty the list of the removed objects:\n *\n * When an object is removed from the container, it is still kept in\n * {@link gdjs.RuntimeInstanceContainer#_instancesRemoved}.\n *\n * This method should be called regularly (after events or behaviors steps) so as to clear this list\n * and allows the removed objects to be cached (or destroyed if the cache is full).\n *\n * The removed objects could not be sent directly to the cache, as events may still be using them after\n * removing them from the scene for example.\n */\n _cacheOrClearRemovedInstances() {\n for (let k = 0, lenk = this._instancesRemoved.length; k < lenk; ++k) {\n const instance = this._instancesRemoved[k];\n // Cache the instance to recycle it into a new instance later.\n // If the object does not support recycling, the cache won't be defined.\n const cache = this._instancesCache.get(instance.getName());\n if (cache) {\n if (cache.length < 128) {\n cache.push(instance);\n }\n }\n instance.onDestroyed();\n }\n this._instancesRemoved.length = 0;\n }\n\n /**\n * Tool function filling _allInstancesList member with all the living object instances.\n */\n private _constructListOfAllInstances() {\n let currentListSize = 0;\n for (const name in this._instances.items) {\n if (this._instances.items.hasOwnProperty(name)) {\n const list = this._instances.items[name];\n const oldSize = currentListSize;\n currentListSize += list.length;\n for (let j = 0, lenj = list.length; j < lenj; ++j) {\n if (oldSize + j < this._allInstancesList.length) {\n this._allInstancesList[oldSize + j] = list[j];\n } else {\n this._allInstancesList.push(list[j]);\n }\n }\n }\n }\n this._allInstancesList.length = currentListSize;\n this._allInstancesListIsUpToDate = true;\n }\n\n /**\n * @param objectName The name of the object\n * @returns the instances of a given object in the container.\n */\n getInstancesOf(objectName: string): gdjs.RuntimeObject[] {\n return this._instances.items[objectName];\n }\n\n /**\n * Get a list of all {@link gdjs.RuntimeObject} living in the container.\n * You should not, normally, need this method at all. It's only to be used\n * in exceptional use cases where you need to loop through all objects,\n * and it won't be performant.\n *\n * @returns The list of all runtime objects in the container\n */\n getAdhocListOfAllInstances(): gdjs.RuntimeObject[] {\n if (!this._allInstancesListIsUpToDate) {\n this._constructListOfAllInstances();\n }\n return this._allInstancesList;\n }\n\n /**\n * Update the objects before launching the events.\n */\n _updateObjectsPreEvents() {\n // It is *mandatory* to create and iterate on a external list of all objects, as the behaviors\n // may delete the objects.\n const allInstancesList = this.getAdhocListOfAllInstances();\n for (let i = 0, len = allInstancesList.length; i < len; ++i) {\n const obj = allInstancesList[i];\n const elapsedTime = obj.getElapsedTime();\n if (!obj.hasNoForces()) {\n const averageForce = obj.getAverageForce();\n const elapsedTimeInSeconds = elapsedTime / 1000;\n obj.setX(obj.getX() + averageForce.getX() * elapsedTimeInSeconds);\n obj.setY(obj.getY() + averageForce.getY() * elapsedTimeInSeconds);\n obj.update(this);\n obj.updateForces(elapsedTimeInSeconds);\n } else {\n obj.update(this);\n }\n obj.updateTimers(elapsedTime);\n allInstancesList[i].stepBehaviorsPreEvents(this);\n }\n\n // Some behaviors may have request objects to be deleted.\n this._cacheOrClearRemovedInstances();\n }\n\n /**\n * Update the objects (update positions, time management...)\n */\n _updateObjectsPostEvents() {\n this._cacheOrClearRemovedInstances();\n\n // It is *mandatory* to create and iterate on a external list of all objects, as the behaviors\n // may delete the objects.\n const allInstancesList = this.getAdhocListOfAllInstances();\n for (let i = 0, len = allInstancesList.length; i < len; ++i) {\n allInstancesList[i].stepBehaviorsPostEvents(this);\n }\n\n // Some behaviors may have request objects to be deleted.\n this._cacheOrClearRemovedInstances();\n }\n\n /**\n * Add an object to the instances living in the container.\n * @param obj The object to be added.\n */\n addObject(obj: gdjs.RuntimeObject) {\n if (!this._instances.containsKey(obj.name)) {\n this._instances.put(obj.name, []);\n }\n this._instances.get(obj.name).push(obj);\n this._allInstancesListIsUpToDate = false;\n }\n\n /**\n * Get all the instances of the object called name.\n * @param name Name of the object for which the instances must be returned.\n * @return The list of objects with the given name\n */\n getObjects(name: string): gdjs.RuntimeObject[] | undefined {\n if (!this._instances.containsKey(name)) {\n logger.info(\n 'RuntimeScene.getObjects: No instances called \"' +\n name +\n '\"! Adding it.'\n );\n this._instances.put(name, []);\n }\n return this._instances.get(name);\n }\n\n /**\n * Create a new object from its name. The object is also added to the instances\n * living in the container (No need to call {@link gdjs.RuntimeScene.addObject})\n * @param objectName The name of the object to be created\n * @return The created object\n */\n createObject(objectName: string): gdjs.RuntimeObject | null {\n if (\n !this._objectsCtor.containsKey(objectName) ||\n !this._objects.containsKey(objectName)\n ) {\n // There is no such object in this container.\n return null;\n }\n\n // Create a new object using the object constructor (cached during loading)\n // and the stored object's data:\n const cache = this._instancesCache.get(objectName);\n const ctor = this._objectsCtor.get(objectName);\n let obj;\n if (!cache || cache.length === 0) {\n obj = new ctor(this, this._objects.get(objectName));\n } else {\n // Reuse an objet destroyed before. If there is an object in the cache,\n // then it means it does support reinitialization.\n obj = cache.pop();\n obj.reinitialize(this._objects.get(objectName));\n }\n this.addObject(obj);\n return obj;\n }\n\n /**\n * Must be called whenever an object must be removed from the container.\n * @param obj The object to be removed.\n */\n markObjectForDeletion(obj: gdjs.RuntimeObject) {\n // Add to the objects removed list.\n // The objects will be sent to the instances cache or really deleted from memory later.\n if (this._instancesRemoved.indexOf(obj) === -1) {\n this._instancesRemoved.push(obj);\n }\n\n // Delete from the living instances.\n if (this._instances.containsKey(obj.getName())) {\n const objId = obj.id;\n const allInstances = this._instances.get(obj.getName());\n for (let i = 0, len = allInstances.length; i < len; ++i) {\n if (allInstances[i].id == objId) {\n allInstances.splice(i, 1);\n this._allInstancesListIsUpToDate = false;\n break;\n }\n }\n }\n\n // Notify the object it was removed from the container\n obj.onDeletedFromScene(this);\n\n // Notify the global callbacks\n for (let j = 0; j < gdjs.callbacksObjectDeletedFromScene.length; ++j) {\n gdjs.callbacksObjectDeletedFromScene[j](this, obj);\n }\n return;\n }\n\n /**\n * Get the layer with the given name\n * @param name The name of the layer\n * @returns The layer, or the base layer if not found\n */\n getLayer(name: string): gdjs.RuntimeLayer {\n if (this._layers.containsKey(name)) {\n return this._layers.get(name);\n }\n return this._layers.get('');\n }\n\n /**\n * Check if a layer exists\n * @param name The name of the layer\n */\n hasLayer(name: string): boolean {\n return this._layers.containsKey(name);\n }\n\n /**\n * Add a layer.\n * @param layerData The data to construct the layer\n */\n abstract addLayer(layerData: LayerData);\n\n /**\n * Remove a layer. All {@link gdjs.RuntimeObject} on this layer will\n * be moved back to the base layer.\n * @param layerName The name of the layer to remove\n */\n removeLayer(layerName: string) {\n const existingLayer = this._layers.get(layerName);\n if (!existingLayer) return;\n\n const allInstances = this.getAdhocListOfAllInstances();\n for (let i = 0; i < allInstances.length; ++i) {\n const runtimeObject = allInstances[i];\n if (runtimeObject.getLayer() === layerName) {\n runtimeObject.setLayer('');\n }\n }\n this._layers.remove(layerName);\n const layerIndex = this._orderedLayers.indexOf(existingLayer);\n this._orderedLayers.splice(layerIndex, 1);\n }\n\n /**\n * Change the position of a layer.\n *\n * @param layerName The name of the layer to reorder\n * @param index The new position in the list of layers\n */\n setLayerIndex(layerName: string, newIndex: integer): void {\n const layer: gdjs.RuntimeLayer = this._layers.get(layerName);\n if (!layer) {\n return;\n }\n const layerIndex = this._orderedLayers.indexOf(layer);\n if (layerIndex === newIndex) return;\n\n this._orderedLayers.splice(layerIndex, 1);\n this._orderedLayers.splice(newIndex, 0, layer);\n\n this.getRenderer().setLayerIndex(layer, newIndex);\n }\n\n /**\n * Fill the array passed as argument with the names of all layers\n * @param result The array where to put the layer names\n */\n getAllLayerNames(result: string[]) {\n this._layers.keys(result);\n }\n\n /**\n * Return the number of instances of the specified object living in the container.\n * @param objectName The object name for which instances must be counted.\n */\n getInstancesCountOnScene(objectName: string): integer {\n const instances = this._instances.get(objectName);\n if (instances) {\n return instances.length;\n }\n\n return 0;\n }\n\n /**\n * Update the objects positions according to their forces\n */\n updateObjectsForces(): void {\n for (const name in this._instances.items) {\n if (this._instances.items.hasOwnProperty(name)) {\n const list = this._instances.items[name];\n for (let j = 0, listLen = list.length; j < listLen; ++j) {\n const obj = list[j];\n if (!obj.hasNoForces()) {\n const averageForce = obj.getAverageForce();\n const elapsedTimeInSeconds = obj.getElapsedTime() / 1000;\n obj.setX(obj.getX() + averageForce.getX() * elapsedTimeInSeconds);\n obj.setY(obj.getY() + averageForce.getY() * elapsedTimeInSeconds);\n obj.updateForces(elapsedTimeInSeconds);\n }\n }\n }\n }\n }\n\n /**\n * Clear any data structures to make sure memory is freed as soon as\n * possible.\n */\n _destroy() {\n // It should not be necessary to reset these variables, but this help\n // ensuring that all memory related to the container is released immediately.\n this._layers = new Hashtable();\n this._orderedLayers = [];\n this._objects = new Hashtable();\n this._instances = new Hashtable();\n this._instancesCache = new Hashtable();\n this._objectsCtor = new Hashtable();\n this._allInstancesList = [];\n this._instancesRemoved = [];\n }\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/*\n * GDevelop JS Platform\n * Copyright 2013-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.\n * This project is released under the MIT License.\n */\nnamespace gdjs {\n const logger = new gdjs.Logger('RuntimeInstanceContainer');\n\n /**\n * A container of object instances rendered on screen.\n */\n export abstract class RuntimeInstanceContainer {\n _initialBehaviorSharedData: Hashtable<BehaviorSharedData | null>;\n\n /** Contains the instances living on the container */\n _instances: Hashtable<RuntimeObject[]>;\n\n /**\n * An array used to create a list of all instance when necessary.\n * @see gdjs.RuntimeInstanceContainer#_constructListOfAllInstances}\n */\n private _allInstancesList: gdjs.RuntimeObject[] = [];\n _allInstancesListIsUpToDate = true;\n\n /** Used to recycle destroyed instance instead of creating new ones. */\n _instancesCache: Hashtable<RuntimeObject[]>;\n\n /** The instances removed from the container and waiting to be sent to the cache. */\n _instancesRemoved: gdjs.RuntimeObject[] = [];\n\n /** Contains the objects data stored in the project */\n _objects: Hashtable<ObjectData>;\n _objectsCtor: Hashtable<typeof RuntimeObject>;\n\n _layers: Hashtable<RuntimeLayer>;\n _orderedLayers: RuntimeLayer[]; // TODO: should this be a single structure with _layers, to enforce its usage?\n _layersCameraCoordinates: Record<string, [float, float, float, float]> = {};\n\n // Options for the debug draw:\n _debugDrawEnabled: boolean = false;\n _debugDrawShowHiddenInstances: boolean = false;\n _debugDrawShowPointsNames: boolean = false;\n _debugDrawShowCustomPoints: boolean = false;\n\n constructor() {\n this._initialBehaviorSharedData = new Hashtable();\n this._instances = new Hashtable();\n this._instancesCache = new Hashtable();\n this._objects = new Hashtable();\n this._objectsCtor = new Hashtable();\n this._layers = new Hashtable();\n this._orderedLayers = [];\n }\n\n /**\n * Return the time elapsed since the last frame,\n * in milliseconds, for objects on the layer.\n */\n abstract getElapsedTime(): float;\n\n /**\n * Get the renderer associated to the container.\n */\n abstract getRenderer(): gdjs.RuntimeInstanceContainerRenderer;\n\n /**\n * Get the renderer for visual debugging associated to the container.\n */\n abstract getDebuggerRenderer(): gdjs.DebuggerRenderer;\n\n /**\n * Get the {@link gdjs.RuntimeGame} associated to this.\n */\n abstract getGame(): gdjs.RuntimeGame;\n\n /**\n * Get the {@link gdjs.RuntimeScene} associated to this.\n */\n abstract getScene(): gdjs.RuntimeScene;\n\n abstract getAsyncTasksManager(): gdjs.AsyncTasksManager;\n\n /**\n * Convert a point from the canvas coordinates (for example,\n * the mouse position) to the container coordinates.\n *\n * @param x The x position, in container coordinates.\n * @param y The y position, in container coordinates.\n * @param result The point instance that is used to return the result.\n */\n abstract convertCoords(x: float, y: float, result?: FloatPoint): FloatPoint;\n\n /**\n * Convert a point from the container coordinates (for example,\n * an object position) to the canvas coordinates.\n *\n * @param sceneX The x position, in container coordinates.\n * @param sceneY The y position, in container coordinates.\n * @param result The point instance that is used to return the result.\n */\n abstract convertInverseCoords(\n sceneX: float,\n sceneY: float,\n result: FloatPoint\n ): FloatPoint;\n\n /**\n * @return the left bound of:\n * - the game resolution for a {@link gdjs.RuntimeScene}\n * - the default dimensions (the AABB of all its children) for a\n * {@link gdjs.CustomRuntimeObject}.\n */\n abstract getUnrotatedViewportMinX(): float;\n\n /**\n * @return the top bound of:\n * - the game resolution for a {@link gdjs.RuntimeScene}\n * - the default dimensions (the AABB of all its children) for a\n * {@link gdjs.CustomRuntimeObject}.\n */\n abstract getUnrotatedViewportMinY(): float;\n\n /**\n * @return the right bound of:\n * - the game resolution for a {@link gdjs.RuntimeScene}\n * - the default dimensions (the AABB of all its children) for a\n * {@link gdjs.CustomRuntimeObject}.\n */\n abstract getUnrotatedViewportMaxX(): float;\n\n /**\n * @return the bottom bound of:\n * - the game resolution for a {@link gdjs.RuntimeScene}\n * - the default dimensions (the AABB of all its children) for a\n * {@link gdjs.CustomRuntimeObject}.\n */\n abstract getUnrotatedViewportMaxY(): float;\n\n /**\n * @return the left bound of:\n * - the initial game resolution for a {@link gdjs.RuntimeScene}\n * - the initial default dimensions (inner area) set in the editor for a\n * {@link gdjs.CustomRuntimeObject}.\n */\n abstract getInitialUnrotatedViewportMinX(): float;\n\n /**\n * @return the top bound of:\n * - the initial game resolution for a {@link gdjs.RuntimeScene}\n * - the initial default dimensions (inner area) set in the editor for a\n * {@link gdjs.CustomRuntimeObject}.\n */\n abstract getInitialUnrotatedViewportMinY(): float;\n\n /**\n * @return the right bound of:\n * - the initial game resolution for a {@link gdjs.RuntimeScene}\n * - the initial default dimensions (inner area) set in the editor for a\n * {@link gdjs.CustomRuntimeObject}.\n */\n abstract getInitialUnrotatedViewportMaxX(): float;\n\n /**\n * @return the bottom bound of:\n * - the initial game resolution for a {@link gdjs.RuntimeScene}\n * - the initial default dimensions (inner area) set in the editor for a\n * {@link gdjs.CustomRuntimeObject}.\n */\n abstract getInitialUnrotatedViewportMaxY(): float;\n\n /**\n * @return the width of:\n * - the game resolution for a {@link gdjs.RuntimeScene}\n * - the default dimensions (the AABB of all its children) for a\n * {@link gdjs.CustomRuntimeObject}.\n */\n abstract getViewportWidth(): float;\n\n /**\n * @return the height of:\n * - the game resolution for a {@link gdjs.RuntimeScene}\n * - the default dimensions (the AABB of all its children) for a\n * {@link gdjs.CustomRuntimeObject}.\n */\n abstract getViewportHeight(): float;\n\n /**\n * @return the center X of:\n * - the game resolution for a {@link gdjs.RuntimeScene}\n * - the default dimensions (the AABB of all its children) for a\n * {@link gdjs.CustomRuntimeObject}.\n */\n abstract getViewportOriginX(): float;\n\n /**\n * @return the center Y of:\n * - the game resolution for a {@link gdjs.RuntimeScene}\n * - the default dimensions (the AABB of all its children) for a\n * {@link gdjs.CustomRuntimeObject}.\n */\n abstract getViewportOriginY(): float;\n\n /**\n * Triggered when the AABB of a child of the container could have changed.\n */\n abstract onChildrenLocationChanged(): void;\n\n /**\n * Activate or deactivate the debug visualization for collisions and points.\n */\n enableDebugDraw(\n enableDebugDraw: boolean,\n showHiddenInstances: boolean,\n showPointsNames: boolean,\n showCustomPoints: boolean\n ): void {\n if (this._debugDrawEnabled && !enableDebugDraw) {\n this.getDebuggerRenderer().clearDebugDraw();\n }\n\n this._debugDrawEnabled = enableDebugDraw;\n this._debugDrawShowHiddenInstances = showHiddenInstances;\n this._debugDrawShowPointsNames = showPointsNames;\n this._debugDrawShowCustomPoints = showCustomPoints;\n }\n\n /**\n * Check if an object is registered, meaning that instances of it can be\n * created and lives in the container.\n * @see gdjs.RuntimeInstanceContainer#registerObject\n */\n isObjectRegistered(objectName: string): boolean {\n return (\n this._objects.containsKey(objectName) &&\n this._instances.containsKey(objectName) &&\n this._objectsCtor.containsKey(objectName)\n );\n }\n\n /**\n * Register a {@link gdjs.RuntimeObject} so that instances of it can be\n * used in the container.\n * @param objectData The data for the object to register.\n */\n registerObject(objectData: ObjectData) {\n this._objects.put(objectData.name, objectData);\n this._instances.put(objectData.name, []);\n\n // Cache the constructor\n const Ctor = gdjs.getObjectConstructor(objectData.type);\n this._objectsCtor.put(objectData.name, Ctor);\n\n // Also prepare a cache for recycled instances, if the object supports it.\n if (Ctor.supportsReinitialization) {\n this._instancesCache.put(objectData.name, []);\n }\n }\n\n /**\n * Update the data of a {@link gdjs.RuntimeObject} so that instances use\n * this when constructed.\n * @param objectData The data for the object to register.\n */\n updateObject(objectData: ObjectData): void {\n if (!this.isObjectRegistered(objectData.name)) {\n logger.warn(\n 'Tried to call updateObject for an object that was not registered (' +\n objectData.name +\n '). Call registerObject first.'\n );\n }\n this._objects.put(objectData.name, objectData);\n }\n\n // Don't erase instances, nor instances cache, or objectsCtor cache.\n /**\n * Unregister a {@link gdjs.RuntimeObject}. Instances will be destroyed.\n * @param objectName The name of the object to unregister.\n */\n unregisterObject(objectName: string) {\n const instances = this._instances.get(objectName);\n if (instances) {\n // This is sub-optimal: markObjectForDeletion will search the instance to\n // remove in instances, so cost is O(n^2), n being the number of instances.\n // As we're unregistering an object which only happen during a hot-reloading,\n // this is fine.\n const instancesToRemove = instances.slice();\n for (let i = 0; i < instancesToRemove.length; i++) {\n this.markObjectForDeletion(instancesToRemove[i]);\n }\n this._cacheOrClearRemovedInstances();\n }\n this._objects.remove(objectName);\n this._instances.remove(objectName);\n this._instancesCache.remove(objectName);\n this._objectsCtor.remove(objectName);\n }\n\n /**\n * Create objects from initial instances data (for example, the initial instances\n * of the scene or the instances of an external layout).\n *\n * @param data The instances data\n * @param xPos The offset on X axis\n * @param yPos The offset on Y axis\n * @param zPos The offset on Z axis\n * @param trackByPersistentUuid If true, objects are tracked by setting their `persistentUuid`\n * to the same as the associated instance. Useful for hot-reloading when instances are changed.\n */\n createObjectsFrom(\n data: InstanceData[],\n xPos: float,\n yPos: float,\n zPos: float,\n trackByPersistentUuid: boolean\n ): void {\n let zOffset: number;\n let shouldTrackByPersistentUuid: boolean;\n\n if (arguments.length === 5) {\n zOffset = zPos;\n shouldTrackByPersistentUuid = trackByPersistentUuid;\n } else {\n /**\n * Support for the previous signature (before 3D was introduced):\n * createObjectsFrom(data, xPos, yPos, trackByPersistentUuid)\n */\n zOffset = 0;\n shouldTrackByPersistentUuid = arguments[3];\n }\n\n for (let i = 0, len = data.length; i < len; ++i) {\n const instanceData = data[i];\n const objectName = instanceData.name;\n const newObject = this.createObject(objectName);\n if (newObject !== null) {\n if (shouldTrackByPersistentUuid) {\n // Give the object the same persistentUuid as the instance, so that\n // it can be hot-reloaded.\n newObject.persistentUuid = instanceData.persistentUuid || null;\n }\n newObject.setPosition(instanceData.x + xPos, instanceData.y + yPos);\n newObject.setAngle(instanceData.angle);\n if (gdjs.Base3DHandler && gdjs.Base3DHandler.is3D(newObject)) {\n if (instanceData.z !== undefined)\n newObject.setZ(instanceData.z + zOffset);\n if (instanceData.rotationX !== undefined)\n newObject.setRotationX(instanceData.rotationX);\n if (instanceData.rotationY !== undefined)\n newObject.setRotationY(instanceData.rotationY);\n }\n\n newObject.setZOrder(instanceData.zOrder);\n newObject.setLayer(instanceData.layer);\n newObject\n .getVariables()\n .initFrom(instanceData.initialVariables, true);\n newObject.extraInitializationFromInitialInstance(instanceData);\n }\n }\n }\n\n /**\n * Get the data representing the initial shared data of the scene for the specified behavior.\n * @param name The name of the behavior\n * @returns The shared data for the behavior, if any.\n */\n getInitialSharedDataForBehavior(name: string): BehaviorSharedData | null {\n return this._initialBehaviorSharedData.get(name);\n }\n\n /**\n * Set the data representing the initial shared data of the scene for the specified behavior.\n * @param name The name of the behavior\n * @param sharedData The shared data for the behavior, or null to remove it.\n */\n setInitialSharedDataForBehavior(\n name: string,\n sharedData: BehaviorSharedData | null\n ): void {\n this._initialBehaviorSharedData.put(name, sharedData);\n }\n\n /**\n * Set the default Z order for each layer, which is the highest Z order found on each layer.\n * Useful as it ensures that instances created from events are, by default, shown in front\n * of other instances.\n */\n _setLayerDefaultZOrders() {\n if (\n this.getGame().getGameData().properties.useDeprecatedZeroAsDefaultZOrder\n ) {\n // Deprecated option to still support games that were made considered 0 as the\n // default Z order for all layers.\n return;\n }\n const layerHighestZOrders: Record<string, number> = {};\n const allInstances = this.getAdhocListOfAllInstances();\n for (let i = 0, len = allInstances.length; i < len; ++i) {\n const object = allInstances[i];\n let layerName = object.getLayer();\n const zOrder = object.getZOrder();\n if (\n layerHighestZOrders[layerName] === undefined ||\n layerHighestZOrders[layerName] < zOrder\n ) {\n layerHighestZOrders[layerName] = zOrder;\n }\n }\n for (let layerName in layerHighestZOrders) {\n this.getLayer(layerName).setDefaultZOrder(\n layerHighestZOrders[layerName] + 1\n );\n }\n }\n\n _updateLayersCameraCoordinates(scale: float) {\n this._layersCameraCoordinates = this._layersCameraCoordinates || {};\n for (const name in this._layers.items) {\n if (this._layers.items.hasOwnProperty(name)) {\n const theLayer = this._layers.items[name];\n this._layersCameraCoordinates[name] = this._layersCameraCoordinates[\n name\n ] || [0, 0, 0, 0];\n this._layersCameraCoordinates[name][0] =\n theLayer.getCameraX() - (theLayer.getCameraWidth() / 2) * scale;\n this._layersCameraCoordinates[name][1] =\n theLayer.getCameraY() - (theLayer.getCameraHeight() / 2) * scale;\n this._layersCameraCoordinates[name][2] =\n theLayer.getCameraX() + (theLayer.getCameraWidth() / 2) * scale;\n this._layersCameraCoordinates[name][3] =\n theLayer.getCameraY() + (theLayer.getCameraHeight() / 2) * scale;\n }\n }\n }\n\n /**\n * Called to update effects of layers before rendering.\n */\n _updateLayersPreRender() {\n for (const layer of this._orderedLayers) {\n layer.updatePreRender(this);\n }\n }\n\n /**\n * Called to update visibility of the renderers of objects\n * rendered on the scene (\"culling\"), update effects (of visible objects)\n * and give a last chance for objects to update before rendering.\n *\n * Visibility is set to false if object is hidden, or if\n * object is too far from the camera of its layer (\"culling\").\n */\n _updateObjectsPreRender() {\n const allInstancesList = this.getAdhocListOfAllInstances();\n // TODO (3D) culling - add support for 3D object culling?\n for (let i = 0, len = allInstancesList.length; i < len; ++i) {\n const object = allInstancesList[i];\n const rendererObject = object.getRendererObject();\n if (rendererObject) {\n rendererObject.visible = !object.isHidden();\n\n // Update effects, only for visible objects.\n if (rendererObject.visible) {\n this.getGame()\n .getEffectsManager()\n .updatePreRender(object.getRendererEffects(), object);\n }\n }\n\n // Perform pre-render update.\n object.updatePreRender(this);\n }\n return;\n }\n\n /**\n * Empty the list of the removed objects:\n *\n * When an object is removed from the container, it is still kept in\n * {@link gdjs.RuntimeInstanceContainer#_instancesRemoved}.\n *\n * This method should be called regularly (after events or behaviors steps) so as to clear this list\n * and allows the removed objects to be cached (or destroyed if the cache is full).\n *\n * The removed objects could not be sent directly to the cache, as events may still be using them after\n * removing them from the scene for example.\n */\n _cacheOrClearRemovedInstances() {\n for (let k = 0, lenk = this._instancesRemoved.length; k < lenk; ++k) {\n const instance = this._instancesRemoved[k];\n // Cache the instance to recycle it into a new instance later.\n // If the object does not support recycling, the cache won't be defined.\n const cache = this._instancesCache.get(instance.getName());\n if (cache) {\n if (cache.length < 128) {\n cache.push(instance);\n }\n }\n instance.onDestroyed();\n }\n this._instancesRemoved.length = 0;\n }\n\n /**\n * Tool function filling _allInstancesList member with all the living object instances.\n */\n private _constructListOfAllInstances() {\n let currentListSize = 0;\n for (const name in this._instances.items) {\n if (this._instances.items.hasOwnProperty(name)) {\n const list = this._instances.items[name];\n const oldSize = currentListSize;\n currentListSize += list.length;\n for (let j = 0, lenj = list.length; j < lenj; ++j) {\n if (oldSize + j < this._allInstancesList.length) {\n this._allInstancesList[oldSize + j] = list[j];\n } else {\n this._allInstancesList.push(list[j]);\n }\n }\n }\n }\n this._allInstancesList.length = currentListSize;\n this._allInstancesListIsUpToDate = true;\n }\n\n /**\n * @param objectName The name of the object\n * @returns the instances of a given object in the container.\n */\n getInstancesOf(objectName: string): gdjs.RuntimeObject[] {\n return this._instances.items[objectName];\n }\n\n /**\n * Get a list of all {@link gdjs.RuntimeObject} living in the container.\n * You should not, normally, need this method at all. It's only to be used\n * in exceptional use cases where you need to loop through all objects,\n * and it won't be performant.\n *\n * @returns The list of all runtime objects in the container\n */\n getAdhocListOfAllInstances(): gdjs.RuntimeObject[] {\n if (!this._allInstancesListIsUpToDate) {\n this._constructListOfAllInstances();\n }\n return this._allInstancesList;\n }\n\n /**\n * Update the objects before launching the events.\n */\n _updateObjectsPreEvents() {\n // It is *mandatory* to create and iterate on a external list of all objects, as the behaviors\n // may delete the objects.\n const allInstancesList = this.getAdhocListOfAllInstances();\n for (let i = 0, len = allInstancesList.length; i < len; ++i) {\n const obj = allInstancesList[i];\n const elapsedTime = obj.getElapsedTime();\n if (!obj.hasNoForces()) {\n const averageForce = obj.getAverageForce();\n const elapsedTimeInSeconds = elapsedTime / 1000;\n obj.setX(obj.getX() + averageForce.getX() * elapsedTimeInSeconds);\n obj.setY(obj.getY() + averageForce.getY() * elapsedTimeInSeconds);\n obj.update(this);\n obj.updateForces(elapsedTimeInSeconds);\n } else {\n obj.update(this);\n }\n obj.updateTimers(elapsedTime);\n allInstancesList[i].stepBehaviorsPreEvents(this);\n }\n\n // Some behaviors may have request objects to be deleted.\n this._cacheOrClearRemovedInstances();\n }\n\n /**\n * Update the objects (update positions, time management...)\n */\n _updateObjectsPostEvents() {\n this._cacheOrClearRemovedInstances();\n\n // It is *mandatory* to create and iterate on a external list of all objects, as the behaviors\n // may delete the objects.\n const allInstancesList = this.getAdhocListOfAllInstances();\n for (let i = 0, len = allInstancesList.length; i < len; ++i) {\n allInstancesList[i].stepBehaviorsPostEvents(this);\n }\n\n // Some behaviors may have request objects to be deleted.\n this._cacheOrClearRemovedInstances();\n }\n\n /**\n * Add an object to the instances living in the container.\n * @param obj The object to be added.\n */\n addObject(obj: gdjs.RuntimeObject) {\n if (!this._instances.containsKey(obj.name)) {\n this._instances.put(obj.name, []);\n }\n this._instances.get(obj.name).push(obj);\n this._allInstancesListIsUpToDate = false;\n }\n\n /**\n * Get all the instances of the object called name.\n * @param name Name of the object for which the instances must be returned.\n * @return The list of objects with the given name\n */\n getObjects(name: string): gdjs.RuntimeObject[] | undefined {\n if (!this._instances.containsKey(name)) {\n logger.info(\n 'RuntimeScene.getObjects: No instances called \"' +\n name +\n '\"! Adding it.'\n );\n this._instances.put(name, []);\n }\n return this._instances.get(name);\n }\n\n /**\n * Create a new object from its name. The object is also added to the instances\n * living in the container (No need to call {@link gdjs.RuntimeScene.addObject})\n * @param objectName The name of the object to be created\n * @return The created object\n */\n createObject(objectName: string): gdjs.RuntimeObject | null {\n if (\n !this._objectsCtor.containsKey(objectName) ||\n !this._objects.containsKey(objectName)\n ) {\n // There is no such object in this container.\n return null;\n }\n\n // Create a new object using the object constructor (cached during loading)\n // and the stored object's data:\n const cache = this._instancesCache.get(objectName);\n const ctor = this._objectsCtor.get(objectName);\n let obj;\n if (!cache || cache.length === 0) {\n obj = new ctor(this, this._objects.get(objectName));\n } else {\n // Reuse an objet destroyed before. If there is an object in the cache,\n // then it means it does support reinitialization.\n obj = cache.pop();\n obj.reinitialize(this._objects.get(objectName));\n }\n this.addObject(obj);\n return obj;\n }\n\n /**\n * Must be called whenever an object must be removed from the container.\n * @param obj The object to be removed.\n */\n markObjectForDeletion(obj: gdjs.RuntimeObject) {\n // Add to the objects removed list.\n // The objects will be sent to the instances cache or really deleted from memory later.\n if (this._instancesRemoved.indexOf(obj) === -1) {\n this._instancesRemoved.push(obj);\n }\n\n // Delete from the living instances.\n if (this._instances.containsKey(obj.getName())) {\n const objId = obj.id;\n const allInstances = this._instances.get(obj.getName());\n for (let i = 0, len = allInstances.length; i < len; ++i) {\n if (allInstances[i].id == objId) {\n allInstances.splice(i, 1);\n this._allInstancesListIsUpToDate = false;\n break;\n }\n }\n }\n\n // Notify the object it was removed from the container\n obj.onDeletedFromScene(this);\n\n // Notify the global callbacks\n for (let j = 0; j < gdjs.callbacksObjectDeletedFromScene.length; ++j) {\n gdjs.callbacksObjectDeletedFromScene[j](this, obj);\n }\n return;\n }\n\n /**\n * Get the layer with the given name\n * @param name The name of the layer\n * @returns The layer, or the base layer if not found\n */\n getLayer(name: string): gdjs.RuntimeLayer {\n if (this._layers.containsKey(name)) {\n return this._layers.get(name);\n }\n return this._layers.get('');\n }\n\n /**\n * Check if a layer exists\n * @param name The name of the layer\n */\n hasLayer(name: string): boolean {\n return this._layers.containsKey(name);\n }\n\n /**\n * Add a layer.\n * @param layerData The data to construct the layer\n */\n abstract addLayer(layerData: LayerData);\n\n /**\n * Remove a layer. All {@link gdjs.RuntimeObject} on this layer will\n * be moved back to the base layer.\n * @param layerName The name of the layer to remove\n */\n removeLayer(layerName: string) {\n const existingLayer = this._layers.get(layerName);\n if (!existingLayer) return;\n\n const allInstances = this.getAdhocListOfAllInstances();\n for (let i = 0; i < allInstances.length; ++i) {\n const runtimeObject = allInstances[i];\n if (runtimeObject.getLayer() === layerName) {\n runtimeObject.setLayer('');\n }\n }\n this._layers.remove(layerName);\n const layerIndex = this._orderedLayers.indexOf(existingLayer);\n this._orderedLayers.splice(layerIndex, 1);\n }\n\n /**\n * Change the position of a layer.\n *\n * @param layerName The name of the layer to reorder\n * @param index The new position in the list of layers\n */\n setLayerIndex(layerName: string, newIndex: integer): void {\n const layer: gdjs.RuntimeLayer = this._layers.get(layerName);\n if (!layer) {\n return;\n }\n const layerIndex = this._orderedLayers.indexOf(layer);\n if (layerIndex === newIndex) return;\n\n this._orderedLayers.splice(layerIndex, 1);\n this._orderedLayers.splice(newIndex, 0, layer);\n\n this.getRenderer().setLayerIndex(layer, newIndex);\n }\n\n /**\n * Fill the array passed as argument with the names of all layers\n * @param result The array where to put the layer names\n */\n getAllLayerNames(result: string[]) {\n this._layers.keys(result);\n }\n\n /**\n * Return the number of instances of the specified object living in the container.\n * @param objectName The object name for which instances must be counted.\n */\n getInstancesCountOnScene(objectName: string): integer {\n const instances = this._instances.get(objectName);\n if (instances) {\n return instances.length;\n }\n\n return 0;\n }\n\n /**\n * Update the objects positions according to their forces\n */\n updateObjectsForces(): void {\n for (const name in this._instances.items) {\n if (this._instances.items.hasOwnProperty(name)) {\n const list = this._instances.items[name];\n for (let j = 0, listLen = list.length; j < listLen; ++j) {\n const obj = list[j];\n if (!obj.hasNoForces()) {\n const averageForce = obj.getAverageForce();\n const elapsedTimeInSeconds = obj.getElapsedTime() / 1000;\n obj.setX(obj.getX() + averageForce.getX() * elapsedTimeInSeconds);\n obj.setY(obj.getY() + averageForce.getY() * elapsedTimeInSeconds);\n obj.updateForces(elapsedTimeInSeconds);\n }\n }\n }\n }\n }\n\n /**\n * Clear any data structures to make sure memory is freed as soon as\n * possible.\n */\n _destroy() {\n // It should not be necessary to reset these variables, but this help\n // ensuring that all memory related to the container is released immediately.\n this._layers = new Hashtable();\n this._orderedLayers = [];\n this._objects = new Hashtable();\n this._instances = new Hashtable();\n this._instancesCache = new Hashtable();\n this._objectsCtor = new Hashtable();\n this._allInstancesList = [];\n this._instancesRemoved = [];\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,2 +1,2 @@
1
- var gdjs;(function(a){class u{constructor(t,i){this.center={x:0,y:0};this.origin={x:0,y:0};this.hasCustomHitBoxes=!1;this.customHitBoxes=[];this.image=t?t.image:"",this.texture=i.getAnimationFrameTexture(this.image),this.points=new Hashtable,this.reinitialize(t,i)}reinitialize(t,i){this.points.clear();for(let n=0,o=t.points.length;n<o;++n){const m=t.points[n],s={x:m.x,y:m.y};this.points.put(m.name,s)}const e=t.originPoint;this.origin.x=e.x,this.origin.y=e.y;const r=t.centerPoint;if(r.automatic!==!0?(this.center.x=r.x,this.center.y=r.y):(this.center.x=i.getAnimationFrameWidth(this.texture)/2,this.center.y=i.getAnimationFrameHeight(this.texture)/2),t.hasCustomCollisionMask){this.hasCustomHitBoxes=!0;let n=0;for(let o=t.customCollisionMask.length;n<o;++n){const m=t.customCollisionMask[n];n>=this.customHitBoxes.length&&this.customHitBoxes.push(new a.Polygon);let s=0;for(const c=m.length;s<c;++s){const l=m[s];s>=this.customHitBoxes[n].vertices.length&&this.customHitBoxes[n].vertices.push([0,0]),this.customHitBoxes[n].vertices[s][0]=l.x,this.customHitBoxes[n].vertices[s][1]=l.y}this.customHitBoxes[n].vertices.length=s}this.customHitBoxes.length=n}else this.customHitBoxes.length=0}getPoint(t){return t==="Centre"||t==="Center"?this.center:t==="Origin"?this.origin:this.points.containsKey(t)?this.points.get(t):this.origin}}a.SpriteAnimationFrame=u;class _{constructor(t,i){this.frames=[];this.timeBetweenFrames=t?t.timeBetweenFrames:1,this.loop=!!t.looping,this.reinitialize(t,i)}reinitialize(t,i){this.timeBetweenFrames=t?t.timeBetweenFrames:1,this.loop=!!t.looping;let e=0;for(const r=t.sprites.length;e<r;++e){const n=t.sprites[e];e<this.frames.length?this.frames[e].reinitialize(n,i):this.frames.push(new a.SpriteAnimationFrame(n,i))}this.frames.length=e}}a.SpriteAnimationDirection=_;class p{constructor(t,i){this.directions=[];this.hasMultipleDirections=!!t.useMultipleDirections,this.name=t.name||"",this.reinitialize(t,i)}reinitialize(t,i){this.hasMultipleDirections=!!t.useMultipleDirections,this.name=t.name||"";let e=0;for(const r=t.directions.length;e<r;++e){const n=t.directions[e];e<this.directions.length?this.directions[e].reinitialize(n,i):this.directions.push(new a.SpriteAnimationDirection(n,i))}this.directions.length=e}}a.SpriteAnimation=p;class g{constructor(t,i){this._animations=[];this._animationFrame=null;this._animationFrameDirty=!0;this._currentAnimation=0;this._currentDirection=0;this._currentFrameIndex=0;this._animationElapsedTime=0;this._animationSpeedScale=1;this._animationPaused=!1;this._onFrameChange=null;this._textureManager=i;for(let e=0,r=t.length;e<r;++e)this._animations.push(new a.SpriteAnimation(t[e],i))}invalidateFrame(){this._animationFrameDirty=!0,this._onFrameChange&&this._onFrameChange()}reinitialize(t){this._currentAnimation=0,this._currentDirection=0,this._currentFrameIndex=0,this._animationElapsedTime=0,this._animationSpeedScale=1,this._animationPaused=!1;let i=0;for(const e=t.length;i<e;++i){const r=t[i];i<this._animations.length?this._animations[i].reinitialize(r,this._textureManager):this._animations.push(new a.SpriteAnimation(r,this._textureManager))}this._animations.length=i,this._animationFrame=null,this.invalidateFrame()}updateFromObjectData(t,i){let e=0;for(const n=i.length;e<n;++e){const o=i[e];e<this._animations.length?this._animations[e].reinitialize(o,this._textureManager):this._animations.push(new a.SpriteAnimation(o,this._textureManager))}return this._animations.length=e,this.invalidateFrame(),this.getCurrentFrame()||this.setAnimationIndex(0),!0}getNetworkSyncData(){return{an:this._currentAnimation,di:this._currentDirection,fr:this._currentFrameIndex,et:this._animationElapsedTime,ss:this._animationSpeedScale,pa:this._animationPaused}}updateFromNetworkSyncData(t){this._currentAnimation=t.an,this._currentDirection=t.di,this._currentFrameIndex=t.fr,this._animationElapsedTime=t.et,this._animationSpeedScale=t.ss,this._animationPaused=t.pa,this.invalidateFrame()}getCurrentFrame(){if(!this._animationFrameDirty)return this._animationFrame;if(this._animationFrameDirty=!1,this._currentAnimation<this._animations.length&&this._currentDirection<this._animations[this._currentAnimation].directions.length){const t=this._animations[this._currentAnimation].directions[this._currentDirection];if(this._currentFrameIndex<t.frames.length)return this._animationFrame=t.frames[this._currentFrameIndex],this._animationFrame}return this._animationFrame=null,this._animationFrame}step(t){if(this._currentAnimation>=this._animations.length||this._currentDirection>=this._animations[this._currentAnimation].directions.length)return!1;const i=this._animations[this._currentAnimation].directions[this._currentDirection],e=this.getAnimationDuration();if(!this._animationPaused&&(i.loop||this._animationElapsedTime!==e)&&i.timeBetweenFrames){const r=this._animationElapsedTime+t*this._animationSpeedScale;return this.setAnimationElapsedTime(i.loop?a.evtTools.common.mod(r,e):a.evtTools.common.clamp(r,0,e))}return!1}setOnFrameChangeCallback(t){this._onFrameChange=t}getAnimationIndex(){return this._currentAnimation}setAnimationIndex(t){return t=t|0,t<this._animations.length&&this._currentAnimation!==t&&t>=0?(this._currentAnimation=t,this._currentFrameIndex=0,this._animationElapsedTime=0,this.invalidateFrame(),!0):!1}getAnimationName(){return this._currentAnimation>=this._animations.length?"":this._animations[this._currentAnimation].name}setAnimationName(t){if(!t)return!1;for(let i=0;i<this._animations.length;++i)if(this._animations[i].name===t)return this.setAnimationIndex(i),!0;return!1}hasAnimationEnded(){if(this._currentAnimation>=this._animations.length||this._currentDirection>=this._animations[this._currentAnimation].directions.length)return!0;const t=this._animations[this._currentAnimation].directions[this._currentDirection];return t.loop?!1:this._currentFrameIndex===t.frames.length-1&&this._animationElapsedTime===t.frames.length*t.timeBetweenFrames}isAnimationPaused(){return this._animationPaused}pauseAnimation(){this._animationPaused=!0}resumeAnimation(){this._animationPaused=!1}getAnimationSpeedScale(){return this._animationSpeedScale}setAnimationSpeedScale(t){this._animationSpeedScale=t}setAnimationFrameIndex(t){if(this._currentAnimation>=this._animations.length||this._currentDirection>=this._animations[this._currentAnimation].directions.length)return!1;const i=this._animations[this._currentAnimation].directions[this._currentDirection];return t>=0&&t<i.frames.length&&t!==this._currentFrameIndex?(this._currentFrameIndex=t,this._animationElapsedTime=t*i.timeBetweenFrames,this.invalidateFrame(),!0):!1}getAnimationFrameIndex(){return this._currentFrameIndex}getAnimationElapsedTime(){return this._animationElapsedTime}setAnimationElapsedTime(t){const i=this._animations[this._currentAnimation].directions[this._currentDirection];this._animationElapsedTime=a.evtTools.common.clamp(t,0,this.getAnimationDuration());const e=this._currentFrameIndex;return this._currentFrameIndex=Math.min(Math.floor(this._animationElapsedTime/i.timeBetweenFrames),i.frames.length-1),e!==this._currentFrameIndex?(this.invalidateFrame(),!0):!1}getAnimationDuration(){const t=this._animations[this._currentAnimation].directions[this._currentDirection];return t.frames.length*t.timeBetweenFrames}getAnimationFrameCount(){if(this._currentAnimation>=this._animations.length)return 0;const t=this._animations[this._currentAnimation];return this._currentDirection>=t.directions.length?0:t.directions[this._currentDirection].frames.length}setDirectionOrAngle(t,i){if(this._currentAnimation>=this._animations.length)return null;const e=this._animations[this._currentAnimation];return e.hasMultipleDirections?(i=i|0,i===this._currentDirection||i>=e.directions.length||e.directions[i].frames.length===0?null:(this._currentDirection=i,this._currentFrameIndex=0,this._animationElapsedTime=0,this.invalidateFrame(),0)):t===i?null:i}getDirectionOrAngle(t){return this._currentAnimation>=this._animations.length?0:this._animations[this._currentAnimation].hasMultipleDirections?this._currentDirection:t}getAngle(t){return this._currentAnimation>=this._animations.length?0:this._animations[this._currentAnimation].hasMultipleDirections?this._currentDirection*45:t}setAngle(t,i){return this._currentAnimation>=this._animations.length?null:this._animations[this._currentAnimation].hasMultipleDirections?(i=i%360,i<0&&(i+=360),this.setDirectionOrAngle(t,Math.round(i/45)%8)):t===i?null:i}hasAnimationEndedLegacy(){if(this._currentAnimation>=this._animations.length||this._currentDirection>=this._animations[this._currentAnimation].directions.length)return!0;const t=this._animations[this._currentAnimation].directions[this._currentDirection];return t.loop?!1:this._currentFrameIndex===t.frames.length-1}}a.SpriteAnimator=g})(gdjs||(gdjs={}));
1
+ var gdjs;(function(a){class c{constructor(t,i){this.center={x:0,y:0};this.origin={x:0,y:0};this.hasCustomHitBoxes=!1;this.customHitBoxes=[];this.image=t?t.image:"",this.texture=i.getAnimationFrameTexture(this.image),this.points=new Hashtable,this.reinitialize(t,i)}reinitialize(t,i){this.image=t.image,this.texture=i.getAnimationFrameTexture(this.image),this.points.clear();for(let n=0,o=t.points.length;n<o;++n){const m=t.points[n],s={x:m.x,y:m.y};this.points.put(m.name,s)}const e=t.originPoint;this.origin.x=e.x,this.origin.y=e.y;const r=t.centerPoint;if(r.automatic!==!0?(this.center.x=r.x,this.center.y=r.y):(this.center.x=i.getAnimationFrameWidth(this.texture)/2,this.center.y=i.getAnimationFrameHeight(this.texture)/2),t.hasCustomCollisionMask){this.hasCustomHitBoxes=!0;let n=0;for(let o=t.customCollisionMask.length;n<o;++n){const m=t.customCollisionMask[n];n>=this.customHitBoxes.length&&this.customHitBoxes.push(new a.Polygon);let s=0;for(const u=m.length;s<u;++s){const l=m[s];s>=this.customHitBoxes[n].vertices.length&&this.customHitBoxes[n].vertices.push([0,0]),this.customHitBoxes[n].vertices[s][0]=l.x,this.customHitBoxes[n].vertices[s][1]=l.y}this.customHitBoxes[n].vertices.length=s}this.customHitBoxes.length=n}else this.customHitBoxes.length=0}getPoint(t){return t==="Centre"||t==="Center"?this.center:t==="Origin"?this.origin:this.points.containsKey(t)?this.points.get(t):this.origin}}a.SpriteAnimationFrame=c;class _{constructor(t,i){this.frames=[];this.timeBetweenFrames=t?t.timeBetweenFrames:1,this.loop=!!t.looping,this.reinitialize(t,i)}reinitialize(t,i){this.timeBetweenFrames=t?t.timeBetweenFrames:1,this.loop=!!t.looping;let e=0;for(const r=t.sprites.length;e<r;++e){const n=t.sprites[e];e<this.frames.length?this.frames[e].reinitialize(n,i):this.frames.push(new a.SpriteAnimationFrame(n,i))}this.frames.length=e}}a.SpriteAnimationDirection=_;class p{constructor(t,i){this.directions=[];this.hasMultipleDirections=!!t.useMultipleDirections,this.name=t.name||"",this.reinitialize(t,i)}reinitialize(t,i){this.hasMultipleDirections=!!t.useMultipleDirections,this.name=t.name||"";let e=0;for(const r=t.directions.length;e<r;++e){const n=t.directions[e];e<this.directions.length?this.directions[e].reinitialize(n,i):this.directions.push(new a.SpriteAnimationDirection(n,i))}this.directions.length=e}}a.SpriteAnimation=p;class g{constructor(t,i){this._animations=[];this._animationFrame=null;this._animationFrameDirty=!0;this._currentAnimation=0;this._currentDirection=0;this._currentFrameIndex=0;this._animationElapsedTime=0;this._animationSpeedScale=1;this._animationPaused=!1;this._onFrameChange=null;this._textureManager=i;for(let e=0,r=t.length;e<r;++e)this._animations.push(new a.SpriteAnimation(t[e],i))}invalidateFrame(){this._animationFrameDirty=!0,this._onFrameChange&&this._onFrameChange()}reinitialize(t){this._currentAnimation=0,this._currentDirection=0,this._currentFrameIndex=0,this._animationElapsedTime=0,this._animationSpeedScale=1,this._animationPaused=!1;let i=0;for(const e=t.length;i<e;++i){const r=t[i];i<this._animations.length?this._animations[i].reinitialize(r,this._textureManager):this._animations.push(new a.SpriteAnimation(r,this._textureManager))}this._animations.length=i,this._animationFrame=null,this.invalidateFrame()}updateFromObjectData(t,i){let e=0;for(const n=i.length;e<n;++e){const o=i[e];e<this._animations.length?this._animations[e].reinitialize(o,this._textureManager):this._animations.push(new a.SpriteAnimation(o,this._textureManager))}return this._animations.length=e,this.invalidateFrame(),this.getCurrentFrame()||this.setAnimationIndex(0),!0}getNetworkSyncData(){return{an:this._currentAnimation,di:this._currentDirection,fr:this._currentFrameIndex,et:this._animationElapsedTime,ss:this._animationSpeedScale,pa:this._animationPaused}}updateFromNetworkSyncData(t){this._currentAnimation=t.an,this._currentDirection=t.di,this._currentFrameIndex=t.fr,this._animationElapsedTime=t.et,this._animationSpeedScale=t.ss,this._animationPaused=t.pa,this.invalidateFrame()}getCurrentFrame(){if(!this._animationFrameDirty)return this._animationFrame;if(this._animationFrameDirty=!1,this._currentAnimation<this._animations.length&&this._currentDirection<this._animations[this._currentAnimation].directions.length){const t=this._animations[this._currentAnimation].directions[this._currentDirection];if(this._currentFrameIndex<t.frames.length)return this._animationFrame=t.frames[this._currentFrameIndex],this._animationFrame}return this._animationFrame=null,this._animationFrame}step(t){if(this._currentAnimation>=this._animations.length||this._currentDirection>=this._animations[this._currentAnimation].directions.length)return!1;const i=this._animations[this._currentAnimation].directions[this._currentDirection],e=this.getAnimationDuration();if(!this._animationPaused&&(i.loop||this._animationElapsedTime!==e)&&i.timeBetweenFrames){const r=this._animationElapsedTime+t*this._animationSpeedScale;return this.setAnimationElapsedTime(i.loop?a.evtTools.common.mod(r,e):a.evtTools.common.clamp(r,0,e))}return!1}setOnFrameChangeCallback(t){this._onFrameChange=t}getAnimationIndex(){return this._currentAnimation}setAnimationIndex(t){return t=t|0,t<this._animations.length&&this._currentAnimation!==t&&t>=0?(this._currentAnimation=t,this._currentFrameIndex=0,this._animationElapsedTime=0,this.invalidateFrame(),!0):!1}getAnimationName(){return this._currentAnimation>=this._animations.length?"":this._animations[this._currentAnimation].name}setAnimationName(t){if(!t)return!1;for(let i=0;i<this._animations.length;++i)if(this._animations[i].name===t)return this.setAnimationIndex(i),!0;return!1}hasAnimationEnded(){if(this._currentAnimation>=this._animations.length||this._currentDirection>=this._animations[this._currentAnimation].directions.length)return!0;const t=this._animations[this._currentAnimation].directions[this._currentDirection];return t.loop?!1:this._currentFrameIndex===t.frames.length-1&&this._animationElapsedTime===t.frames.length*t.timeBetweenFrames}isAnimationPaused(){return this._animationPaused}pauseAnimation(){this._animationPaused=!0}resumeAnimation(){this._animationPaused=!1}getAnimationSpeedScale(){return this._animationSpeedScale}setAnimationSpeedScale(t){this._animationSpeedScale=t}setAnimationFrameIndex(t){if(this._currentAnimation>=this._animations.length||this._currentDirection>=this._animations[this._currentAnimation].directions.length)return!1;const i=this._animations[this._currentAnimation].directions[this._currentDirection];return t>=0&&t<i.frames.length&&t!==this._currentFrameIndex?(this._currentFrameIndex=t,this._animationElapsedTime=t*i.timeBetweenFrames,this.invalidateFrame(),!0):!1}getAnimationFrameIndex(){return this._currentFrameIndex}getAnimationElapsedTime(){return this._animationElapsedTime}setAnimationElapsedTime(t){const i=this._animations[this._currentAnimation].directions[this._currentDirection];this._animationElapsedTime=a.evtTools.common.clamp(t,0,this.getAnimationDuration());const e=this._currentFrameIndex;return this._currentFrameIndex=Math.min(Math.floor(this._animationElapsedTime/i.timeBetweenFrames),i.frames.length-1),e!==this._currentFrameIndex?(this.invalidateFrame(),!0):!1}getAnimationDuration(){const t=this._animations[this._currentAnimation].directions[this._currentDirection];return t.frames.length*t.timeBetweenFrames}getAnimationFrameCount(){if(this._currentAnimation>=this._animations.length)return 0;const t=this._animations[this._currentAnimation];return this._currentDirection>=t.directions.length?0:t.directions[this._currentDirection].frames.length}setDirectionOrAngle(t,i){if(this._currentAnimation>=this._animations.length)return null;const e=this._animations[this._currentAnimation];return e.hasMultipleDirections?(i=i|0,i===this._currentDirection||i>=e.directions.length||e.directions[i].frames.length===0?null:(this._currentDirection=i,this._currentFrameIndex=0,this._animationElapsedTime=0,this.invalidateFrame(),0)):t===i?null:i}getDirectionOrAngle(t){return this._currentAnimation>=this._animations.length?0:this._animations[this._currentAnimation].hasMultipleDirections?this._currentDirection:t}getAngle(t){return this._currentAnimation>=this._animations.length?0:this._animations[this._currentAnimation].hasMultipleDirections?this._currentDirection*45:t}setAngle(t,i){return this._currentAnimation>=this._animations.length?null:this._animations[this._currentAnimation].hasMultipleDirections?(i=i%360,i<0&&(i+=360),this.setDirectionOrAngle(t,Math.round(i/45)%8)):t===i?null:i}hasAnimationEndedLegacy(){if(this._currentAnimation>=this._animations.length||this._currentDirection>=this._animations[this._currentAnimation].directions.length)return!0;const t=this._animations[this._currentAnimation].directions[this._currentDirection];return t.loop?!1:this._currentFrameIndex===t.frames.length-1}}a.SpriteAnimator=g})(gdjs||(gdjs={}));
2
2
  //# sourceMappingURL=SpriteAnimator.js.map
@@ -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
  }