import { _decorator, error, TextAsset } from 'cc' import { CsvParser } from './CsvParser' import { Constants } from '../../data/Constants' import { Logger } from '../../extend/Logger' import { Singleton } from '../manager/Singleton' import { bundleMgr } from '../manager/BundleManager' const { ccclass, property } = _decorator //wws @ccclass('CsvManager') class CsvManager extends Singleton { // 表格所在的目录 private _directory: string = 'csv' // 表格解析器单例 private _parser: CsvParser = new CsvParser() /*调用事例 加载所有CSV表 await csvMgr.loadAll( (finished, total) => { Logger.log(`加载进度: ${finished}/${total}`); }, (isAllFinished, tableName, data) => { Logger.log(`CSV加载完成`+ tableName); } ); //获取表数据(异步) let levels = csvMgr.getTable("levels") Logger.log("物品表数据:", JSON.stringify(levels)); //获取表数据 (异步) csvMgr.getTable("item").then(table => { Logger.log("物品表数据:", table); });*/ /** * 加载所有CSV配置表 * @param onProgress @param onProgress 进度回调 (isAllFinished: 是否全部完成, tableName: 表名, data: 表数据) * @returns 当所有表加载完成或出错时resolve/reject */ public async loadAll( onProgress?: ( isAllFinished: boolean, finishCount: number, total: number, tableName?: string, data?: any[] ) => void ): Promise { try { const bundle = await bundleMgr.getBundle(Constants.bundleName.data) //1. 获取目录下所有CSV文件列表(不实际加载资源) const fileList: Array = bundle.getDirWithPath(this._directory) if (fileList.length === 0) { Logger.warn(`目录 ${this._directory} 下未找到CSV文件`) return } const total = fileList.length let loadedCount = 0 //2. 逐个加载文件 for (const file of fileList) { const asset = await this._loadSingleTable(file.path) //解析数据并缓存 const data = this._parser.addTable(asset.name, asset.text) //更新进度和回调 loadedCount++ const tableName = file.path.split('/').pop() onProgress?.(loadedCount == total, loadedCount, total, tableName, data) } } catch (err) { error('加载CSV表过程中发生错误:', err) throw err // 重新抛出错误,让调用方可以捕获 } } /** * 加载单个CSV表 * @param path 表路径 * @returns Promise 加载成功的TextAsset * @private */ private async _loadSingleTable(path: string): Promise { const bundle = await bundleMgr.getBundle(Constants.bundleName.data) return new Promise((resolve, reject) => { bundle.load(path, TextAsset, (err, asset) => { if (err || !asset) { reject(err || new Error(`加载资源 ${path} 失败`)) } else { resolve(asset) } }) }) } /** * 调用事例 csvMgr.getTableArr('weapon'); * 异步获取表数据(如果表未加载会自动加载) * @param tableName 表名 * @returns Promise 表数据数组 */ public getTableArr(tableName: string): any { return this._parser.getTableArr(tableName) } /**调用事例 csvMgr.findOne('weapon', w => w.quality === 'epic') * 查询单条记录 * @param tableName 表名 * @param predicate 查询条件函数 * @returns 匹配的第一条记录或undefined */ public findOne(tableName: string, predicate: (item: T) => boolean): T | undefined { return this.getTableArr(tableName).find(predicate) } /** * 查询多条记录 * @param tableName 表名 * @param predicate 查询条件函数 * @returns 匹配的所有记录数组 */ public findMany(tableName: string, predicate: (item: T) => boolean): T[] { return this.getTableArr(tableName).filter(predicate) } } //全局单例 export const csvMgr = CsvManager.ins()