/** * ResourceManager.js * Handles preloading of image resources using wx.createImage. * Provides progress callback and cached access to loaded images. */ class ResourceManager { constructor() { /** @type {Map} */ this._cache = new Map(); this._totalAssets = 0; this._loadedAssets = 0; } /** * Preload a list of image assets. * @param {Array<{key: string, src: string}>} assetList - Assets to load. * @param {Function} [onProgress] - Called with (loaded, total) on each load. * @returns {Promise} Resolves when all assets are loaded. */ loadImages(assetList, onProgress) { this._totalAssets = assetList.length; this._loadedAssets = 0; if (this._totalAssets === 0) { return Promise.resolve(); } const promises = assetList.map(({ key, src }) => { return new Promise((resolve, reject) => { // If already cached, skip if (this._cache.has(key)) { this._loadedAssets++; if (onProgress) onProgress(this._loadedAssets, this._totalAssets); resolve(); return; } const img = wx.createImage(); img.onload = () => { this._cache.set(key, img); this._loadedAssets++; if (onProgress) onProgress(this._loadedAssets, this._totalAssets); resolve(); }; img.onerror = (err) => { console.warn(`[ResourceManager] Failed to load: ${src}`, err); // Resolve anyway so other assets continue loading this._loadedAssets++; if (onProgress) onProgress(this._loadedAssets, this._totalAssets); resolve(); }; img.src = src; }); }); return Promise.all(promises).then(() => {}); } /** * Get a loaded image by key. * @param {string} key * @returns {Image|null} */ getImage(key) { return this._cache.get(key) || null; } /** * Check if an image is loaded. * @param {string} key * @returns {boolean} */ hasImage(key) { return this._cache.has(key); } /** * Clear all cached images. */ clear() { this._cache.clear(); this._totalAssets = 0; this._loadedAssets = 0; } /** Current loading progress (0 to 1). */ get progress() { if (this._totalAssets === 0) return 1; return this._loadedAssets / this._totalAssets; } } module.exports = ResourceManager;