一、说明

    异步加载就是把消耗程序时间比较大的加载操作放到其他线程中,待加载完毕后通过回调函数的方式通知主线程。
 
addImageAsync函数实现(Cocos2dx 3.3)

Link: http://codepad.org/UuNcXMqq    [ raw code | fork ]  
 
  1. void TextureCache::addImageAsync(const std::string &path, const std::function<void(Texture2D*)>& callback)
  2. {
  3. Texture2D *texture = nullptr;
  4.  
  5. std::string fullpath = FileUtils::getInstance()->fullPathForFilename(path);
  6.  
  7. auto it = _textures.find(fullpath);
  8. if( it != _textures.end() )
  9. texture = it->second;
  10.  
  11. if (texture != nullptr)
  12. {
  13. callback(texture);
  14. return;
  15. }
  16.  
  17. // lazy init
  18. if (_asyncStructQueue == nullptr)
  19. {
  20. _asyncStructQueue = new queue<AsyncStruct*>();
  21. _imageInfoQueue = new deque<ImageInfo*>();
  22.  
  23. // create a new thread to load images
  24. _loadingThread = new std::thread(&TextureCache::loadImage, this);
  25.  
  26. _needQuit = false;
  27. }
  28.  
  29. if ( == _asyncRefCount)
  30. {
  31. Director::getInstance()->getScheduler()->schedule(CC_SCHEDULE_SELECTOR(TextureCache::addImageAsyncCallBack), this, , false);
  32. }
  33.  
  34. ++_asyncRefCount;
  35.  
  36. // generate async struct
  37. AsyncStruct *data = new (std::nothrow) AsyncStruct(fullpath, callback);
  38.  
  39. // add async struct into queue
  40. _asyncStructQueueMutex.lock();
  41. _asyncStructQueue->push(data);
  42. _asyncStructQueueMutex.unlock();
  43.  
  44. _sleepCondition.notify_one();
  45. }
异步加载实例:
    ImageAsync.lua

