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://www.mzph.cn/bicheng/47636.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WebPack5.0 快速入门

前端工程化WebPack5️⃣ 前置知识: 此文章属于前端——框架进阶篇,需要实现掌握:HTMLCSSJS三件套、Node... 😀推荐分享一波个人Blog文档: JavaScript、前端工程\模块化、邂逅Node.JS的那一夜 什么是WebPack❓ Web…

QT CNA上位机报错 解决方案

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

Kafka Producer之数据重复和乱序问题

文章目录 1. 数据重复2. 数据乱序 为了可靠性,Kafka有消息重试机制,但是同时也带来了2大问题 1. 数据重复 消息发送到broker后,broker记录消息数据到log中,但是由于网络问题,producer没有收到acks,于是再次…

【机器学习实战】Datawhale夏令营2:深度学习回顾

#DataWhale夏令营 #ai夏令营 文章目录 1. 深度学习的定义1.1 深度学习&图神经网络1.2 机器学习和深度学习的关系 2. 深度学习的训练流程2.1 数学基础2.1.1 梯度下降法基本原理数学表达步骤学习率 α梯度下降的变体 2.1.2 神经网络与矩阵网络结构表示前向传播激活函数…

Three.js 实战【2】—— 船模型海上场景渲染

停止了好久没有更新three这方面的文章了,从上两年还是vue2,一下子都换到vue3了,下面这些three都是基于vue3来进行开发的哈,先看一下这篇文章实现的效果哈。其中关于模型什么的资源都放在Git上了 初始化场景 安装three就直接通过n…

springboot系列十: 自定义转换器,处理JSON,内容协商

文章目录 自定义转换器基本介绍应用实例查看源码注意事项和细节 处理JSON需求说明应用实例 内容协商基本介绍应用实例debug源码优先返回xml注意事项和细节 ⬅️ 上一篇: springboot系列九: 接收参数相关注解 🎉 欢迎来到 springboot系列十: 自定义转换器&#xff0c…

ssh远程登录另一台linux电脑

大部分的博客内容所说的安装好ssh服务后,terminal输入 ssh -p port_number clientnameserver_ip 之后输入密码等等就可以登上别人的电脑 但是这是有一个前提的,就是这两台电脑要在同一个局域网下面。 如果很远呢? 远到不在同一个网下面怎么办…

1.JavaWeb开发简介(Tomcat安装使用+Servlet简介)

文章目录 一.web开发简介1.概念:2.特点:3.常用技术:4.服务架构5.web应用开发模式6.HTTP协议1)概念:2)HTTP最基本的过程是:3)IP/域名4)HTTP协议请求方式 7.JavaWeb的相关技术8.Java Web服务器 二、安装配置Tomcat1.简介2.Tomcat目录结构 三.Servlet的入门应用1.使用步骤2.使用注…

ABAP使用SQL直接更新数据库与使用IN UPDATE TASK的区别

1. 背景 刚接触ABAP的小伙伴常常会有这样的疑问,为什么不直接使用Open SQL直接更新数据库,而要把对DB的操作封装到IN UPDATE TASK中呢? 对于这个问题,比较常见的解释是,IN UPDATE TASK的方式会保证数据更新的一致性。…

接口开发:Orcal数据库的批量修改sql

场景:在日常的CURD中一定会用到批量修改。在我们的项目中,使用的数据库是Orcal,由于之前基本都是使用Mysql的,使用的sql语句也基本都是用mysql的。但是在这次的接口编写时用mysql的批量修改出了问题,刚开始我还以为是写…

如何每天不用动手就可以自动加人

只需要设置一次,批量导入客户号码或是微信号并设置好添加规则,系统就会自动进行添加。

Elastic 线下 Meetup 将于 2024 年 7 月 27 号在深圳举办

2024 Elastic Meetup 深圳站活动,由 Elastic、腾讯、新智锦绣联合举办,现诚邀广大技术爱好者及开发者参加。 时间地点 2024年 7 月 27 日 13:30-18:00 活动地点 中国深圳 南山区海天二路 33 号腾讯滨海大厦 北塔 3 楼多功能厅 ​ 活动流程 14:00-15…

HTTP请求走私漏洞原理与利用手段分析

文章目录 前言Http请求走私1.1 漏洞诞生场景1.2 漏洞基本原理1.3 HTTP1.1与2.0 请求走私分类2.1 CL.TE类型实例2.2 TE.CL类型实例2.3 TE.TE混淆实例2.4 漏洞检测工具? 请求走私利用3.1 绕过前端安全控制3.2 揭示前端请求重写3.3 捕获他人请求内容3.4 走私构造反射XS…

从数据湖到湖仓一体:统一数据架构演进之路

文章目录 一、前言二、什么是湖仓一体?起源概述 三、为什么要构建湖仓一体?1. 成本角度2. 技术角度 四、湖仓一体实践过程阶段一:摸索阶段(仓、湖并行建设)阶段二:发展阶段方式一、湖上建仓(湖在下、仓在上)方式二:仓外…

MySQL运维实战之Clone插件(10.1)使用Clone插件

作者:俊达 clone插件介绍 mysql 8.0.17版本引入了clone插件。使用clone插件可以对本地l或远程的mysql实例进行clone操作。clone插件会拷贝innodb存储引擎表,clone得到的是原数据库的一个一致性的快照,可以使用该快照数据来启动新的实例。cl…

SpringMVC注解全解析:构建高效Web应用的终极指南 (下)

一. 引言 在上篇文章中,我们介绍了几个重要的SpringMVC注解: SpringBootApplication:Spring Boot项目的启动类注解。RequestMapping:用于映射URL到控制器类或方法,支持多种请求方式。RequestParam:用于绑…

UniVue@v1.5.0版本发布:里程碑版本

前言 以后使用UniVue都推荐使用1.5.0以后的版本,这个版本之后,更新的速度将会放缓。 希望这个框架能够切实的帮助大家更好的开发游戏,做出一款好游戏!本开源项目采用的开源协议为MIT协议,完全开源化,以后也…

基于Python+Django+MySQL的心理咨询预约系统

心理咨询预约系统 DjangoMySQL 基于PythonDjangoMySQL的心理咨询预约系统 项目主要依赖Django3.2,MySQL 支持随机验证码生成与登录验证 简介 基于PythonDjangoMySQL的心理咨询预约系统通过连接数据库获取数据,登录新增随机数字验证码验证。具体可以看…

【机器学习】机器学习与图像分类的融合应用与性能优化新探索

文章目录 引言第一章:机器学习在图像分类中的应用1.1 数据预处理1.1.1 数据清洗1.1.2 数据归一化1.1.3 数据增强 1.2 模型选择1.2.1 卷积神经网络1.2.2 迁移学习1.2.3 混合模型 1.3 模型训练1.3.1 梯度下降1.3.2 随机梯度下降1.3.3 Adam优化器 1.4 模型评估与性能优…

Qt支持LG高级汽车内容平台

Qt Group与LG 电子(简称LG)正携手合作,将Qt软件框架嵌入其基于 webOS的ACPLG车载娱乐平台,用于应用程序开发。该合作旨在让原始设备制造商(OEM)的开发者和设计师能为汽车创建更具创新性的沉浸式汽车内容流媒…