1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
| const { ccclass } = cc._decorator;
interface LoadTask { url: string; type: typeof cc.Asset; onProgress?: (progress: number) => void; onComplete?: (err: Error, asset: any) => void; }
@ccclass export default class BatchResourceLoader {
private static _instance: BatchResourceLoader = null;
static getInstance(): BatchResourceLoader { if (!this._instance) { this._instance = new BatchResourceLoader(); } return this._instance; }
private _maxConcurrent: number = 3; private _queue: LoadTask[] = []; private _running: number = 0; private _cache: Map<string, any> = new Map();
load(url: string, type: typeof cc.Asset, callback?: (err: Error, asset: any) => void) { if (this._cache.has(url)) { callback?.(null, this._cache.get(url)); return; }
this._queue.push({ url, type, onComplete: callback });
this._processQueue(); }
loadBatch(tasks: { url: string; type: typeof cc.Asset }[], onProgress?: (completed: number, total: number) => void, onComplete?: (results: Map<string, any>) => void) {
const total = tasks.length; let completed = 0; const results = new Map<string, any>();
tasks.forEach(task => { this.load(task.url, task.type, (err, asset) => { completed++;
if (!err) { results.set(task.url, asset); }
onProgress?.(completed, total);
if (completed >= total) { onComplete?.(results); } }); }); }
private _processQueue() { while (this._running < this._maxConcurrent && this._queue.length > 0) { const task = this._queue.shift(); if (!task) continue;
this._running++;
cc.loader.load(task.url, (err, asset) => { this._running--;
if (!err && asset) { this._cache.set(task.url, asset); }
task.onComplete?.(err, asset); this._processQueue(); }); } }
getFromCache(url: string): any { return this._cache.get(url); }
release(url: string) { const asset = this._cache.get(url); if (asset) { cc.loader.release(url); this._cache.delete(url); } }
releaseAll() { this._cache.forEach((asset, url) => { cc.loader.release(url); }); this._cache.clear(); } }
|