加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

cocos2d-x中的图片异步加载机制

发布时间:2020-12-14 16:59:54 所属栏目:百科 来源:网络整理
导读:3.X版本的cocos2d-x使用C++11标准,最新的C++11标准引入了对线程的原生支持,下面对其做简单介绍。在C++11标准中可以使用std::thread来快速创建一个线程: void threadFunc1(){ std::cout "threadFunc1:t" std::endl; // sleep 1 秒 std::this_thread::slee
3.X版本的cocos2d-x使用C++11标准,最新的C++11标准引入了对线程的原生支持,下面对其做简单介绍。在C++11标准中可以使用std::thread来快速创建一个线程:
void threadFunc1(){
std::cout << "threadFunc1:t" << std::endl;
// sleep 1 秒
std::this_thread::sleep_for(std::chrono::seconds(1));
}
std::thread thread1(&threadFunc1);
至此我们已经创建了一个线程thread1,可以对线程进行相应的join,detach等操作。

3.X版本的cocos2d-x使用std::thread创建的线程来进行资源的加载,cocos使用 TextureCache 来对纹理资源进行统一管理,在2.X版本中其是一个单件,用户可以直接在脚本层调用getInstance方法来获得对TextureCache的引用,而在3.X版本中,TextureCache由Director来进行管理。TextureCache提供了两个接口(这里只讨论这两个接口):
Texture2D * addImage( const std:: string &filepath);
virtual void addImageAsync( const std:: string &filepath, const std:: function < void ( Texture2D *)>& callback);
顾名思义,第一个函数提供了直接加载纹理资源的方法,查看cocos2d-x的源码发现,该方法首先在TextureCache的缓存中查找相应的纹理资源,如果未找到则直接从磁盘中读取文件,并加入到相应缓存中。而第二个函数则是其对应的异步操作方法,该方法相对复杂,下面我们来重点看该方法的实现机制。
std:: function也是在C++11引入一种通用多态函数封装器( general-purpose polymorphic function wrapper )猛戳,addImageAsync的最后一个参数是当纹理资源加载完成时对调用该回调函数。 下面给出资源加载的流程图,其中忽略了loadImage线程的创建及定时器的启动销毁过程:

从流程图及源代码中可看出addImageAsync接口首先去查询缓存,如果命中则直接使用callback来处理结果,否则将要请求的资源添加到一个请求队列 _asyncStructQueue,并使用 notify_one()通知加载线程进行相应的加载操作,TextureCache使用了Lazy的方法来创建线程(线程函数loadImage),即实例化TextureCache时并不创建线程,而是等到需要异步加载时如果线程还未创建则创建一个线程。

TextureCache ::loadImage()是TextureCache的线程函数,内部运行了一个while(true)循环,当请求队列不为空时则取出队列头进行处理,该线程使用 initWithImageFileThreadSafe来从磁盘中读取数据并创建一个texture,最后将加载好的texture放入另一个队列 _imageInfoQueue中。相反如果队列为空,则使用wait方法进行等待。

addImageAsync方法中启动了一个定时器:
Director ::getInstance()->getScheduler()->schedule( schedule_selector ( TextureCache ::addImageAsyncCallBack), this , false );,该定时器会在每帧去检查_imageInfoQueue,如果该队列不为空,则在该帧中对_imageInfoQueue中的每个元素调用callback方法来进行渲染,当 _asyncRefCount == 0时,也即所有需要加载的纹理都已加载完成,则将该定时器清除。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读