Link: http://codepad.org/ydr3m4bK    [ raw code | fork ]  
  1. --图片异步加载
  2. ImageAsync=class("ImageAsync",function()
  3. return cc.Layer:create()
  4. end)
  5.  
  6. ImageAsync.ctor=function(self)
  7. self.size=cc.Director:getInstance():getWinSize()
  8. self:initTexture()
  9. self:loadingLabel()
  10. self.curIndex= --当前loaded的图片编号
  11.  
  12. self:registerScriptHandler(function(tag)
  13. if tag=="enter" then
  14. --设置定时器
  15. self:scheduleUpdateWithPriorityLua(function(dt)
  16. self:loadTexture()
  17. end,)
  18. elseif tag=="exit" then
  19. cclog("exit")
  20. self:unscheduleUpdate()
  21. cc.Director:getInstance():getTextureCache():removeAllTextures()
  22. end
  23. end)
  24. end
  25.  
  26. --初始化loadding label
  27. ImageAsync.loadingLabel=function(self)
  28. local label=cc.Label:createWithTTF("Loading...0%", "res/fonts/arial.ttf", )
  29. label:setPosition(self.size.width/,self.size.height/)
  30. self:addChild(label)
  31. self.label=label
  32. end
  33.  
  34. --初始化图片集
  35. ImageAsync.initTexture=function(self)
  36. self.textures={}
  37. for i=, do
  38. for j=, do
  39. local image=string.format("Images/sprites_test/sprite-%d-%d.png",i,j)
  40. table.insert(self.textures,image)
  41. end
  42. end
  43. end
  44.  
  45. --异步加载图片
  46. ImageAsync.loadTexture=function(self)
  47. local function loadedImage(texture)
  48. local sprite=cc.Sprite:createWithTexture(texture)
  49. sprite:setPosition(cc.p(self.size.width/,self.size.height/))
  50. sprite:setScale()
  51. self:addChild(sprite)
  52. self.curIndex=self.curIndex+
  53. self.label:setString(string.format("Loading...%d%%",math.floor(*self.curIndex/#self.textures)))
  54. cclog(string.format("loaded self.textures[%d]:%s",self.curIndex,self.textures[self.curIndex]))
  55. end
  56.  
  57. local textureCache=cc.Director:getInstance():getTextureCache()
  58. for i=,#self.textures do
  59. textureCache:addImageAsync(self.textures[i],loadedImage)
  60. end
  61.  
  62. self:unscheduleUpdate()
  63. end
  64.  
  65. ImageAsync.create=function()
  66. local layer=ImageAsync.new()
  67. return layer
  68. end
  69.  
  70. return ImageAsync
执行效果:
    
 
补充说明:
    Cocos2dx TextureCache会加载图片到内存中,创建Sprite  initWithFile时如果内存中已经有该texture直接使用该texture,这样就达到了减少切换界面时出现的卡顿(直接从内存中取资源,而非IO操作),具体实现如下:
    
 
TextureCache的addImage实现如下:
  1. Texture2D * TextureCache::addImage(const std::string &path)
  2. {
  3. Texture2D * texture = nullptr;
  4. Image* image = nullptr;
  5. // Split up directory and filename
  6. // MUTEX:
  7. // Needed since addImageAsync calls this method from a different thread
  8.  
  9. std::string fullpath = FileUtils::getInstance()->fullPathForFilename(path);
  10. if (fullpath.size() == )
  11. {
  12. return nullptr;
  13. }
  14. auto it = _textures.find(fullpath);
  15. if( it != _textures.end() )
  16. texture = it->second;
  17.  
  18. if (! texture)
  19. {
  20. // all images are handled by UIImage except PVR extension that is handled by our own handler
  21. do
  22. {
  23. image = new (std::nothrow) Image();
  24. CC_BREAK_IF(nullptr == image);
  25.  
  26. bool bRet = image->initWithImageFile(fullpath);
  27. CC_BREAK_IF(!bRet);
  28.  
  29. texture = new (std::nothrow) Texture2D();
  30.  
  31. if( texture && texture->initWithImage(image) )
  32. {
  33. #if CC_ENABLE_CACHE_TEXTURE_DATA
  34. // cache the texture file name
  35. VolatileTextureMgr::addImageTexture(texture, fullpath);
  36. #endif
  37. // texture already retained, no need to re-retain it
  38. _textures.insert( std::make_pair(fullpath, texture) );
  39. }
  40. else
  41. {
  42. CCLOG("cocos2d: Couldn't create texture for file:%s in TextureCache", path.c_str());
  43. }
  44. } while ();
  45. }
  46.  
  47. CC_SAFE_RELEASE(image);
  48.  
  49. return texture;
  50. }
 
补充说明:
    异步加载plist和png图片——方法是在异步加载png图片的回调函数中,加载plist文件
    Link: http://codepad.org/BuWR4Hdl    [ raw code | fork ]
 
  1. local BaseLoading=class("BaseLoading",function()
  2. return cc.Layer:create()
  3. end)
  4.  
  5. BaseLoading.init=function(self)
  6. self._size=cc.Director:getInstance():getWinSize()
  7. self._textures={}
  8. self._curIndex= --当前loaded的图片编号
  9.  
  10. self:initTexture()
  11. self:loadingUI()
  12. end
  13.  
  14. --需要加载的所有资源文件
  15. BaseLoading.initTexture=function(self)
  16.  
  17. end
  18.  
  19. --异步加载图片
  20. BaseLoading.loadTexture=function(self)
  21. local frameCache=cc.SpriteFrameCache:getInstance()
  22. --加载图片
  23. local function loadPng(texture)
  24. self._label:setString(string.format("Loading...%d%%",math.floor(*self._curIndex/#self._textures)))
  25. cclog(string.format("loaded self.textures[%d]:%s",self._curIndex,self._textures[self._curIndex].loc..".png"))
  26. if self._curIndex==#self._textures then
  27. self:finishLoading()
  28. end
  29. self._curIndex=self._curIndex+
  30. end
  31.  
  32. --加载Plist图片
  33. local function loadPlist(texture)
  34. frameCache:addSpriteFrames(self._textures[self._curIndex].loc..".plist")
  35. self._label:setString(string.format("Loading...%d%%",math.floor(*self._curIndex/#self._textures)))
  36. cclog(string.format("loaded self.textures[%d]:%s",self._curIndex,self._textures[self._curIndex].loc..".png"))
  37. if self._curIndex==#self._textures then
  38. self:finishLoading()
  39. end
  40. self._curIndex=self._curIndex+
  41. end
  42.  
  43. local textureCache=cc.Director:getInstance():getTextureCache()
  44. for i=,#self._textures do
  45. local rtype=self._textures[i].rtype
  46. if rtype=="png" then
  47. textureCache:addImageAsync(self._textures[i].loc..".png",loadPng)
  48. elseif rtype=="plist" then
  49. textureCache:addImageAsync(self._textures[i].loc..".png",loadPlist)
  50. end
  51. end
  52. self:unscheduleUpdate()
  53. end
  54.  
  55. --loading UI
  56. BaseLoading.loadingUI=function(self)
  57. local label=cc.Label:createWithTTF("Loading...0%", "res/fonts/Marker Felt.ttf", )
  58. label:setPosition(self._size.width/,self._size.height/)
  59. self:addChild(label)
  60. self._label=label
  61. end
  62.  
  63. BaseLoading.startLoading=function(self)
  64. self:registerScriptHandler(function(tag)
  65. if tag=="enter" then
  66. --设置定时器
  67. self:scheduleUpdateWithPriorityLua(function(dt)
  68. self:loadTexture()
  69. end,)
  70. elseif tag=="exit" then
  71. self:unscheduleUpdate()
  72. end
  73. end)
  74. end
  75.  
  76. --完成异步加载图片回调函数
  77. BaseLoading.finishLoading=function(self)
  78.  
  79. end
  80.  
  81. return BaseLoading
补充说明:
    异步加载plist纹理和png图片
    加载plist时,先加载plist对应的png图片,加载plist对应的png图片之后,在异步回调函数中,将plist载入textureCache中
 
 

【Cocos2dx3.x Lua】图片异步加载的更多相关文章

  1. cocos2dx lua中异步加载网络图片,可用于显示微信头像

    最近在做一个棋牌项目,脚本语言用的lua,登录需要使用微信登录,用户头像用微信账户的头像,微信接口返回的头像是一个url,那么遇到的一个问题就是如何在lua中异步加载这个头像,先在引擎源码里找了下可能 ...

  2. Android-Universal-Image-Loader 图片异步加载类库的使用

    在博客中看到一篇利用组件进行图片异步加载的文章在此作记录 原文:http://blog.csdn.net/vipzjyno1/article/details/23206387 这个图片异步加载并缓存的 ...

  3. Android图片异步加载框架Android-Universal-Image-Loader

    版权声明:本文为博主原创文章,未经博主允许不得转载. Android-Universal-Image-Loader是一个图片异步加载,缓存和显示的框架.这个框架已经被很多开发者所使用,是最常用的几个 ...

  4. Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)

    这个图片异步加载并缓存的类已经被很多开发者所使用,是最常用的几个开源库之一,主流的应用,随便反编译几个火的项目,都可以见到它的身影. 可是有的人并不知道如何去使用这库如何进行配置,网上查到的信息对于刚 ...

  5. Android ListView 图片异步加载和图片内存缓存

    开发Android应用经常需要处理图片的加载问题.因为图片一般都是存放在服务器端,需要联网去加载,而这又是一个比较耗时的过程,所以Android中都是通过开启一个异步线程去加载.为了增加用户体验,给用 ...

  6. Android 图片异步加载的体会,SoftReference已经不再适用

      在网络上搜索Android图片异步加载的相关文章,目前大部分提到的解决方案,都是采用Map<String, SoftReference<Drawable>>  这样软引用的 ...

  7. 【转】Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)

    Android-Universal-Image-Loader 原文地址:http://blog.csdn.net/vipzjyno1/article/details/23206387 这个图片异步加载 ...

  8. Android图片异步加载之Android-Universal-Image-Loader

    将近一个月没有更新博客了,由于这段时间以来准备毕业论文等各种事务缠身,一直没有时间和精力沉下来继续学习和整理一些东西.最近刚刚恢复到正轨,正好这两天看了下Android上关于图片异步加载的开源项目,就 ...

  9. Android图片异步加载之Android-Universal-Image-Loader(转)

    今天要介绍的是Github上一个使用非常广泛的图片异步加载库Android-Universal-Image-Loader,该项目的功能十分强大,可以说是我见过的目前功能最全.性能最优的图片异步加载解决 ...

随机推荐

  1. SQLServer------Sql Server性能优化辅助指标SET STATISTICS TIME ON和SET STATISTICS IO ON

    转载: http://www.cnblogs.com/xqhppt/p/4041799.html

  2. JBOSS-EAP-6.2集群部署

    1 概述 应用的合理部署即能提高系统的可靠性和稳定性,又能提高系统的可维护性和扩展性.本文档详细阐述基于Apache负载均衡和JBOSS7集群的应用系统部署方案和配置步骤.内容涉及部署方案.环境配置. ...

  3. Java集合----Map集合

    Map Map 用于保存具有映射关系的数据,因此 Map 集合里保存着两组值,一组值用于保存 Map 里的 Key,另外一组用于保存 Map 里的 Value Map 中的 key 和 value 都 ...

  4. GIS-009-Cesium 使用

    //加载ArcGIS 发布的地图服务MapServervar url='http://Jason:6080/arcgis/rest/services/SampleWorldCities/MapServ ...

  5. GIS-006-ArcGIS API 空间关系

    Name Description 解释 SPATIAL_REL_CONTAINS Part or all of a feature from feature class 1 is contained ...

  6. hive的初步认识与hive的本质

    Hive是什么?就从这儿开始学习.... Hive是建立在Hadoop hdfs上的数据仓库基础架构. Hive可以用来数据抽取转换加载(ETL). Hive定义了简单的类SQL查询语句,称为HQL. ...

  7. nginx服务器配置说明

    总结nginx的一些配置选项: nginx全局配置文件 # 定义nginx运行的用户和组//一个默认同时为用户和组 //没有则默认为nobody user www-data; # nginx进程数,建 ...

  8. 通过([AjaxPro.AjaxMethod(AjaxPro.HttpSessionStateRequirement.Read)] )在前台html页面调用cs方法

    app_code中CS代码( Cs页面文件名public class ajaxGET): [AjaxPro.AjaxMethod(AjaxPro.HttpSessionStateRequirement ...

  9. c++11——可变参数模板

    在c++11之前,类模板和函数模板只能含有固定数量的模板参数,c++11增加了可变模板参数特性:允许模板定义中包含0到任意个模板参数.声明可变参数模板时,需要在typename或class后面加上省略 ...

  10. 简明 Vim 教程

    学习 vim 并且其会成为你最后一个使用的文本编辑器.没有比这个更好的文本编辑器了,非常地难学,但是却不可思议地好用. 我建议下面这四个步骤: 存活 感觉良好 觉得更好,更强,更快 使用VIM的超能力 ...