CsvManager.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import { _decorator, error, TextAsset } from 'cc'
  2. import { CsvParser } from './CsvParser'
  3. import { Constants } from '../../data/Constants'
  4. import { Logger } from '../../extend/Logger'
  5. import { Singleton } from '../manager/Singleton'
  6. import { bundleMgr } from '../manager/BundleManager'
  7. const { ccclass, property } = _decorator
  8. //wws
  9. @ccclass('CsvManager')
  10. class CsvManager extends Singleton {
  11. // 表格所在的目录
  12. private _directory: string = 'csv'
  13. // 表格解析器单例
  14. private _parser: CsvParser = new CsvParser()
  15. /*调用事例 加载所有CSV表
  16. await csvMgr.loadAll(
  17. (finished, total) => {
  18. Logger.log(`加载进度: ${finished}/${total}`);
  19. },
  20. (isAllFinished, tableName, data) => {
  21. Logger.log(`CSV加载完成`+ tableName);
  22. }
  23. );
  24. //获取表数据(异步)
  25. let levels = csvMgr.getTable("levels")
  26. Logger.log("物品表数据:", JSON.stringify(levels));
  27. //获取表数据 (异步)
  28. csvMgr.getTable("item").then(table => {
  29. Logger.log("物品表数据:", table);
  30. });*/
  31. /**
  32. * 加载所有CSV配置表
  33. * @param onProgress @param onProgress 进度回调 (isAllFinished: 是否全部完成, tableName: 表名, data: 表数据)
  34. * @returns 当所有表加载完成或出错时resolve/reject
  35. */
  36. public async loadAll(
  37. onProgress?: (
  38. isAllFinished: boolean,
  39. finishCount: number,
  40. total: number,
  41. tableName?: string,
  42. data?: any[]
  43. ) => void
  44. ): Promise<void> {
  45. try {
  46. const bundle = await bundleMgr.getBundle(Constants.bundleName.data)
  47. //1. 获取目录下所有CSV文件列表(不实际加载资源)
  48. const fileList: Array<any> = bundle.getDirWithPath(this._directory)
  49. if (fileList.length === 0) {
  50. Logger.warn(`目录 ${this._directory} 下未找到CSV文件`)
  51. return
  52. }
  53. const total = fileList.length
  54. let loadedCount = 0
  55. //2. 逐个加载文件
  56. for (const file of fileList) {
  57. const asset = await this._loadSingleTable(file.path)
  58. //解析数据并缓存
  59. const data = this._parser.addTable(asset.name, asset.text)
  60. //更新进度和回调
  61. loadedCount++
  62. const tableName = file.path.split('/').pop()
  63. onProgress?.(loadedCount == total, loadedCount, total, tableName, data)
  64. }
  65. } catch (err) {
  66. error('加载CSV表过程中发生错误:', err)
  67. throw err // 重新抛出错误,让调用方可以捕获
  68. }
  69. }
  70. /**
  71. * 加载单个CSV表
  72. * @param path 表路径
  73. * @returns Promise<TextAsset> 加载成功的TextAsset
  74. * @private
  75. */
  76. private async _loadSingleTable(path: string): Promise<TextAsset> {
  77. const bundle = await bundleMgr.getBundle(Constants.bundleName.data)
  78. return new Promise<TextAsset>((resolve, reject) => {
  79. bundle.load(path, TextAsset, (err, asset) => {
  80. if (err || !asset) {
  81. reject(err || new Error(`加载资源 ${path} 失败`))
  82. } else {
  83. resolve(asset)
  84. }
  85. })
  86. })
  87. }
  88. /**
  89. * 调用事例 csvMgr.getTableArr('weapon');
  90. * 异步获取表数据(如果表未加载会自动加载)
  91. * @param tableName 表名
  92. * @returns Promise<T[]> 表数据数组
  93. */
  94. public getTableArr(tableName: string): any {
  95. return this._parser.getTableArr(tableName)
  96. }
  97. /**调用事例 csvMgr.findOne('weapon', w => w.quality === 'epic')
  98. * 查询单条记录
  99. * @param tableName 表名
  100. * @param predicate 查询条件函数
  101. * @returns 匹配的第一条记录或undefined
  102. */
  103. public findOne<T = any>(tableName: string, predicate: (item: T) => boolean): T | undefined {
  104. return this.getTableArr(tableName).find(predicate)
  105. }
  106. /**
  107. * 查询多条记录
  108. * @param tableName 表名
  109. * @param predicate 查询条件函数
  110. * @returns 匹配的所有记录数组
  111. */
  112. public findMany<T = any>(tableName: string, predicate: (item: T) => boolean): T[] {
  113. return this.getTableArr(tableName).filter(predicate)
  114. }
  115. }
  116. //全局单例
  117. export const csvMgr = CsvManager.ins()