import { _decorator, AssetManager, assetManager, instantiate, Node, NodePool, Prefab, resources } from 'cc'; const { ccclass, property } = _decorator; @ccclass('NodePoolManager') export class NodePoolManager { private static _instance: NodePoolManager = null; private _nodePoolMap: Map = null; private _prefabCache: Map = new Map(); static get instance() { if (this._instance) { return this._instance; } this._instance = new NodePoolManager(); return this._instance; } constructor() { this._nodePoolMap = new Map(); } // 内部调用,通过name获取节点池 getNodePoolByName(name: string): NodePool { if (!this._nodePoolMap.has(name)) { let nodePool = new NodePool(name); this._nodePoolMap.set(name, nodePool) } let nodePool = this._nodePoolMap.get(name); return nodePool } getNodeFromPoolStatic(name: string, prefab?: Prefab): Node | null { let nodePool = this.getNodePoolByName(name); let poolSize = nodePool.size(); if (poolSize <= 0) { let node = instantiate(prefab); nodePool.put(node); } return nodePool.get(); } async getNodeFromPoolDynamic(name: string, path: string, bundleName?: string): Promise { let nodePool = this.getNodePoolByName(name); if (nodePool.size() <= 0) { let prefab = await this.loadPrefab(path, bundleName); let node = instantiate(prefab); nodePool.put(node); } return nodePool.get(); } async loadPrefab(path: string, bundleName?: string): Promise { let key = bundleName ? `${bundleName}:${path}` : path; let cachedPrefab = this._prefabCache.get(key); if (cachedPrefab) return cachedPrefab; let loadBundle = async (): Promise => { let exist = assetManager.getBundle(bundleName); if (exist) return exist; return await new Promise((resolve, reject) => { assetManager.loadBundle(bundleName, (err, bundle) => { if (err) return reject(err); resolve(bundle); }); }); } let loadFromBundle = bundleName && bundleName.length > 0; let bundle = loadFromBundle ? await loadBundle() : resources; let prefabInCache = (bundle as any).get?.(path, Prefab); if (prefabInCache) { this._prefabCache.set(key, prefabInCache); return prefabInCache; } let prefab = await new Promise((resolve, reject) => { bundle.load(path, Prefab, (e, p) => e ? reject(e) : resolve(p)); }); this._prefabCache.set(key, prefab); return prefab; } putNodeToPool(name: string, node: Node) { let nodePool = this.getNodePoolByName(name); nodePool.put(node); } clearNodePoolByName(name: string) { let nodePool = this.getNodePoolByName(name); nodePool.clear(); if (this._nodePoolMap.has(name)) { this._nodePoolMap.delete(name); } } clearAll() { this._nodePoolMap.forEach(value => { value.clear(); }) this._nodePoolMap.clear(); } static destoryInstance() { this._instance = null; } }