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`的内部对象,减少内存分配和回收的开销。

local cachePool =TablePool:new(16,nil,function(t)for i, _ in pairs(t) dot[i] = nilendend
)

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

function LoaderWallet:initialize(owner)self.owner = owner
endfunction LoaderWallet:setOwner(owner)self.owner = ownerself.loaders = cachePool:getObj()self.callbacks = cachePool:getObj()
end

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

function LoaderWallet:release()if not self.owner thenLogger.error("Try to Release LoaderWallet Twice. You should check if nil firstly.")returnendfor _, loader in pairs(self.loaders) doloader:release()endcachePool:releaseObj(self.loaders)cachePool:releaseObj(self.callbacks)self.owner = nilself.loaders = nilself.callbacks = nilif self.rlsFunc thenself.rlsFunc(self)end
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. 返回句柄:返回加载器的句柄,用于标识这个加载操作。
---@param path string
---@param callback fun(self:table, handle:number) @self是owner
---@param queue CS.Topjoy.Base.ResourceManagement.OperationHandles.OperationQueue
---@return number @handle
function LoaderWallet:loadAssetAsync(path, callback, queue)---@type AssetLoaderlocal loader = g.loaderManager:newAssetLoader(path)if queue thenloader:loadQueued(queue, self.onLoaderDone, self)elseloader:loadAsync(self.onLoaderDone, self)endlocal handle = loader.handleIDself.loaders[handle] = loaderself.callbacks[handle] = callbackreturn handle
end

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

### 注意事项

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

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

--[[Desc: Loader持有者,封装Release
--]]---@class LoaderWallet
local LoaderWallet = SimpleClassUtil:class()
local cachePool =TablePool:new(16,nil,function(t)for i, _ in pairs(t) dot[i] = nilendend
)
function LoaderWallet:initialize(owner)self.owner = owner
endfunction LoaderWallet:setOwner(owner)self.owner = ownerself.loaders = cachePool:getObj()self.callbacks = cachePool:getObj()
end--- 释放所有的内部loader
function LoaderWallet:release()if not self.owner thenLogger.error("Try to Release LoaderWallet Twice. You should check if nil firstly.")returnendfor _, loader in pairs(self.loaders) doloader:release()endcachePool:releaseObj(self.loaders)cachePool:releaseObj(self.callbacks)self.owner = nilself.loaders = nilself.callbacks = nilif self.rlsFunc thenself.rlsFunc(self)end
end---@private
---@param loader BaseLoader
function LoaderWallet:onLoaderDone(loader)if self.owner==nil thenloader:release()returnendlocal handle = loader.handleIDlocal cb = self.callbacks[handle]if cb thencb(self.owner, handle)end
end---@param handle number
---@return boolean
function LoaderWallet:isComplete(handle)local loader = self.loaders[handle]if loader thenreturn loader.isCompleteendreturn false
end---@param handle number
---@return number @[0, 1]
function LoaderWallet:getProgress(handle)local loader = self.loaders[handle]if loader thenreturn loader:getProgress()endreturn 0
end---@param handle number
---@return boolean
function LoaderWallet:isLoading(handle)local loader = self.loaders[handle]if loader thenreturn loader:isLoading()endreturn false
end---@param handle number
---@return boolean
function LoaderWallet:isValidHandle(handle)return self.loaders[handle]~=nil
end---@param handle number
---@param unload boolean
function LoaderWallet:markUnloadParam(handle, unload)local loader = self.loaders[handle]if loader thenloader:markUnloadParam(unload)elseLogger.error("Miss Loader for handle:", handle)end
end---@param handle number
function LoaderWallet:releaseHandle(handle)local loader = self.loaders[handle]if loader thenloader:release()self.loaders[handle] = nilself.callbacks[handle] = nilelseLogger.error("Miss Loader for handle:", handle)end
end---@param path string
---@return boolean
function LoaderWallet:hasAnyWithPath(path)for _, loader in pairs(self.loaders) doif loader.path == path thenreturn trueendendreturn false
end--- 获取加载完成后的资源。如,prefab。
---@param handle number
---@return CS.UnityEngine.Object
function LoaderWallet:getAsset(handle)local loader = self.loaders[handle]if loader thenreturn loader.resultelseLogger.error("Miss Loader for handle:", handle)end
end--- 获取子资源。如,sprite。
---@param handle number
---@param name string
---@return CS.UnityEngine.Object
function LoaderWallet:getSubAsset(handle, name)local loader = self.loaders[handle]if loader thenreturn loader:getSubAsset(name)elseLogger.error("Miss Loader for handle:", handle)end
end---@param path string
---@param callback fun(self:table, handle:number) @self是owner
---@param queue CS.GameYL.Base.ResourceManagement.OperationHandles.OperationQueue
---@return number @handle
function LoaderWallet:loadAssetAsync(path, callback, queue)---@type AssetLoaderlocal loader = g.loaderManager:newAssetLoader(path)if queue thenloader:loadQueued(queue, self.onLoaderDone, self)elseloader:loadAsync(self.onLoaderDone, self)endlocal handle = loader.handleIDself.loaders[handle] = loaderself.callbacks[handle] = callbackreturn handle
end---@param path string
---@param callback fun(self:table, handle:number) @self是owner
---@param queue CS.GameYL.Base.ResourceManagement.OperationHandles.OperationQueue
---@return number @handle
function LoaderWallet:loadListSpriteAsync(path, callback, queue)---@type ListSpriteLoaderlocal loader = g.loaderManager:newListSpriteLoader(path)if queue thenloader:loadQueued(queue, self.onLoaderDone, self)elseloader:loadAsync(self.onLoaderDone, self)endlocal handle = loader.handleIDself.loaders[handle] = loaderself.callbacks[handle] = callbackreturn handle
end---@param path string
---@param callback fun(self:table, handle:number) @self是owner
---@param queue CS.GameYL.Base.ResourceManagement.OperationHandles.OperationQueue
---@return number @handle
function LoaderWallet:loadMaterialAsync(path, callback, queue)---@type MaterialLoaderlocal loader = g.loaderManager:newMaterialLoader(path)if queue thenloader:loadQueued(queue, self.onLoaderDone, self)elseloader:loadAsync(self.onLoaderDone, self)endlocal handle = loader.handleIDself.loaders[handle] = loaderself.callbacks[handle] = callbackreturn handle
end---@param path string
---@param callback fun(self:table, handle:number) @self是owner
---@param queue CS.GameYL.Base.ResourceManagement.OperationHandles.OperationQueue
---@return number @handle
function LoaderWallet:loadPrefabAsync(path, callback, queue)---@type PrefabLoaderlocal loader = g.loaderManager:newPrefabLoader(path)if queue thenloader:loadQueued(queue, self.onLoaderDone, self)elseloader:loadAsync(self.onLoaderDone, self)endlocal handle = loader.handleIDself.loaders[handle] = loaderself.callbacks[handle] = callbackreturn handle
end---@param path string
---@param callback fun(self:table, handle:number) @self是owner
---@return number @handle
function LoaderWallet:loadSceneAsync(path, callback)---@type SceneLoaderlocal loader = Global.loaderManager:loadSceneAsync(path, self.onLoaderDone, self)local handle = loader.handleIDself.loaders[handle] = loaderself.callbacks[handle] = callbackreturn handle
end---@param path string
---@param callback fun(self:table, handle:number) @self是owner
---@param queue CS.GameYL.Base.ResourceManagement.OperationHandles.OperationQueue
---@return number @handle
function LoaderWallet:loadTextAssetAsync(path, callback, queue)---@type TextAssetLoaderlocal loader = g.loaderManager:newTextAssetLoader(path)if queue thenloader:loadQueued(queue, self.onLoaderDone, self)elseloader:loadAsync(self.onLoaderDone, self)endlocal handle = loader.handleIDself.loaders[handle] = loaderself.callbacks[handle] = callbackreturn handle
end---@param path string
---@param callback fun(self:table, handle:number) @self是owner
---@param queue CS.GameYL.Base.ResourceManagement.OperationHandles.OperationQueue
---@return number @handle
function LoaderWallet:loadTextureAsync(path, callback, queue)---@type TextureLoaderlocal loader = g.loaderManager:newTextureLoader(path)if queue thenloader:loadQueued(queue, self.onLoaderDone, self)elseloader:loadAsync(self.onLoaderDone, self)endlocal handle = loader.handleIDself.loaders[handle] = loaderself.callbacks[handle] = callbackreturn handle
end---@param path string
---@param callback fun(self:table, handle:number) @self是owner
---@return number @handle
function LoaderWallet:loadWwiseBankAsync(path, callback)---@type WwiseBankLoaderlocal loader = g.loaderManager:newWwiseBankLoader(path)loader:loadAsync(self.onLoaderDone, self)local handle = loader.handleIDself.loaders[handle] = loaderself.callbacks[handle] = callbackreturn handle
end---@overload fun(path:string)
---@param path string
---@param decodeBank boolean
---@param saveDecodedBank boolean
---@return number @handle
function LoaderWallet:loadWwiseBankSync(path, decodeBank, saveDecodedBank)---@type WwiseBankLoaderlocal loader = g.loaderManager:newWwiseBankLoader(path)loader.decodeBank = decodeBankloader.saveDecodedBank = saveDecodedBankloader:loadSync()local handle = loader.handleIDself.loaders[handle] = loaderreturn handle
endreturn LoaderWallet

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3249114.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

QT CNA上位机报错 解决方案

QT编译报错: -lControlCAN 解决方案 更换三个文件,即可解决(QT 自带的是32位库,应使用64位库文件)

【Vue】快速入门:构建你的第一个Vue 3应用

文章目录 一、Vue简介二、环境搭建1. 安装Node.js和npm2. 安装Vue CLI 三、创建Vue项目四、项目结构介绍五、组件基础创建一个组件使用组件 六、模板语法插值指令v-bindv-ifv-for 七、事件处理八、状态管理安装Vuex创建Store使用Store 九、路由基础安装Vue Router配置路由使用路…

PiT : 基于池化层Pooling layer的Vision Transformer

CNN的降维原理;随着深度的增加,传统CNN的通道维数增加,空间维数减少。经验表明,这样的空间降维对变压器结构也是有益的,并在原有的ViT模型的基础上提出了一种新的基于池的视觉变压器(PiT)。 1. 引言 ViT与卷积神经网络(CNN)有很大的不同。将输入图像分成1616小块馈送到变压…

力扣刷题之2959.关闭分部的可行集合数目

题干描述 一个公司在全国有 n 个分部,它们之间有的有道路连接。一开始,所有分部通过这些道路两两之间互相可以到达。 公司意识到在分部之间旅行花费了太多时间,所以它们决定关闭一些分部(也可能不关闭任何分部)&…

mysql group_concat()函数、行转列函数

文章目录 一、group_concat函数1.1、语法1.2、示例1.2.1、查询所有姓名,并显示在一行1.2.2、单列合并,指定冒号分隔符1.2.3、单列合并,去重1.2.4、多列拼接合并1.2.5、多列拼接合并,列和列之间指定分隔符 在mysql的关联查询或子查…

周报0708-0715(run代码)

本周围绕代码展开学习,学习了组内的FWI代码,主要收获是熟练了创建环境、匹配解释器、安装必要包的流程,以及搜索时的小Tips:比如需要的包whl(表示该包的编译版本)。遇到的问题仍然不少 三个主要问题&#…

「实战应用」如何用图表控件LightningChart JS创建树状图应用?

LightningChart JS是Web上性能特高的图表库,具有出色的执行性能 - 使用高数据速率同时监控数十个数据源。 GPU加速和WebGL渲染确保您的设备的图形处理器得到有效利用,从而实现高刷新率和流畅的动画,常用于贸易,工程,航…

Go语言并发编程-同步和锁

同步和锁 概述 同步是并发编程的基本要素之一,我们通过channel可以完成多个goroutine间数据和信号的同步。 除了channel外,我们还可以使用go的官方同步包sync,sync/atomic 完成一些基础的同步功能。主要包含同步数据、锁、原子操作等。 一…

P3-AI产品经理-九五小庞

AI产品的数据流向 美团外卖,实时只能调度 美团28分钟送达需求的分析 AI产品常用的算法 常用算法 常见的AI算法解析 自然语言生成NLG语音识别:科大讯飞,通义千问 虚拟现实机器学习平台 决策管理系统生物特征识别技术 RPA(机器人流程自动…

ICE-BA原理

文章目录 主要思想约束建立IMU&Local & globalBAIMU预积分LocalBAGlobalBA求解方法常用的求解思路改进增量BA方法 论文: 《ICE-BA: Incremental, Consistent and Efficient Bundle Adjustment for Visual-Inertial SLAM》 ICE-BA:增量、一致且高…

多商户SaaS版扫码点餐系统开源

基于前后端分离的 多商户 SaaS 版扫码点餐系统,支持后台点餐、多人同时在线点餐、购物车共享、餐桌状态实时监控,菜品管理、餐桌管理等众多功能。 源码下载:多商户 SaaS 版扫码点餐系统.zip 功能特色 手机扫码点餐功能:用户可…

如何评价2023年国际高校数学建模竞赛B题?

问题1:在三星堆发现的一个外圆直径为85厘米,内圆直径为40厘米(假设)的青铜车轮,青铜车轮有5条车轴(射线),5条内弧线本质是双曲线,顶点与内圆相切,内弧双曲线的…

植物病害分级调研

Web of Science搜索,关键字“plant disease severity recognition”,共407篇,限制2023年以后共71篇 2019、2020 《Disentangled Representation Learning for Leaf Diseases Recognition》 2019 IF:0.8 论文:Disen…

Xcode进行真机测试时总是断连,如何解决?

嗨。大家好,我是兰若姐姐。最近我在用真机进行app自动化测试的时候,经常会遇到xcode和手机断连,每次断连之后需要重新连接,每次断开都会出现以下截图的报错 当这种情况出现时,之前执行的用例就相当于白执行了&#xff…

爬虫瑞数5案例:某大学总医院

声明: 该文章为学习使用,严禁用于商业用途和非法用途,违者后果自负,由此产生的一切后果均与作者无关 一、瑞数简介 瑞数动态安全 Botgate(机器人防火墙)以“动态安全”技术为核心,通过动态封装、动态验证、动态混淆、动态令牌等技术对服务器网页底层代码持续动态变换,…

Go语言并发编程-Goroutine调度

goroutine 概念 在Go中,每个并发执行的单元称为goroutine。通常称为Go协程。 go 关键字启动goroutine go中使用关键字 go 即可启动新的goroutine。 示例代码: 两个函数分别输出奇数和偶数。采用常规调用顺序执行,和采用go并发调用&…

大模型学习笔记十一:视觉大模型

一、判别式模型和生成式模型 1)判别式模型Discriminative ①给某一个样本,判断属于某个类别的概率,擅长分类任务,计算量少。(学习策略函数Y f(X)或者条件概率P(YIX)) ②不能反映训练数据本身的特性 ③学习…

优思学院|直方图与条形图的具体区别

在六西格玛方法、质量管理工具中,数据的分析和可视化是关键步骤。直方图和条形图是两种常用的图表工具,但它们在用途和显示方式上有显著区别。本文将详细探讨这两种图表的定义、特性、应用及如何选择适合的图表。 1. 直方图和条形图的定义 直方图是一种…

人工智能未来发展前景将会怎样?

当我们探讨人工智能未来的发展前景时,可以从多个角度来详细说明其可能的影响和趋势: 技术进步与应用扩展 1.深度学习与机器学习: 进一步优化和算法进展:深度学习已经取得了巨大成就,但仍面临挑战,如对小数…

程序员想要6万一个月,需要什么能力,要吃什么样的苦?

让我们来算一道小学数学题:6w*1272w,年包72w的程序员起码是阿里P7-P8的水平了,论工作职责来说,起码得是大厂的一个小tech leader,如果是在小公司,基本上是公司骨干级成员,或是统筹整个项目和小组…