Worked on dynamic texture loading
This commit is contained in:
@ -15,7 +15,7 @@ import GmPanel from '@/components/gameMaster/GmPanel.vue'
|
||||
import Login from '@/screens/Login.vue'
|
||||
import Characters from '@/screens/Characters.vue'
|
||||
import Game from '@/screens/Game.vue'
|
||||
import Loading from '@/screens/Loading.vue'
|
||||
// import Loading from '@/screens/Loading.vue'
|
||||
import ZoneEditor from '@/screens/ZoneEditor.vue'
|
||||
import { computed } from 'vue'
|
||||
|
||||
@ -23,7 +23,7 @@ const gameStore = useGameStore()
|
||||
const zoneEditorStore = useZoneEditorStore()
|
||||
|
||||
const currentScreen = computed(() => {
|
||||
if (!gameStore.isAssetsLoaded) return Loading
|
||||
// if (!gameStore.isAssetsLoaded) return Loading
|
||||
if (!gameStore.connection) return Login
|
||||
if (!gameStore.token) return Login
|
||||
if (!gameStore.character) return Characters
|
||||
|
@ -8,7 +8,7 @@ import { useScene } from 'phavuer'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useZoneEditorStore } from '@/stores/zoneEditorStore'
|
||||
import { onBeforeMount, onBeforeUnmount } from 'vue'
|
||||
import { createTileArray, getTile, placeTile, setAllTiles } from '@/composables/zoneComposable'
|
||||
import { createTileArray, getTile, placeTile, setLayerTiles } from '@/composables/zoneComposable'
|
||||
import Controls from '@/components/utilities/Controls.vue'
|
||||
|
||||
const emit = defineEmits(['tilemap:create'])
|
||||
@ -117,7 +117,7 @@ function paint(pointer: Phaser.Input.Pointer) {
|
||||
if (!pointer.isDown) return
|
||||
|
||||
// Set new tileArray with selected tile
|
||||
setAllTiles(zoneTilemap, tiles, createTileArray(zoneTilemap.width, zoneTilemap.height, zoneEditorStore.selectedTile.id))
|
||||
setLayerTiles(zoneTilemap, tiles, createTileArray(zoneTilemap.width, zoneTilemap.height, zoneEditorStore.selectedTile.id))
|
||||
|
||||
// Adjust zoneEditorStore.zone.tiles
|
||||
zoneEditorStore.zone.tiles = createTileArray(zoneTilemap.width, zoneTilemap.height, zoneEditorStore.selectedTile.id)
|
||||
@ -127,7 +127,7 @@ onBeforeMount(() => {
|
||||
if (!zoneEditorStore.zone?.tiles) {
|
||||
return
|
||||
}
|
||||
setAllTiles(zoneTilemap, tiles, zoneEditorStore.zone.tiles)
|
||||
setLayerTiles(zoneTilemap, tiles, zoneEditorStore.zone.tiles)
|
||||
|
||||
scene.input.on(Phaser.Input.Events.POINTER_MOVE, pencil)
|
||||
scene.input.on(Phaser.Input.Events.POINTER_MOVE, eraser)
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Modal v-for="notification in gameStore.getNotifications" :key="notification.id" :isModalOpen="true" @modal:close="closeNotification(notification.id)">
|
||||
<Modal v-for="notification in gameStore.notifications" :key="notification.id" :isModalOpen="true" @modal:close="closeNotification(notification.id)">
|
||||
<template #modalHeader v-if="notification.title">
|
||||
<h3 class="m-0 font-medium shrink-0 text-white">{{ notification.title }}</h3>
|
||||
</template>
|
||||
|
@ -1,28 +0,0 @@
|
||||
<template>
|
||||
<Image v-for="object in zoneStore.zone?.zoneObjects" v-bind="getImageProps(object)" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { calculateIsometricDepth, tileToWorldX, tileToWorldY } from '@/composables/zoneComposable'
|
||||
import { Image, Text } from 'phavuer'
|
||||
import { useZoneStore } from '@/stores/zoneStore'
|
||||
import type { ZoneObject } from '@/types'
|
||||
|
||||
const zoneStore = useZoneStore()
|
||||
|
||||
const props = defineProps<{
|
||||
tilemap: Phaser.Tilemaps.Tilemap
|
||||
}>()
|
||||
|
||||
const getImageProps = (object: ZoneObject) => {
|
||||
return {
|
||||
depth: calculateIsometricDepth(object.positionX, object.positionY, object.object.frameWidth, object.object.frameHeight),
|
||||
x: tileToWorldX(props.tilemap as any, object.positionX, object.positionY),
|
||||
y: tileToWorldY(props.tilemap as any, object.positionX, object.positionY),
|
||||
flipX: object.isRotated,
|
||||
texture: object.object.id,
|
||||
originY: Number(object.object.originX),
|
||||
originX: Number(object.object.originY)
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1,16 +1,16 @@
|
||||
<template>
|
||||
<Tiles :key="zoneStore.zone?.id ?? 0" @tilemap:create="tileMap = $event" />
|
||||
<Objects v-if="tileMap" :tilemap="tileMap as Phaser.Tilemaps.Tilemap" />
|
||||
<ZoneTiles :key="zoneStore.zone?.id ?? 0" @tilemap:create="tileMap = $event" />
|
||||
<ZoneObjects v-if="tileMap" :tilemap="tileMap as Phaser.Tilemaps.Tilemap" />
|
||||
<Characters v-if="tileMap" :tilemap="tileMap as Phaser.Tilemaps.Tilemap" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useZoneStore } from '@/stores/zoneStore'
|
||||
import { onBeforeUnmount, ref } from 'vue'
|
||||
import { onBeforeUnmount, ref, onBeforeMount } from 'vue'
|
||||
import type { Character as CharacterT, Zone as ZoneT, ExtendedCharacter as ExtendedCharacterT } from '@/types'
|
||||
import Tiles from '@/components/zone/Tiles.vue'
|
||||
import Objects from '@/components/zone/Objects.vue'
|
||||
import ZoneTiles from '@/components/zone/ZoneTiles.vue'
|
||||
import ZoneObjects from '@/components/zone/ZoneObjects.vue'
|
||||
import Characters from '@/components/zone/Characters.vue'
|
||||
|
||||
const gameStore = useGameStore()
|
||||
@ -51,9 +51,12 @@ gameStore.connection!.on('character:move', (data: ExtendedCharacterT) => {
|
||||
zoneStore.updateCharacter(data)
|
||||
})
|
||||
|
||||
gameStore.connection!.emit('zone:character:join', async (response: zoneLoadData) => {
|
||||
zoneStore.setZone(response.zone)
|
||||
zoneStore.setCharacters(response.characters)
|
||||
onBeforeMount(async () => {
|
||||
gameStore!.connection!.emit('zone:character:join', async (response: zoneLoadData) => {
|
||||
// Set zone and characters
|
||||
zoneStore.setZone(response.zone)
|
||||
zoneStore.setCharacters(response.characters)
|
||||
})
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
|
14
src/components/zone/ZoneObjects.vue
Normal file
14
src/components/zone/ZoneObjects.vue
Normal file
@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<ZoneObject v-for="zoneObject in zoneStore.zone?.zoneObjects" :tilemap="tilemap" :zoneObject />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useZoneStore } from '@/stores/zoneStore'
|
||||
import ZoneObject from '@/components/zone/partials/ZoneObject.vue'
|
||||
|
||||
const zoneStore = useZoneStore()
|
||||
|
||||
defineProps<{
|
||||
tilemap: Phaser.Tilemaps.Tilemap
|
||||
}>()
|
||||
</script>
|
@ -7,14 +7,13 @@ import config from '@/config'
|
||||
import { useScene } from 'phavuer'
|
||||
import { useZoneStore } from '@/stores/zoneStore'
|
||||
import { onBeforeMount, onBeforeUnmount } from 'vue'
|
||||
import { placeTile, setAllTiles } from '@/composables/zoneComposable'
|
||||
import { setLayerTiles } from '@/composables/zoneComposable'
|
||||
import Controls from '@/components/utilities/Controls.vue'
|
||||
|
||||
const emit = defineEmits(['tilemap:create'])
|
||||
|
||||
const zoneStore = useZoneStore()
|
||||
const scene = useScene()
|
||||
|
||||
const zoneTilemap = createTilemap()
|
||||
const tiles = createTileLayer()
|
||||
|
||||
@ -54,7 +53,7 @@ onBeforeMount(() => {
|
||||
if (!zoneStore.zone?.tiles) {
|
||||
return
|
||||
}
|
||||
setAllTiles(zoneTilemap, tiles, zoneStore.zone.tiles)
|
||||
setLayerTiles(zoneTilemap, tiles, zoneStore.zone.tiles)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
63
src/components/zone/partials/ZoneObject.vue
Normal file
63
src/components/zone/partials/ZoneObject.vue
Normal file
@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<Image v-if="isTextureLoaded" v-bind="imageProps" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, computed } from 'vue'
|
||||
import { Image, useScene } from 'phavuer'
|
||||
import { calculateIsometricDepth, tileToWorldX, tileToWorldY } from '@/composables/zoneComposable'
|
||||
import { useAssetManager } from '@/utilities/assetManager'
|
||||
import type { ZoneObject } from '@/types'
|
||||
|
||||
const props = defineProps<{
|
||||
tilemap: Phaser.Tilemaps.Tilemap
|
||||
zoneObject: ZoneObject
|
||||
}>()
|
||||
|
||||
const scene = useScene()
|
||||
const assetManager = useAssetManager
|
||||
const isTextureLoaded = ref(false)
|
||||
|
||||
const imageProps = computed(() => ({
|
||||
depth: calculateIsometricDepth(props.zoneObject.positionX, props.zoneObject.positionY, props.zoneObject.object.frameWidth, props.zoneObject.object.frameHeight),
|
||||
x: tileToWorldX(props.tilemap, props.zoneObject.positionX, props.zoneObject.positionY),
|
||||
y: tileToWorldY(props.tilemap, props.zoneObject.positionX, props.zoneObject.positionY),
|
||||
flipX: props.zoneObject.isRotated,
|
||||
texture: props.zoneObject.object.id,
|
||||
originY: Number(props.zoneObject.object.originX),
|
||||
originX: Number(props.zoneObject.object.originY)
|
||||
}))
|
||||
|
||||
const loadTexture = async () => {
|
||||
const textureId = props.zoneObject.object.id
|
||||
|
||||
// Check if the texture is already loaded in Phaser
|
||||
if (scene.textures.exists(textureId)) {
|
||||
isTextureLoaded.value = true
|
||||
return
|
||||
}
|
||||
|
||||
let assetData = await assetManager.getAsset(textureId)
|
||||
|
||||
if (!assetData) {
|
||||
await assetManager.downloadAsset(textureId, `/assets/objects/${textureId}.png`, 'objects', props.zoneObject.object.updatedAt)
|
||||
assetData = await assetManager.getAsset(textureId)
|
||||
}
|
||||
|
||||
if (assetData) {
|
||||
return new Promise<void>((resolve) => {
|
||||
scene.textures.addBase64(textureId, assetData.data)
|
||||
scene.textures.once(`addtexture-${textureId}`, () => {
|
||||
isTextureLoaded.value = true
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadTexture().catch((error) => {
|
||||
console.error('Error loading texture:', error)
|
||||
})
|
||||
})
|
||||
</script>
|
0
src/composables/gameComposable.ts
Normal file
0
src/composables/gameComposable.ts
Normal file
@ -3,8 +3,6 @@ import Tilemap = Phaser.Tilemaps.Tilemap
|
||||
import TilemapLayer = Phaser.Tilemaps.TilemapLayer
|
||||
import Tileset = Phaser.Tilemaps.Tileset
|
||||
import Tile = Phaser.Tilemaps.Tile
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useAssetManager } from '@/utilities/assets'
|
||||
|
||||
export function getTile(layer: TilemapLayer | Tilemap, x: number, y: number): Tile | undefined {
|
||||
const tile = layer.getTileAtWorldXY(x, y)
|
||||
@ -52,11 +50,7 @@ export function placeTile(zone: Tilemap, layer: TilemapLayer, x: number, y: numb
|
||||
layer.putTileAt(tileImg.firstgid, x, y)
|
||||
}
|
||||
|
||||
export function deleteTile(layer: TilemapLayer, x: number, y: number) {
|
||||
layer.removeTileAt(x, y)
|
||||
}
|
||||
|
||||
export function setAllTiles(zone: Tilemap, layer: TilemapLayer, tiles: string[][]) {
|
||||
export function setLayerTiles(zone: Tilemap, layer: TilemapLayer, tiles: string[][]) {
|
||||
tiles.forEach((row: string[], y: number) => {
|
||||
row.forEach((tile: string, x: number) => {
|
||||
placeTile(zone, layer, x, y, tile)
|
||||
@ -73,17 +67,5 @@ export const calculateIsometricDepth = (x: number, y: number, width: number = 0,
|
||||
if (isCharacter) {
|
||||
return baseDepth // @TODO: Fix collision, this is a hack
|
||||
}
|
||||
|
||||
// For objects, use their back bottom corner
|
||||
return baseDepth + (width + height) / (2 * config.tile_size.x)
|
||||
}
|
||||
|
||||
export const sortByIsometricDepth = <T extends { positionX: number; positionY: number }>(items: T[]) => {
|
||||
return [...items].sort((a, b) => {
|
||||
return calculateIsometricDepth(a.positionX, a.positionY, 0, 0) - calculateIsometricDepth(b.positionX, b.positionY, 0, 0)
|
||||
})
|
||||
}
|
||||
|
||||
export const clearAssets = (scene: Phaser.Scene) => {
|
||||
scene.load.destroy()
|
||||
}
|
||||
|
@ -2,18 +2,16 @@
|
||||
<div class="flex justify-center items-center h-dvh relative">
|
||||
<Game :config="gameConfig" @create="createGame">
|
||||
<Scene name="main" @preload="preloadScene" @create="createScene">
|
||||
<div v-if="isLoaded">
|
||||
<Menu />
|
||||
<Hud />
|
||||
<Hotkeys />
|
||||
<Minimap />
|
||||
<Zone />
|
||||
<Chat />
|
||||
<ExpBar />
|
||||
<Menu />
|
||||
<Hud />
|
||||
<Hotkeys />
|
||||
<Minimap />
|
||||
<Zone />
|
||||
<Chat />
|
||||
<ExpBar />
|
||||
|
||||
<Inventory />
|
||||
<Effects />
|
||||
</div>
|
||||
<Inventory />
|
||||
<Effects />
|
||||
</Scene>
|
||||
</Game>
|
||||
</div>
|
||||
@ -22,9 +20,8 @@
|
||||
<script setup lang="ts">
|
||||
import config from '@/config'
|
||||
import 'phaser'
|
||||
import { ref, onBeforeUnmount } from 'vue'
|
||||
import { onBeforeUnmount } from 'vue'
|
||||
import { Game, Scene } from 'phavuer'
|
||||
import { useAssetManager } from '@/utilities/assets'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import Menu from '@/components/gui/Menu.vue'
|
||||
import ExpBar from '@/components/gui/ExpBar.vue'
|
||||
@ -36,10 +33,10 @@ import Inventory from '@/components/gui/UserPanel.vue'
|
||||
import Effects from '@/components/Effects.vue'
|
||||
import Minimap from '@/components/gui/Minimap.vue'
|
||||
import AwaitLoaderPlugin from 'phaser3-rex-plugins/plugins/awaitloader-plugin'
|
||||
import { useAssetManager } from '@/utilities/assetManager'
|
||||
|
||||
const assetManager = useAssetManager
|
||||
const gameStore = useGameStore()
|
||||
const isLoaded = ref(false)
|
||||
const assetManager = useAssetManager
|
||||
|
||||
const gameConfig = {
|
||||
name: config.name,
|
||||
@ -77,61 +74,24 @@ const createGame = (game: Phaser.Game) => {
|
||||
}
|
||||
|
||||
function preloadScene(scene: Phaser.Scene) {
|
||||
isLoaded.value = false
|
||||
|
||||
/**
|
||||
* Create loading bar
|
||||
*/
|
||||
const width = scene.cameras.main.width
|
||||
const height = scene.cameras.main.height
|
||||
|
||||
const progressBox = scene.add.graphics()
|
||||
const progressBar = scene.add.graphics()
|
||||
progressBox.fillStyle(0x222222, 0.8)
|
||||
progressBox.fillRect(width / 2 - 180, height / 2, 320, 50)
|
||||
|
||||
const loadingText = scene.make.text({
|
||||
x: width / 2,
|
||||
y: height / 2 - 50,
|
||||
text: 'Loading...',
|
||||
style: {
|
||||
font: '20px monospace',
|
||||
fill: '#ffffff'
|
||||
}
|
||||
})
|
||||
loadingText.setOrigin(0.5, 0.5)
|
||||
|
||||
scene.load.on(Phaser.Loader.Events.PROGRESS, function (value: any) {
|
||||
progressBar.clear()
|
||||
progressBar.fillStyle(0x368f8b, 1)
|
||||
progressBar.fillRect(width / 2 - 180 + 10, height / 2 + 10, 300 * value, 30)
|
||||
})
|
||||
|
||||
scene.load.on(Phaser.Loader.Events.COMPLETE, function () {
|
||||
progressBar.destroy()
|
||||
progressBox.destroy()
|
||||
loadingText.destroy()
|
||||
isLoaded.value = true
|
||||
})
|
||||
|
||||
/**
|
||||
* Load the base assets into the Phaser scene
|
||||
*/
|
||||
scene.load.image('blank_tile', '/assets/zone/blank_tile.png')
|
||||
scene.load.image('waypoint', '/assets/waypoint.png')
|
||||
|
||||
scene.load.rexAwait(async (successCallback: any, failureCallback: any) => {
|
||||
/**
|
||||
* Load the assets into the Phaser scene
|
||||
*/
|
||||
scene.load.rexAwait(async function (successCallback) {
|
||||
await assetManager.getAssetsByGroup('tiles').then((assets) => {
|
||||
assets.forEach((asset) => {
|
||||
if (scene.load.textureManager.exists(asset.key)) return
|
||||
scene.textures.addBase64(asset.key, asset.data)
|
||||
})
|
||||
})
|
||||
|
||||
// Load objects
|
||||
await assetManager.getAssetsByGroup('objects').then((assets) => {
|
||||
assets.forEach((asset) => {
|
||||
if (scene.load.textureManager.exists(asset.key)) return
|
||||
scene.textures.addBase64(asset.key, asset.data)
|
||||
})
|
||||
})
|
||||
@ -140,24 +100,22 @@ function preloadScene(scene: Phaser.Scene) {
|
||||
})
|
||||
}
|
||||
|
||||
const createScene = (scene: Phaser.Scene) => {
|
||||
function createScene(scene: Phaser.Scene) {
|
||||
/**
|
||||
* Create sprite animations
|
||||
* This is done here because phaser forces us to
|
||||
*/
|
||||
// assetManager.getAssetsByGroup('sprite_animations').then((assets) => {
|
||||
// assets.forEach((asset) => {
|
||||
// scene.anims.create({
|
||||
// key: asset.key,
|
||||
// frameRate: 7,
|
||||
// frames: scene.anims.generateFrameNumbers(asset.key, { start: 0, end: asset.frameCount! - 1 }),
|
||||
// repeat: -1
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
assetManager.getAssetsByGroup('sprite_animations').then((assets) => {
|
||||
assets.forEach((asset) => {
|
||||
scene.anims.create({
|
||||
key: asset.key,
|
||||
frameRate: 7,
|
||||
frames: scene.anims.generateFrameNumbers(asset.key, { start: 0, end: asset.frameCount! - 1 }),
|
||||
repeat: -1
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
isLoaded.value = false
|
||||
})
|
||||
onBeforeUnmount(() => {})
|
||||
</script>
|
||||
|
@ -17,9 +17,14 @@
|
||||
import { onMounted, ref } from 'vue'
|
||||
import config from '@/config'
|
||||
import type { AssetT as ServerAsset } from '@/types'
|
||||
import { useAssetManager } from '@/utilities/assets'
|
||||
import { useAssetManager } from '@/utilities/assetManager'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
|
||||
/**
|
||||
* This component downloads all assets from the server and
|
||||
* stores them in the asset manager.
|
||||
*/
|
||||
|
||||
const gameStore = useGameStore()
|
||||
const assetManager = useAssetManager
|
||||
const isLoaded = ref(false)
|
||||
@ -50,7 +55,7 @@ async function loadAssetsIntoAssetManager(assets: ServerAsset[]): Promise<void>
|
||||
}
|
||||
|
||||
// Add the asset to the asset manager
|
||||
await assetManager.addAsset(asset.key, asset.url, asset.group, asset.updatedAt, asset.frameCount, asset.frameWidth, asset.frameHeight)
|
||||
await assetManager.downloadAsset(asset.key, asset.url, asset.group, asset.updatedAt, asset.frameCount, asset.frameWidth, asset.frameHeight)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ export async function login(username: string, password: string) {
|
||||
useCookies().set('token', response.data.token as string, {
|
||||
// for whole domain
|
||||
// @TODO : #190
|
||||
domain: window.location.hostname.split('.').slice(-2).join('.')
|
||||
// domain: window.location.hostname.split('.').slice(-2).join('.')
|
||||
})
|
||||
return { success: true, token: response.data.token }
|
||||
} catch (error: any) {
|
||||
|
@ -9,6 +9,7 @@ export const useGameStore = defineStore('game', {
|
||||
return {
|
||||
notifications: [] as Notification[],
|
||||
isAssetsLoaded: false,
|
||||
loadedAssets: [] as string[],
|
||||
token: '' as string | null,
|
||||
connection: null as Socket | null,
|
||||
user: null as User | null,
|
||||
@ -30,12 +31,6 @@ export const useGameStore = defineStore('game', {
|
||||
}
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
getNotifications: (state: any) => state.notifications,
|
||||
getAssetByKey: (state) => {
|
||||
return (key: string) => state.assets.find((asset) => asset.key === key)
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
addNotification(notification: Notification) {
|
||||
if (!notification.id) {
|
||||
@ -108,10 +103,10 @@ export const useGameStore = defineStore('game', {
|
||||
useCookies().remove('token', {
|
||||
// for whole domain
|
||||
// @TODO : #190
|
||||
domain: window.location.hostname.split('.').slice(-2).join('.')
|
||||
// domain: window.location.hostname.split('.').slice(-2).join('.')
|
||||
})
|
||||
|
||||
// this.isAssetsLoaded = false
|
||||
this.isAssetsLoaded = false
|
||||
this.connection = null
|
||||
this.token = null
|
||||
this.user = null
|
||||
|
@ -1,41 +1,28 @@
|
||||
import config from '@/config'
|
||||
import Dexie from 'dexie'
|
||||
|
||||
interface Asset {
|
||||
key: string
|
||||
data: Blob
|
||||
group: string
|
||||
updatedAt: Date
|
||||
frameCount?: number
|
||||
frameWidth?: number
|
||||
frameHeight?: number
|
||||
}
|
||||
|
||||
interface AssetWithUrl extends Omit<Asset, 'data'> {
|
||||
data: string
|
||||
}
|
||||
|
||||
class AssetManager extends Dexie {
|
||||
assets!: Dexie.Table<Asset, string>
|
||||
assets!: Dexie.Table<
|
||||
{
|
||||
key: string
|
||||
data: Blob
|
||||
group: string
|
||||
updatedAt: Date
|
||||
frameCount?: number
|
||||
frameWidth?: number
|
||||
frameHeight?: number
|
||||
},
|
||||
string
|
||||
>
|
||||
|
||||
constructor() {
|
||||
super('AssetManager')
|
||||
super('Assets')
|
||||
this.version(1).stores({
|
||||
assets: 'key, group'
|
||||
})
|
||||
}
|
||||
|
||||
async getAssetCount(): Promise<number> {
|
||||
try {
|
||||
const count = await this.assets.count()
|
||||
return count
|
||||
} catch (error) {
|
||||
console.error('Failed to get asset count:', error)
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
async addAsset(key: string, url: string, group: string, updatedAt: Date, frameCount?: number, frameWidth?: number, frameHeight?: number): Promise<void> {
|
||||
async downloadAsset(key: string, url: string, group: string, updatedAt: Date, frameCount?: number, frameWidth?: number, frameHeight?: number) {
|
||||
try {
|
||||
const response = await fetch(config.server_endpoint + url)
|
||||
const blob = await response.blob()
|
||||
@ -45,7 +32,7 @@ class AssetManager extends Dexie {
|
||||
}
|
||||
}
|
||||
|
||||
async getAsset(key: string): Promise<AssetWithUrl | null> {
|
||||
async getAsset(key: string) {
|
||||
try {
|
||||
const asset = await this.assets.get(key)
|
||||
if (asset) {
|
||||
@ -60,7 +47,7 @@ class AssetManager extends Dexie {
|
||||
return null
|
||||
}
|
||||
|
||||
async getAssetsByGroup(group: string): Promise<AssetWithUrl[]> {
|
||||
async getAssetsByGroup(group: string) {
|
||||
try {
|
||||
const assets = await this.assets.where('group').equals(group).toArray()
|
||||
return assets.map((asset) => ({
|
||||
@ -73,15 +60,7 @@ class AssetManager extends Dexie {
|
||||
}
|
||||
}
|
||||
|
||||
async clearAssets(): Promise<void> {
|
||||
try {
|
||||
await this.assets.clear()
|
||||
} catch (error) {
|
||||
console.error('Failed to clear assets:', error)
|
||||
}
|
||||
}
|
||||
|
||||
async deleteAsset(key: string): Promise<void> {
|
||||
async deleteAsset(key: string) {
|
||||
try {
|
||||
await this.assets.delete(key)
|
||||
} catch (error) {
|
Reference in New Issue
Block a user