当前位置:   article > 正文

lua 游戏架构 之 LoaderWallet 异步加载

lua 游戏架构 之 LoaderWallet 异步加载

定义了一个名为`LoaderWallet` class,用于管理资源加载器(Loader)。这个类封装了资源加载的功能,包括异步加载,以及资源的释放和状态查询。下面是对代码的详细解释

### 类定义和初始化

这里定义了一个名为`LoaderWallet`的类,并使用`SimpleClassUtil:class()`方法进行初始化

定义 一个对象池:TablePool 类 lua 游戏架构 之 TablePool`对象池-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/heyuchang666/article/details/140530648
定义了一个`cachePool`对象,用于缓存`LoaderWallet`的内部对象,减少内存分配和回收的开销。

  1. local cachePool =
  2. TablePool:new(
  3. 16,
  4. nil,
  5. function(t)
  6. for i, _ in pairs(t) do
  7. t[i] = nil
  8. end
  9. end
  10. )

owner是一个成员变量,用于存储LoaderWallet的拥有者。这个拥有者可以是任何对象,通常是一个游戏对象或场景对象,用于管理资源加载。

  1. function LoaderWallet:initialize(owner)
  2. self.owner = owner
  3. end
  4. function LoaderWallet:setOwner(owner)
  5. self.owner = owner
  6. self.loaders = cachePool:getObj()
  7. self.callbacks = cachePool:getObj()
  8. end

释放所有内部加载器,并释放loaderscallbacks对象。如果LoaderWallet已经被释放过,则输出错误日志。

  1. function LoaderWallet:release()
  2. if not self.owner then
  3. Logger.error("Try to Release LoaderWallet Twice. You should check if nil firstly.")
  4. return
  5. end
  6. for _, loader in pairs(self.loaders) do
  7. loader:release()
  8. end
  9. cachePool:releaseObj(self.loaders)
  10. cachePool:releaseObj(self.callbacks)
  11. self.owner = nil
  12. self.loaders = nil
  13. self.callbacks = nil
  14. if self.rlsFunc then
  15. self.rlsFunc(self)
  16. end
  17. end
设计方法 于查询加载器的状态,包括是否完成、加载进度、是否正在加载以及句柄是否有效。
  • isComplete
  • getProgress
  • isLoading
  • isValidHandle
设计方法用于标记资源是否需要卸载、释放加载器、获取加载完成的资源以及获取子资源
  • markUnloadParam
  • releaseHandle
  • getAsset
  • getSubAsset
设计 异步加载不同类型的资源 方法 loadAssetAsync
  1. 创建资源加载器:使用g.loaderManager:newAssetLoader(path)创建一个新的资源加载器实例,path是资源的路径。
  2. 判断是否使用队列:如果提供了queue参数,则调用loader:loadQueued(queue, self.onLoaderDone, self)将资源加载操作加入队列中,并指定加载完成后的回调函数self.onLoaderDone。否则,调用loader:loadAsync(self.onLoaderDone, self)直接异步加载资源。
  3. 保存加载器实例和回调函数:将加载器实例和对应的回调函数保存到self.loadersself.callbacks表中,使用加载器的句柄(handleID)作为键。
  4. 返回句柄:返回加载器的句柄,用于标识这个加载操作。
  1. ---@param path string
  2. ---@param callback fun(self:table, handle:number) @self是owner
  3. ---@param queue CS.Topjoy.Base.ResourceManagement.OperationHandles.OperationQueue
  4. ---@return number @handle
  5. function LoaderWallet:loadAssetAsync(path, callback, queue)
  6. ---@type AssetLoader
  7. local loader = g.loaderManager:newAssetLoader(path)
  8. if queue then
  9. loader:loadQueued(queue, self.onLoaderDone, self)
  10. else
  11. loader:loadAsync(self.onLoaderDone, self)
  12. end
  13. local handle = loader.handleID
  14. self.loaders[handle] = loader
  15. self.callbacks[handle] = callback
  16. return handle
  17. end

异步加载资源,并允许用户指定加载完成后的回调函数。这对于需要异步加载资源并处理加载结果的应用场景非常有用,比如游戏中的资源预加载、UI资源的动态加载等。

### 注意事项

1. **资源管理**:确保在不再需要资源时及时释放,避免内存泄漏。
2. **错误处理**:在资源加载失败时,应记录错误信息,便于调试。
3. **线程安全**:如果`LoaderWallet`在多线程环境下使用,需要确保线程安全。

这段代码主要用于游戏开发中的资源管理,通过封装资源加载器,简化了资源加载和管理的流程。

  1. --[[
  2. Desc: Loader持有者,封装Release
  3. --]]
  4. ---@class LoaderWallet
  5. local LoaderWallet = SimpleClassUtil:class()
  6. local cachePool =
  7. TablePool:new(
  8. 16,
  9. nil,
  10. function(t)
  11. for i, _ in pairs(t) do
  12. t[i] = nil
  13. end
  14. end
  15. )
  16. function LoaderWallet:initialize(owner)
  17. self.owner = owner
  18. end
  19. function LoaderWallet:setOwner(owner)
  20. self.owner = owner
  21. self.loaders = cachePool:getObj()
  22. self.callbacks = cachePool:getObj()
  23. end
  24. --- 释放所有的内部loader
  25. function LoaderWallet:release()
  26. if not self.owner then
  27. Logger.error("Try to Release LoaderWallet Twice. You should check if nil firstly.")
  28. return
  29. end
  30. for _, loader in pairs(self.loaders) do
  31. loader:release()
  32. end
  33. cachePool:releaseObj(self.loaders)
  34. cachePool:releaseObj(self.callbacks)
  35. self.owner = nil
  36. self.loaders = nil
  37. self.callbacks = nil
  38. if self.rlsFunc then
  39. self.rlsFunc(self)
  40. end
  41. end
  42. ---@private
  43. ---@param loader BaseLoader
  44. function LoaderWallet:onLoaderDone(loader)
  45. if self.owner==nil then
  46. loader:release()
  47. return
  48. end
  49. local handle = loader.handleID
  50. local cb = self.callbacks[handle]
  51. if cb then
  52. cb(self.owner, handle)
  53. end
  54. end
  55. ---@param handle number
  56. ---@return boolean
  57. function LoaderWallet:isComplete(handle)
  58. local loader = self.loaders[handle]
  59. if loader then
  60. return loader.isComplete
  61. end
  62. return false
  63. end
  64. ---@param handle number
  65. ---@return number @[0, 1]
  66. function LoaderWallet:getProgress(handle)
  67. local loader = self.loaders[handle]
  68. if loader then
  69. return loader:getProgress()
  70. end
  71. return 0
  72. end
  73. ---@param handle number
  74. ---@return boolean
  75. function LoaderWallet:isLoading(handle)
  76. local loader = self.loaders[handle]
  77. if loader then
  78. return loader:isLoading()
  79. end
  80. return false
  81. end
  82. ---@param handle number
  83. ---@return boolean
  84. function LoaderWallet:isValidHandle(handle)
  85. return self.loaders[handle]~=nil
  86. end
  87. ---@param handle number
  88. ---@param unload boolean
  89. function LoaderWallet:markUnloadParam(handle, unload)
  90. local loader = self.loaders[handle]
  91. if loader then
  92. loader:markUnloadParam(unload)
  93. else
  94. Logger.error("Miss Loader for handle:", handle)
  95. end
  96. end
  97. ---@param handle number
  98. function LoaderWallet:releaseHandle(handle)
  99. local loader = self.loaders[handle]
  100. if loader then
  101. loader:release()
  102. self.loaders[handle] = nil
  103. self.callbacks[handle] = nil
  104. else
  105. Logger.error("Miss Loader for handle:", handle)
  106. end
  107. end
  108. ---@param path string
  109. ---@return boolean
  110. function LoaderWallet:hasAnyWithPath(path)
  111. for _, loader in pairs(self.loaders) do
  112. if loader.path == path then
  113. return true
  114. end
  115. end
  116. return false
  117. end
  118. --- 获取加载完成后的资源。如,prefab。
  119. ---@param handle number
  120. ---@return CS.UnityEngine.Object
  121. function LoaderWallet:getAsset(handle)
  122. local loader = self.loaders[handle]
  123. if loader then
  124. return loader.result
  125. else
  126. Logger.error("Miss Loader for handle:", handle)
  127. end
  128. end
  129. --- 获取子资源。如,sprite。
  130. ---@param handle number
  131. ---@param name string
  132. ---@return CS.UnityEngine.Object
  133. function LoaderWallet:getSubAsset(handle, name)
  134. local loader = self.loaders[handle]
  135. if loader then
  136. return loader:getSubAsset(name)
  137. else
  138. Logger.error("Miss Loader for handle:", handle)
  139. end
  140. end
  141. ---@param path string
  142. ---@param callback fun(self:table, handle:number) @self是owner
  143. ---@param queue CS.GameYL.Base.ResourceManagement.OperationHandles.OperationQueue
  144. ---@return number @handle
  145. function LoaderWallet:loadAssetAsync(path, callback, queue)
  146. ---@type AssetLoader
  147. local loader = g.loaderManager:newAssetLoader(path)
  148. if queue then
  149. loader:loadQueued(queue, self.onLoaderDone, self)
  150. else
  151. loader:loadAsync(self.onLoaderDone, self)
  152. end
  153. local handle = loader.handleID
  154. self.loaders[handle] = loader
  155. self.callbacks[handle] = callback
  156. return handle
  157. end
  158. ---@param path string
  159. ---@param callback fun(self:table, handle:number) @self是owner
  160. ---@param queue CS.GameYL.Base.ResourceManagement.OperationHandles.OperationQueue
  161. ---@return number @handle
  162. function LoaderWallet:loadListSpriteAsync(path, callback, queue)
  163. ---@type ListSpriteLoader
  164. local loader = g.loaderManager:newListSpriteLoader(path)
  165. if queue then
  166. loader:loadQueued(queue, self.onLoaderDone, self)
  167. else
  168. loader:loadAsync(self.onLoaderDone, self)
  169. end
  170. local handle = loader.handleID
  171. self.loaders[handle] = loader
  172. self.callbacks[handle] = callback
  173. return handle
  174. end
  175. ---@param path string
  176. ---@param callback fun(self:table, handle:number) @self是owner
  177. ---@param queue CS.GameYL.Base.ResourceManagement.OperationHandles.OperationQueue
  178. ---@return number @handle
  179. function LoaderWallet:loadMaterialAsync(path, callback, queue)
  180. ---@type MaterialLoader
  181. local loader = g.loaderManager:newMaterialLoader(path)
  182. if queue then
  183. loader:loadQueued(queue, self.onLoaderDone, self)
  184. else
  185. loader:loadAsync(self.onLoaderDone, self)
  186. end
  187. local handle = loader.handleID
  188. self.loaders[handle] = loader
  189. self.callbacks[handle] = callback
  190. return handle
  191. end
  192. ---@param path string
  193. ---@param callback fun(self:table, handle:number) @self是owner
  194. ---@param queue CS.GameYL.Base.ResourceManagement.OperationHandles.OperationQueue
  195. ---@return number @handle
  196. function LoaderWallet:loadPrefabAsync(path, callback, queue)
  197. ---@type PrefabLoader
  198. local loader = g.loaderManager:newPrefabLoader(path)
  199. if queue then
  200. loader:loadQueued(queue, self.onLoaderDone, self)
  201. else
  202. loader:loadAsync(self.onLoaderDone, self)
  203. end
  204. local handle = loader.handleID
  205. self.loaders[handle] = loader
  206. self.callbacks[handle] = callback
  207. return handle
  208. end
  209. ---@param path string
  210. ---@param callback fun(self:table, handle:number) @self是owner
  211. ---@return number @handle
  212. function LoaderWallet:loadSceneAsync(path, callback)
  213. ---@type SceneLoader
  214. local loader = Global.loaderManager:loadSceneAsync(path, self.onLoaderDone, self)
  215. local handle = loader.handleID
  216. self.loaders[handle] = loader
  217. self.callbacks[handle] = callback
  218. return handle
  219. end
  220. ---@param path string
  221. ---@param callback fun(self:table, handle:number) @self是owner
  222. ---@param queue CS.GameYL.Base.ResourceManagement.OperationHandles.OperationQueue
  223. ---@return number @handle
  224. function LoaderWallet:loadTextAssetAsync(path, callback, queue)
  225. ---@type TextAssetLoader
  226. local loader = g.loaderManager:newTextAssetLoader(path)
  227. if queue then
  228. loader:loadQueued(queue, self.onLoaderDone, self)
  229. else
  230. loader:loadAsync(self.onLoaderDone, self)
  231. end
  232. local handle = loader.handleID
  233. self.loaders[handle] = loader
  234. self.callbacks[handle] = callback
  235. return handle
  236. end
  237. ---@param path string
  238. ---@param callback fun(self:table, handle:number) @self是owner
  239. ---@param queue CS.GameYL.Base.ResourceManagement.OperationHandles.OperationQueue
  240. ---@return number @handle
  241. function LoaderWallet:loadTextureAsync(path, callback, queue)
  242. ---@type TextureLoader
  243. local loader = g.loaderManager:newTextureLoader(path)
  244. if queue then
  245. loader:loadQueued(queue, self.onLoaderDone, self)
  246. else
  247. loader:loadAsync(self.onLoaderDone, self)
  248. end
  249. local handle = loader.handleID
  250. self.loaders[handle] = loader
  251. self.callbacks[handle] = callback
  252. return handle
  253. end
  254. ---@param path string
  255. ---@param callback fun(self:table, handle:number) @self是owner
  256. ---@return number @handle
  257. function LoaderWallet:loadWwiseBankAsync(path, callback)
  258. ---@type WwiseBankLoader
  259. local loader = g.loaderManager:newWwiseBankLoader(path)
  260. loader:loadAsync(self.onLoaderDone, self)
  261. local handle = loader.handleID
  262. self.loaders[handle] = loader
  263. self.callbacks[handle] = callback
  264. return handle
  265. end
  266. ---@overload fun(path:string)
  267. ---@param path string
  268. ---@param decodeBank boolean
  269. ---@param saveDecodedBank boolean
  270. ---@return number @handle
  271. function LoaderWallet:loadWwiseBankSync(path, decodeBank, saveDecodedBank)
  272. ---@type WwiseBankLoader
  273. local loader = g.loaderManager:newWwiseBankLoader(path)
  274. loader.decodeBank = decodeBank
  275. loader.saveDecodedBank = saveDecodedBank
  276. loader:loadSync()
  277. local handle = loader.handleID
  278. self.loaders[handle] = loader
  279. return handle
  280. end
  281. return LoaderWallet

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号