ResKeeper.ts 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import { Asset, assetManager, ImageAsset, SpriteFrame, Texture2D, _decorator } from 'cc';
  2. import { DEV } from 'cc/env';
  3. import { AutoBind } from '../common/AutoBind';
  4. import { StringUtil } from '../util/StringUtil';
  5. import { LoadQueue } from './LoadQueue';
  6. import { resLoader } from './ResLoader';
  7. const { ccclass, menu, property } = _decorator;
  8. @ccclass('ResKeeper')
  9. @menu('私有组件/ResKeeper')
  10. export class ResKeeper extends AutoBind {
  11. @property({ displayName: "启用分帧加载", tooltip: DEV && "该组件加载资源是否使用分帧加载" })
  12. private frame_load = false;
  13. @property({ displayName: "加载优先级", slide: true, max: 10, min: 0, step: 1, visible() { return this.frame_load == true; }, tooltip: DEV && "分帧加载优先级,优先级越大越先加载" })
  14. private load_priority = 0;
  15. // private _net_cache = new Map<string, SpriteFrame>();
  16. private _res_cache = new Map<string, Asset>();
  17. private _uuid_sign = StringUtil.getUUID(12);
  18. private _uuid_idx = 0;
  19. protected onDestroy() {
  20. this.release();
  21. }
  22. /**
  23. * 在当前资源缓存中清理一个缓存(主要用于一个组件加载多个资源但只使用其中一个,这个时候就可以调用释放前面的特定资源)
  24. * @param uuid 缓存ID
  25. */
  26. // protected releaseCache(uuid: string) {
  27. // if (uuid && uuid != "" && this._res_cache.has(uuid)) {
  28. // let res = this._res_cache.get(uuid);
  29. // res?.decRef();
  30. // res = null;
  31. // this._res_cache.delete(uuid);
  32. // uuid = "";
  33. // }
  34. // }
  35. /**
  36. * 在该节点上添加一个资源,该资源将随父节点销毁自动销毁,如果父节点被销毁,则销毁资源
  37. * @param bundle 包名
  38. * @param url 路径
  39. * @param type 类型
  40. * @param completed 加载成功后回调
  41. */
  42. protected load(bundle: string, url: string, type: typeof Asset, completed: (res: Asset, uuid?: string) => void) {
  43. let callback = (error: Error, res: Asset) => {
  44. if (error) {
  45. console.error(error);
  46. } else {
  47. if (this.isValid) {
  48. let uuid = this._addResCache(res);
  49. completed && completed(res, uuid);
  50. } else {
  51. // resLoader.release(url, bundle);
  52. }
  53. }
  54. };
  55. if (this.frame_load) {
  56. LoadQueue.pushLoad(this.load_priority, bundle, url, type, callback, this);
  57. } else {
  58. resLoader.load(bundle, url, type, callback);
  59. }
  60. }
  61. /**
  62. * 在该节点上添加一个网络图片,该资源将随父节点销毁自动销毁,如果父节点被销毁,则销毁资源
  63. * @param url 路径
  64. * @param completed 加载成功后回调
  65. */
  66. // protected loadAvatar(url: string, completed: (res: SpriteFrame) => void) {
  67. // let callback = (error: Error, image: ImageAsset) => {
  68. // if (error) {
  69. // console.error(error);
  70. // } else {
  71. // if (this.isValid) {
  72. // this._addResCache(image);
  73. // let frame = this._net_cache.get(url);
  74. // if (frame) {
  75. // frame.addRef();
  76. // completed && completed(frame);
  77. // } else {
  78. // let texture = new Texture2D();
  79. // texture.image = image;
  80. // let frame = new SpriteFrame();
  81. // frame.texture = texture;
  82. // this._net_cache.set(url, frame);
  83. // frame.addRef();
  84. // completed && completed(frame);
  85. // }
  86. // }
  87. // }
  88. // };
  89. // if (url.indexOf(".png") == -1) {
  90. // assetManager.loadRemote<ImageAsset>(url, { ext: '.png' }, callback);
  91. // } else {
  92. // assetManager.loadRemote<ImageAsset>(url, callback);
  93. // }
  94. // }
  95. private _addResCache(res: Asset) {
  96. ++this._uuid_idx;
  97. let uuid = this.node.uuid + "_<" + this._uuid_sign + ">_[" + this._uuid_idx + "]";
  98. res.addRef();
  99. this._res_cache.set(uuid, res);
  100. return uuid;
  101. }
  102. release() {
  103. // this._net_cache.forEach((frame, url) => {
  104. // if (frame.isValid) {
  105. // const tmp_frame = frame;
  106. // frame.decRef(false);
  107. // frame = null;
  108. // if (tmp_frame.refCount <= 0) {
  109. // let texture = tmp_frame.texture as Texture2D;
  110. // if (tmp_frame.packable) {
  111. // texture = tmp_frame.original?._texture as Texture2D;
  112. // }
  113. // if (texture) {
  114. // texture.image?.decRef();
  115. // texture.image = null;
  116. // texture.destroy();
  117. // }
  118. // tmp_frame.destroy();
  119. // }
  120. // }
  121. // });
  122. // this._net_cache.clear();
  123. this._res_cache.forEach((res) => {
  124. res?.decRef();
  125. res = null;
  126. });
  127. this._res_cache.clear();
  128. }
  129. }