untitled-game-engine/src/core/assets.js
2025-03-28 18:06:18 -05:00

112 lines
2.3 KiB
JavaScript

import { NotImplementedError } from '../utils/error.js'
export const AssetType = Object.freeze({
Text: url => fetch(url).then(res => res.text()),
ArrayBuffer: url => fetch(url).then(res => res.arrayBuffer()),
Image: url => new Promise((resolve, reject) => {
const image = new Image()
image.onload = () => resolve(image)
image.onerror = err => reject(err)
image.src = url
})
})
class StorageLayer {
has(_key) {
throw new NotImplementedError()
}
get(_key) {
throw new NotImplementedError()
}
set(_key, _value) {
throw new NotImplementedError()
}
}
class MemoryStorage extends StorageLayer {
#memory = new Map()
has(key) {
return this.#memory.has(key)
}
get(key) {
return this.#memory.get(key)
}
set(key, value) {
this.#memory.set(key, value)
}
}
class LocalStorage extends StorageLayer {
#cache = new MemoryStorage()
has(key) {
if (this.#cache.has(key)) {
return true
} else {
const item = localStorage.getItem(key)
if (item != null) {
this.#cache.set(key, item)
return true
}
return false
}
}
get(key) {
if (this.#cache.has(key)) {
return this.#cache.get(key)
} else {
const item = localStorage.getItem(key)
if (item != null) {
this.#cache.set(key, item)
return item
}
return null
}
}
set(key, value) {
this.#cache.set(key, value)
localStorage.setItem(key, value)
}
}
export class Assets {
#storage = new LocalStorage()
/**
*
* @param {UrlLike} url
* @param {(url: UrlLike) => Promise<any>} handler
*/
async load(url, handler = AssetType.ArrayBuffer) {
if (this.#storage.has(url)) {
return this.#storage.get(url)
}
try {
const data = await handler(url)
this.#storage.set(url, data)
return data
} catch (err) {
console.error(err)
}
}
/**
* @param {UrlLike} url
*/
get(url) {
return this.#storage.get(url)
}
}