From ed17e7f16ee3cb98013926ae7ceb95605e87d243 Mon Sep 17 00:00:00 2001 From: Dennis Postma Date: Sat, 2 Nov 2024 02:20:34 +0100 Subject: [PATCH] #217: Solved duplicate texture loading issue, #215: Finished Dexie implementation. --- package-lock.json | 137 +++++++++++++----- .../zoneEditor/zonePartials/ZoneObject.vue | 12 +- src/components/sprites/Character.vue | 16 +- src/components/zone/partials/ZoneObject.vue | 17 +-- src/composables/gameComposable.ts | 64 +++++--- 5 files changed, 163 insertions(+), 83 deletions(-) diff --git a/package-lock.json b/package-lock.json index f99c517..ca25188 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1283,6 +1283,7 @@ "integrity": "sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { "detect-libc": "^1.0.3", "is-glob": "^4.0.3", @@ -1928,9 +1929,9 @@ } }, "node_modules/@types/node": { - "version": "20.17.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.4.tgz", - "integrity": "sha512-Fi1Bj8qTJr4f1FDdHFR7oMlOawEYSzkHNdBJK+aRjcDDNHwEV3jPPjuZP2Lh2QNgXeqzM8Y+U6b6urKAog2rZw==", + "version": "20.17.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.5.tgz", + "integrity": "sha512-n8FYY/pRxu496441gIcAQFZPKXbhsd6VZygcq+PTSZ75eMh/Ke0hCAROdUa21qiFqKNsPPYic46yXDO1JGiPBQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2426,14 +2427,14 @@ "license": "MIT" }, "node_modules/@vue/devtools-core": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@vue/devtools-core/-/devtools-core-7.6.1.tgz", - "integrity": "sha512-wnxvfcz5uGPjG7wIQkIlapmO0TYr+8p2MNFsPfhQFPdpu0miEmQXVxyNetAFrK7GfTrC0suOuq0J1Otez9gz1A==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@vue/devtools-core/-/devtools-core-7.6.2.tgz", + "integrity": "sha512-hJfjNR3ai94Mb6i0PB42kxUPkPreS6Dl07FUaHAcw+umtkUX55jTXe7+mhsHx9NI6NFT+1WMFREIy8O81KLYyA==", "dev": true, "license": "MIT", "dependencies": { - "@vue/devtools-kit": "^7.6.1", - "@vue/devtools-shared": "^7.6.1", + "@vue/devtools-kit": "^7.6.2", + "@vue/devtools-shared": "^7.6.2", "mitt": "^3.0.1", "nanoid": "^3.3.4", "pathe": "^1.1.2", @@ -2444,13 +2445,13 @@ } }, "node_modules/@vue/devtools-kit": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.6.1.tgz", - "integrity": "sha512-cCcdskZDLqKwJUHq1+kH9zAfYM+y9OFq8J2NT0xcAUYpu8K5IJd03ydZkvr7ydOd9UKBxrGyZpYe9PpJ0ChrVw==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.6.2.tgz", + "integrity": "sha512-k61BxHRmcTtIQZFouF9QWt9nCCNtSdw12lhg8VNtHq5/XOBGD+ewiK27a40UJ8UPYoCJvi80hbvbYr5E/Zeu1g==", "dev": true, "license": "MIT", "dependencies": { - "@vue/devtools-shared": "^7.6.1", + "@vue/devtools-shared": "^7.6.2", "birpc": "^0.2.19", "hookable": "^5.5.3", "mitt": "^3.0.1", @@ -2460,9 +2461,9 @@ } }, "node_modules/@vue/devtools-shared": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.6.1.tgz", - "integrity": "sha512-SdIif2YoOWo8/s8c1+NU67jcx8qoSjM9caetQnjl3++Kufo0qa5JRZe95iV6vvupQzVGGo3ACY0LTyAsMfGeCg==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.6.2.tgz", + "integrity": "sha512-lcjyJ7hCC0W0kNwnCGMLVTMvDLoZgjcq9BvboPgS+6jQyDul7fpzRSKTGtGhCHoxrDox7qBAKGbAl2Rcf7GE1A==", "dev": true, "license": "MIT", "dependencies": { @@ -3358,6 +3359,17 @@ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "license": "MIT" }, + "node_modules/dagre": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/dagre/-/dagre-0.8.5.tgz", + "integrity": "sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graphlib": "^2.1.8", + "lodash": "^4.17.15" + } + }, "node_modules/data-urls": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", @@ -3478,6 +3490,7 @@ "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", "dev": true, "license": "Apache-2.0", + "optional": true, "bin": { "detect-libc": "bin/detect-libc.js" }, @@ -3584,9 +3597,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.49", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.49.tgz", - "integrity": "sha512-ZXfs1Of8fDb6z7WEYZjXpgIRF6MEu8JdeGA0A40aZq6OQbS+eJpnnV49epZRna2DU/YsEjSQuGtQPPtvt6J65A==", + "version": "1.5.50", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.50.tgz", + "integrity": "sha512-eMVObiUQ2LdgeO1F/ySTXsvqvxb6ZH2zPGaMYsWzRDdOddUa77tdmI0ltg+L16UpbWdhPmuF3wIQYyQq65WfZw==", "dev": true, "license": "ISC" }, @@ -3978,6 +3991,16 @@ "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", "license": "MIT" }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, "node_modules/execa": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", @@ -4375,6 +4398,38 @@ "dev": true, "license": "MIT" }, + "node_modules/graphlib": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", + "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.15" + } + }, + "node_modules/graphology": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/graphology/-/graphology-0.25.4.tgz", + "integrity": "sha512-33g0Ol9nkWdD6ulw687viS8YJQBxqG5LWII6FI6nul0pq6iM2t5EKquOTFDbyTblRB3O9I+7KX4xI8u5ffekAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "events": "^3.3.0", + "obliterator": "^2.0.2" + }, + "peerDependencies": { + "graphology-types": ">=0.24.0" + } + }, + "node_modules/graphology-types": { + "version": "0.24.7", + "resolved": "https://registry.npmjs.org/graphology-types/-/graphology-types-0.24.7.tgz", + "integrity": "sha512-tdcqOOpwArNjEr0gNQKCXwaNCWnQJrog14nJNQPeemcLnXQUUGrsCWpWkVKt46zLjcS6/KGoayeJfHHyPDlvwA==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -5267,7 +5322,8 @@ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true }, "node_modules/node-fetch": { "version": "2.7.0", @@ -5493,6 +5549,13 @@ "node": ">= 6" } }, + "node_modules/obliterator": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", + "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==", + "dev": true, + "license": "MIT" + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -5733,13 +5796,15 @@ } }, "node_modules/phaser3-rex-plugins": { - "version": "1.80.9", - "resolved": "https://registry.npmjs.org/phaser3-rex-plugins/-/phaser3-rex-plugins-1.80.9.tgz", - "integrity": "sha512-yx+WSAf4MOF2AimVL/Dv7eN65/YuO4LVNlYihDP0tAgFfCoTBunAd0YDbv82eoSkOAd0gy6w3Qh71p3kq1eRTA==", + "version": "1.80.10", + "resolved": "https://registry.npmjs.org/phaser3-rex-plugins/-/phaser3-rex-plugins-1.80.10.tgz", + "integrity": "sha512-7qpWkpFmXobkpMSFEIRcVnotpAYZDksGzgCuZrzDAy+vtmKex5bTdSEZ8UDYYwYgkuAhVoMsveFF6oDfGOSY4Q==", "dev": true, "license": "MIT", "dependencies": { + "dagre": "^0.8.5", "eventemitter3": "^3.1.2", + "graphology": "^0.25.4", "i18next": "^22.5.1", "i18next-http-backend": "^2.5.2", "js-yaml": "^4.1.0", @@ -6380,13 +6445,12 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.80.5", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.80.5.tgz", - "integrity": "sha512-TQd2aoQl/+zsxRMEDSxVdpPIqeq9UFc6pr7PzkugiTx3VYCFPUaa3P4RrBQsqok4PO200Vkz0vXQBNlg7W907g==", + "version": "1.80.6", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.80.6.tgz", + "integrity": "sha512-ccZgdHNiBF1NHBsWvacvT5rju3y1d/Eu+8Ex6c21nHp2lZGLBEtuwc415QfiI1PJa1TpCo3iXwwSRjRpn2Ckjg==", "dev": true, "license": "MIT", "dependencies": { - "@parcel/watcher": "^2.4.1", "chokidar": "^4.0.0", "immutable": "^4.0.0", "source-map-js": ">=0.6.2 <2.0.0" @@ -6396,6 +6460,9 @@ }, "engines": { "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" } }, "node_modules/saxes": { @@ -7024,9 +7091,9 @@ "license": "Apache-2.0" }, "node_modules/tslib": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", - "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, "license": "0BSD" }, @@ -7299,15 +7366,15 @@ } }, "node_modules/vite-plugin-vue-devtools": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-7.6.1.tgz", - "integrity": "sha512-nMzlrEd60HG9KSmN4xsEponDoFFh+1LNFIuuJplo5irS8QEg4aG+vBsE3EWo5S1e5OSi1mqPX++hL/jVjncBUA==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-7.6.2.tgz", + "integrity": "sha512-YPE/8AIBsomvHadZ02Kkp8yZo2FR0SFNjbC2lcMgW+hNA1ZoXu9b5oi18gTMzJcLLFRNNSMNjShA4RLqXlIR/A==", "dev": true, "license": "MIT", "dependencies": { - "@vue/devtools-core": "^7.6.1", - "@vue/devtools-kit": "^7.6.1", - "@vue/devtools-shared": "^7.6.1", + "@vue/devtools-core": "^7.6.2", + "@vue/devtools-kit": "^7.6.2", + "@vue/devtools-shared": "^7.6.2", "execa": "^8.0.1", "sirv": "^3.0.0", "vite-plugin-inspect": "^0.8.7", diff --git a/src/components/gameMaster/zoneEditor/zonePartials/ZoneObject.vue b/src/components/gameMaster/zoneEditor/zonePartials/ZoneObject.vue index 29704af..126fcea 100644 --- a/src/components/gameMaster/zoneEditor/zonePartials/ZoneObject.vue +++ b/src/components/gameMaster/zoneEditor/zonePartials/ZoneObject.vue @@ -38,11 +38,7 @@ loadTexture(scene, { updatedAt: props.zoneObject.object.updatedAt, frameWidth: props.zoneObject.object.frameWidth, frameHeight: props.zoneObject.object.frameHeight -} as AssetDataT) - .then((loaded) => { - isTextureLoaded.value = loaded - }) - .catch((error) => { - console.error('Error loading texture:', error) - }) - \ No newline at end of file +} as AssetDataT).catch((error) => { + console.error('Error loading texture:', error) +}) + diff --git a/src/components/sprites/Character.vue b/src/components/sprites/Character.vue index 585c4a2..815e188 100644 --- a/src/components/sprites/Character.vue +++ b/src/components/sprites/Character.vue @@ -37,7 +37,6 @@ const props = defineProps<{ character: ExtendedCharacter }>() -const isTextureLoaded = ref(false) const charChatContainer = refObj() const charContainer = refObj() const charSprite = refObj() @@ -183,13 +182,14 @@ watch( watch(() => props.character.isMoving, updateSprite) watch(() => props.character.rotation, updateSprite) -loadSpriteTextures(scene, props.character.characterType?.sprite as SpriteT).then((loaded) => { - isTextureLoaded.value = loaded - charSprite.value!.setTexture(charTexture.value) - charSprite.value!.setFlipX(isFlippedX.value) -}).catch((error) => { - console.error('Error loading texture:', error) -}) +loadSpriteTextures(scene, props.character.characterType?.sprite as SpriteT) + .then(() => { + charSprite.value!.setTexture(charTexture.value) + charSprite.value!.setFlipX(isFlippedX.value) + }) + .catch((error) => { + console.error('Error loading texture:', error) + }) onMounted(() => { charChatContainer.value!.setName(`${props.character!.name}_chatContainer`) diff --git a/src/components/zone/partials/ZoneObject.vue b/src/components/zone/partials/ZoneObject.vue index 11b2eea..a3678ae 100644 --- a/src/components/zone/partials/ZoneObject.vue +++ b/src/components/zone/partials/ZoneObject.vue @@ -1,21 +1,22 @@ diff --git a/src/composables/gameComposable.ts b/src/composables/gameComposable.ts index bd22f52..fa9ddb3 100644 --- a/src/composables/gameComposable.ts +++ b/src/composables/gameComposable.ts @@ -3,42 +3,62 @@ import { useGameStore } from '@/stores/gameStore' import { AssetStorage } from '@/storage/assetStorage' import config from '@/config' +const textureLoadingPromises = new Map>() + export async function loadTexture(scene: Phaser.Scene, assetData: AssetDataT): Promise { const gameStore = useGameStore() const assetStorage = new AssetStorage() // Check if the texture is already loaded in Phaser - if (scene.textures.exists(assetData.key)) { - return true + if (gameStore.game.loadedAssets.find((asset) => asset.key === assetData.key)) { + return Promise.resolve(true) } - // Check if the asset is already cached - let asset = await assetStorage.get(assetData.key) - - // If asset is not found, download it - if (!asset) { - await assetStorage.download(assetData) - asset = await assetStorage.get(assetData.key) + // If there's already a loading promise for this texture, return it + if (textureLoadingPromises.has(assetData.key)) { + return await textureLoadingPromises.get(assetData.key)! } - // If asset is found, add it to the scene - if (asset) { - return new Promise((resolve) => { - scene.textures.addBase64(asset.key, asset.data) - scene.textures.once(`addtexture-${asset.key}`, () => { - gameStore.game.loadedAssets.push(asset) - resolve(true) + // Create new loading promise + const loadingPromise = (async () => { + // Check if the asset is already cached + let asset = await assetStorage.get(assetData.key) + + // If asset is not found, download it + if (!asset) { + await assetStorage.download(assetData) + asset = await assetStorage.get(assetData.key) + } + + // If asset is found, add it to the scene + if (asset) { + return new Promise((resolve) => { + // Remove existing texture if it exists + if (scene.textures.exists(asset.key)) { + scene.textures.remove(asset.key) + } + + scene.textures.addBase64(asset.key, asset.data) + scene.textures.once(`addtexture-${asset.key}`, () => { + gameStore.game.loadedAssets.push(assetData) + textureLoadingPromises.delete(assetData.key) // Clean up the promise + resolve(true) + }) }) - }) - } + } - return false + textureLoadingPromises.delete(assetData.key) // Clean up the promise + return Promise.resolve(false) + })() + + // Store the loading promise + textureLoadingPromises.set(assetData.key, loadingPromise) + return loadingPromise } export async function loadSpriteTextures(scene: Phaser.Scene, sprite: Sprite) { const sprite_actions = await fetch(config.server_endpoint + '/assets/list_sprite_actions/' + sprite?.id).then((response) => response.json()) for await (const sprite_action of sprite_actions) { - await loadTexture(scene, { key: sprite_action.key, data: sprite_action.data, @@ -62,5 +82,5 @@ export async function loadSpriteTextures(scene: Phaser.Scene, sprite: Sprite) { repeat: -1 }) } - return true -} \ No newline at end of file + return Promise.resolve(true) +}